Skip to content
Snippets Groups Projects
Commit a0ad2e1b authored by Camilo Ernesto Escobar Bedoya's avatar Camilo Ernesto Escobar Bedoya Committed by Andrii Podanenko
Browse files

Issue #3362297 New Queue Worker to send Email Notifications

parent aa919880
No related branches found
No related tags found
1 merge request!70Issue #3362297 New Queue Worker to send Email Notifications
......@@ -154,6 +154,7 @@ function recurring_events_reminders_cron() {
$registration_creation_service->setEventInstance($instance);
$registrants = $registration_creation_service->retrieveRegisteredParties();
if (empty($registrants)) {
return;
}
......@@ -162,7 +163,8 @@ function recurring_events_reminders_cron() {
// Send an email to all registrants.
foreach ($registrants as $registrant) {
recurring_events_registration_send_notification($key, $registrant);
// Add each notification to be sent to the queue.
\Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant);
}
}
}
......
......@@ -143,26 +143,44 @@ function template_preprocess_registrant(array &$variables) {
* Implements hook_mail().
*/
function recurring_events_registration_mail($key, &$message, $params) {
/** @var \Drupal\recurring_events_registration\NotificationService */
$service = \Drupal::service('recurring_events_registration.notification_service');
$service->setKey($key)->setEntity($params['registrant']);
if ((empty($params['subject']) || empty($params['body']) || empty($params['from']))
&& !empty($params['registrant'])
&& $params['registrant'] instanceof Registrant) {
/** @var \Drupal\recurring_events_registration\NotificationService */
$service = \Drupal::service('recurring_events_registration.notification_service');
$service->setKey($key)->setEntity($params['registrant']);
}
if ($service->isEnabled()) {
if (!empty($params['subject'])) {
$service->setSubject($params['subject']);
}
if (!empty($params['body'])) {
$service->setMessage($params['body']);
}
if (!empty($params['from'])) {
$service->setFrom($params['from']);
}
if (!empty($params['from'])) {
$message['from'] = $params['from'];
}
elseif (isset($service)) {
$message['from'] = $service->getFrom();
}
if (!empty($params['subject'])) {
$message['subject'] = $params['subject'];
}
elseif (isset($service)) {
$message['subject'] = $service->getSubject();
}
if (!empty($params['body'])) {
$message['body'][] = $params['body'];
}
elseif (isset($service)) {
$message['body'][] = $service->getMessage();
}
return FALSE;
// echo 'params::' . PHP_EOL;
// print_r($params);
// echo 'message::' . PHP_EOL;
// print_r($message);
// $message['from'] = $params['from'] ?? isset($service) ? $service->getFrom() : '';
// $message['subject'] = $params['subject'] ?? isset($service) ? $service->getSubject() : '';
// $message['body'][] = $params['body'] ?? isset($service) ? $service->getMessage() : '';
}
/**
......@@ -218,7 +236,8 @@ function recurring_events_registration_recurring_events_save_pre_instances_delet
// Send an email to all registrants.
foreach ($registrants as $registrant) {
recurring_events_registration_send_notification($key, $registrant);
// Add each notification to be sent to the queue.
\Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant);
$registrant->delete();
}
}
......@@ -250,7 +269,8 @@ function recurring_events_registration_entity_update(EntityInterface $entity) {
// Send an email to all registrants.
foreach ($registrants as $registrant) {
recurring_events_registration_send_notification($key, $registrant);
// Add each notification to be sent to the queue.
\Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant);
}
}
}
......@@ -274,7 +294,8 @@ function recurring_events_registration_recurring_events_pre_delete_instance(Even
foreach ($registrants as $registrant) {
// Only send email notifications if this event instance is in the future.
if ($registration_creation_service->eventInstanceIsInFuture()) {
recurring_events_registration_send_notification($key, $registrant);
// Add each notification to be sent to the queue.
\Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant);
}
$registrant->delete();
}
......@@ -296,7 +317,8 @@ function recurring_events_registration_recurring_events_pre_delete_instances(Eve
// Send an email to the future registrants.
foreach ($future_registrants as $registrant) {
recurring_events_registration_send_notification($key, $registrant);
// Add each notification to be sent to the queue.
\Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant);
}
}
......@@ -317,7 +339,7 @@ function recurring_events_registration_recurring_events_pre_delete_instances(Eve
*
* @param string $key
* The mail key used to determine the message and subject.
* @param \Drupal\recurring_events_registration\Entity\RegistrantInterface $registrant
* @param \Drupal\recurring_events_registration\Entity\RegistrantInterface|bool $registrant
* The registrant this email relates to.
*/
function recurring_events_registration_send_notification($key, RegistrantInterface $registrant) {
......
......@@ -4,7 +4,7 @@ services:
arguments: ['@string_translation', '@database', '@logger.factory', '@messenger', '@entity_type.manager', '@module_handler', '@token']
recurring_events_registration.notification_service:
class: Drupal\recurring_events_registration\NotificationService
arguments: ['@string_translation', '@config.factory', '@logger.factory', '@messenger', '@token', '@module_handler', '@recurring_events_registration.creation_service']
arguments: ['@string_translation', '@config.factory', '@logger.factory', '@messenger', '@token', '@module_handler', '@recurring_events_registration.creation_service', '@queue']
recurring_events_registration.access_handler:
class: Drupal\recurring_events_registration\AccessHandler
arguments: ['@string_translation', '@recurring_events_registration.creation_service', '@current_route_match', '@entity_type.manager']
......@@ -12,4 +12,4 @@ services:
class: Drupal\recurring_events_registration\Routing\RouteSubscriber
arguments: [ '@config.factory' ]
tags:
- { name: event_subscriber }
- { name: event_subscriber }
\ No newline at end of file
......@@ -10,6 +10,7 @@ use Drupal\Core\Utility\Token;
use Drupal\recurring_events_registration\Entity\RegistrantInterface;
use Drupal\Core\Extension\ModuleHandler;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Queue\QueueFactory;
/**
* Provides a service with helper functions to facilitate notifications.
......@@ -114,6 +115,13 @@ class NotificationService {
*/
protected $custom = FALSE;
/**
* The update fetch queue.
*
* @var \Drupal\Core\Queue\QueueFactory
*/
protected $queueFactory;
/**
* Class constructor.
*
......@@ -131,8 +139,10 @@ class NotificationService {
* The module handler service.
* @param \Drupal\recurring_events_registration\RegistrationCreationService $creation_service
* The registration creation service.
* @param \Drupal\Core\Queue\QueueFactory $queue_factory
* The queue factory.
*/
public function __construct(TranslationInterface $translation, ConfigFactory $config_factory, LoggerChannelFactoryInterface $logger, Messenger $messenger, Token $token, ModuleHandler $module_handler, RegistrationCreationService $creation_service) {
public function __construct(TranslationInterface $translation, ConfigFactory $config_factory, LoggerChannelFactoryInterface $logger, Messenger $messenger, Token $token, ModuleHandler $module_handler, RegistrationCreationService $creation_service, QueueFactory $queue_factory) {
$this->translation = $translation;
$this->configFactory = $config_factory;
$this->loggerFactory = $logger->get('recurring_events_registration');
......@@ -141,6 +151,7 @@ class NotificationService {
$this->moduleHandler = $module_handler;
$this->creationService = $creation_service;
$this->configName = 'recurring_events_registration.registrant.config';
$this->queueFactory = $queue_factory;
}
/**
......@@ -154,7 +165,8 @@ class NotificationService {
$container->get('messenger'),
$container->get('token'),
$container->get('module_handler'),
$container->get('recurring_events_registration.creation_service')
$container->get('recurring_events_registration.creation_service'),
$container->get('queue')
);
}
......@@ -246,7 +258,7 @@ class NotificationService {
* @return string|bool
* The key, or FALSE if not set.
*/
protected function getKey() {
public function getKey() {
if (empty($this->key)) {
$this->messenger->addError($this->translation->translate('No key defined for @module notifications.', [
'@module' => 'recurring_events_registration',
......@@ -352,11 +364,7 @@ class NotificationService {
public function getSubject($parse_tokens = TRUE) {
$key = $this->getKey();
if ($key) {
$subject = $this->subject;
if (empty($subject)) {
$subject = $this->getConfigValue('subject');
$this->setSubject($subject);
}
$subject = $this->getConfigValue('subject');
if (empty($subject)) {
$this->messenger->addError($this->translation->translate('No default subject configured for @key emails in @config_name.', [
......@@ -386,11 +394,7 @@ class NotificationService {
public function getMessage($parse_tokens = TRUE) {
$key = $this->getKey();
if ($key) {
$message = $this->message;
if (empty($message)) {
$message = $this->getConfigValue('body');
$this->setMessage($message);
}
$message = $this->getConfigValue('body');
if (empty($message)) {
$this->messenger->addError($this->translation->translate('No default body configured for @key emails in @config_name.', [
......@@ -450,4 +454,57 @@ class NotificationService {
return $this->creationService->getAvailableTokens($relevant_tokens);
}
/**
* Adds an email notification to be sent later by the Queue Worker.
*/
public function addEmailNotificationToQueue($key, RegistrantInterface $registrant) {
$config = $this->configFactory->get('recurring_events_registration.registrant.config');
$send_email = $config->get('email_notifications');
$send_email_key = $config->get('notifications' . '.' . $key . '.enabled');
// Modify $send_email if necessary.
if ($registrant instanceof RegistrantInterface) {
$this->moduleHandler->alter('recurring_events_registration_send_notification', $send_email, $registrant);
}
if ($send_email && $send_email_key) {
// We need to get the parsed email subject and message (after token
// replacement) to add them to the `$item` that will be queued. We are
// not adding the `$registrant` to the `$item`, since in the queue worker
// we cannot rely on operations over the `$registrant` or its parent
// instance or series, since at that point those entities might have been
// deleted. There are some operations and notification types that require
// the `$registrant`to be deleted, for example: the notifications
// corresponding to the keys 'series_modification_notification' and
// 'instance_deletion_notification'.
// @see recurring_events_registration_recurring_events_save_pre_instances_deletion()
// @see recurring_events_registration_recurring_events_pre_delete_instance()
$this->setKey($key)->setEntity($registrant);
$subject = $this->getSubject();
$message = $this->getMessage();
$from = $this->getFrom();
// Create the item to be added to the queue.
$item = new \stdClass();
$item->key = $key;
$item->to = $registrant->email->value;
$params = [
'subject' => $subject,
'body' => $message,
'from' => $from,
];
// Allow modules to add data to the `$params`. They can get the data from
// `$registrant`. Those `$params` are used later as the
// `$message['params']` in mail hooks.
$this->moduleHandler->alter('recurring_events_registration_message_params_alter', $params, $registrant);
$item->params = $params;
// Add the item to the queue.
$queue = $this->queueFactory->get('recurring_events_registration_email_notifications_queue_worker');
$queue->createItem($item);
}
}
}
<?php
namespace Drupal\recurring_events_registration\Plugin\QueueWorker;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
/**
* Defines 'recurring_events_registration_email_notifications_queue_worker' queue worker.
*
* @QueueWorker(
* id = "recurring_events_registration_email_notifications_queue_worker",
* title = @Translation("Email Notifications Queue Worker"),
* cron = {"time" = 6}
* )
*/
class EmailNotificationsQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* The mail manager.
*
* @var \Drupal\Core\Mail\MailManagerInterface
*/
protected $mailManager;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* Constructs a new LocaleTranslation object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* @param \Drupal\Core\Mail\MailManagerInterface $mail_manager
* The mail manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, MailManagerInterface $mail_manager, LanguageManagerInterface $language_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->mailManager = $mail_manager;
$this->languageManager = $language_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('plugin.manager.mail'),
$container->get('language_manager')
);
}
/**
* {@inheritdoc}
*/
public function processItem($item) {
if (empty($item->key) || empty($item->to) || (empty($item->params['subject']) && empty($item->params['body']))) {
return;
}
// All this worker has to do is to send the email.
// The Subject and Body already have to be included in the `$item`.
$this->mailManager->mail('recurring_events_registration', $item->key, $item->to, $this->languageManager->getDefaultLanguage()->getId(), $item->params);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment