View source
<?php
namespace Drupal\queue_mail\Plugin\QueueWorker;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Theme\ThemeInitializationInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
class SendMailQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {
use StringTranslationTrait;
protected $themeManager;
protected $themeInitialization;
protected $activeTheme;
protected $mailManager;
protected $logger;
protected $config;
protected $queue;
protected $moduleHandler;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($container
->get('theme.manager'), $container
->get('theme.initialization'), $container
->get('plugin.manager.mail'), $container
->get('logger.factory'), $container
->get('config.factory'), $container
->get('queue'), $container
->get('module_handler'));
}
public function __construct(ThemeManagerInterface $theme_manager, ThemeInitializationInterface $theme_init, MailManagerInterface $mail_manager, LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, ContainerAwareInterface $queue_factory, ModuleHandlerInterface $module_handler) {
$this->themeManager = $theme_manager;
$this->themeInitialization = $theme_init;
$this->activeTheme = $this->themeManager
->getActiveTheme();
$this->mailManager = $mail_manager;
$this->logger = $logger_factory
->get('mail');
$this->config = $config_factory
->get('queue_mail.settings');
$this->queue = $queue_factory
->get('queue_mail', TRUE);
$this->moduleHandler = $module_handler;
}
public function processItem($message) {
$original_message = $message;
$interval = $this->config
->get('requeue_interval');
if (isset($message['last_attempt']) && $message['last_attempt'] + $interval > time()) {
throw new \RuntimeException(sprintf('Sending of mail "%s" is skipped in the mail queue due to requeue interval.', $message['id']));
}
$this->moduleHandler
->alter('queue_mail_send', $message);
if (empty($message['send'])) {
$message['result'] = NULL;
return $message;
}
$system = $this->mailManager
->getInstance([
'module' => $message['module'],
'key' => $message['key'],
]);
$this
->setMailTheme($message);
$current_langcode = $this
->setMailLanguage($message);
try {
$message = $system
->format($message);
} finally {
$this
->setActiveTheme($message);
$this
->setActiveLanguage($message, $current_langcode);
}
if ($message['subject']) {
$message['subject'] = PlainTextOutput::renderFromHtml($message['subject']);
}
$message['result'] = $system
->mail($message);
if (!$message['result']) {
$this->logger
->error('Error sending email (from %from to %to with reply-to %reply).', [
'%from' => $message['from'],
'%to' => $message['to'],
'%reply' => $message['reply-to'] ? $message['reply-to'] : $this
->t('not set'),
]);
$this
->processRetryLimit($original_message);
}
$this
->waitBetweenSending();
return $message;
}
protected function setMailLanguage(array $message) {
return $message['langcode'];
}
protected function setActiveLanguage(array $message, $langcode) {
}
protected function setMailTheme(array $message) {
if ($this
->messageHasAnotherTheme($message)) {
$theme = $this->themeInitialization
->initTheme($message['theme']);
$this->themeManager
->setActiveTheme($theme);
}
}
protected function setActiveTheme(array $message) {
if ($this
->messageHasAnotherTheme($message)) {
$this->themeManager
->setActiveTheme($this->activeTheme);
}
}
protected function messageHasAnotherTheme(array $message) {
return !empty($message['theme']) && $message['theme'] != $this->activeTheme
->getName();
}
protected function waitBetweenSending() {
if ($wait_time = $this->config
->get('queue_mail_queue_wait_time')) {
sleep($wait_time);
}
}
protected function processRetryLimit(array $original_message) {
$original_message['last_attempt'] = time();
if (!isset($original_message['fail_count'])) {
$original_message['fail_count'] = 0;
}
$original_message['fail_count']++;
$threshold = $this->config
->get('threshold');
if ($original_message['fail_count'] < $threshold) {
$this->queue
->createItem($original_message);
}
else {
$this->logger
->error('Attempt sending email (from %from to %to with reply-to %reply) exceeded retry threshold and was deleted.', [
'%from' => $original_message['from'],
'%to' => $original_message['to'],
'%reply' => $original_message['reply-to'] ? $original_message['reply-to'] : $this
->t('not set'),
]);
}
}
}