View source
<?php
namespace Drupal\activity_send_email\Plugin\AdvancedQueue\JobType;
use Drupal\activity_creator\ActivityNotifications;
use Drupal\activity_send_email\EmailFrequencyManager;
use Drupal\activity_send_email\Plugin\ActivityDestination\EmailActivityDestination;
use Drupal\advancedqueue\Entity\Queue;
use Drupal\advancedqueue\Job;
use Drupal\advancedqueue\JobResult;
use Drupal\advancedqueue\Plugin\AdvancedQueue\JobType\JobTypeBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Logger\LoggerChannelTrait;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ActivitySendEmailJobType extends JobTypeBase implements ContainerFactoryPluginInterface {
use LoggerChannelTrait;
protected $frequencyManager;
protected $database;
protected $activityNotifications;
protected $swiftmailSettings;
protected $entityTypeManager;
protected $queueFactory;
protected $languageManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EmailFrequencyManager $frequency_manager, Connection $connection, ActivityNotifications $activity_notifications, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, QueueFactory $queue_factory, LanguageManager $language_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->frequencyManager = $frequency_manager;
$this->database = $connection;
$this->activityNotifications = $activity_notifications;
$this->swiftmailSettings = $config_factory
->get('social_swiftmail.settings');
$this->entityTypeManager = $entity_type_manager;
$this->queueFactory = $queue_factory;
$this->languageManager = $language_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('plugin.manager.emailfrequency'), $container
->get('database'), $container
->get('activity_creator.activity_notifications'), $container
->get('config.factory'), $container
->get('entity_type.manager'), $container
->get('queue'), $container
->get('language_manager'));
}
public function process(Job $job) {
try {
$data = $job
->getPayload();
$activity_storage = $this->entityTypeManager
->getStorage('activity');
if (!empty($data['entity_id']) && ($activity = $activity_storage
->load($data['entity_id']))) {
if (!$activity
->getRelatedEntity() instanceof EntityInterface) {
$activity
->delete();
$this->activityNotifications
->deleteNotificationsbyIds([
$activity
->id(),
]);
$this
->getLogger('activity_send_email_worker')
->notice('The activity was already deleted. We marked it as successful.');
return JobResult::success('The activity was already deleted. We marked it as successful.');
}
$is_multilingual = $this->languageManager
->isMultilingual();
if (empty($data['recipients'])) {
$recipients = array_column($activity->field_activity_recipient_user
->getValue(), 'target_id');
if (count($recipients) > 50) {
if ($is_multilingual) {
foreach ($languages = $this->languageManager
->getLanguages() as $language) {
$langcode = $language
->getId();
$user_ids_per_language = $this->database
->select('users_field_data', 'ufd')
->fields('ufd', [
'uid',
])
->condition('uid', $recipients, 'IN')
->condition('preferred_langcode', $langcode)
->execute()
->fetchAllKeyed(0, 0);
$this
->prepareBatch($data, $user_ids_per_language, $langcode);
}
}
else {
$this
->prepareBatch($data, $recipients);
}
$this
->getLogger('activity_send_email_worker')
->notice('The Job was not finished correctly, no error thrown.');
return JobResult::success('The Job was has been split up in batches.');
}
}
else {
$recipients = $data['recipients'];
}
if (!empty($recipients)) {
$message_storage = $this->entityTypeManager
->getStorage('message');
$message = $message_storage
->load($activity
->getFieldValue('field_activity_message', 'target_id'));
$message_template_id = $message
->getTemplate()
->id();
$parameters = [
'activity' => $activity,
'message' => $message,
'message_template_id' => $message_template_id,
];
$email_frequencies = [
'immediately',
'daily',
'weekly',
'none',
];
$processed_users = [];
foreach ($email_frequencies as $email_frequency) {
if ($target_recipients = EmailActivityDestination::getSendEmailUsersIdsByFrequency($recipients, $message_template_id, $email_frequency)) {
$processed_users = array_merge($processed_users, $target_recipients);
$parameters['target_recipients'] = $target_recipients;
$parameters['frequency'] = $email_frequency;
if (!empty($data['langcode'])) {
$parameters['langcode'] = $data['langcode'];
}
$this
->sendToFrequencyManager($parameters);
}
}
if ($remaining_users = array_diff($recipients, $processed_users)) {
$template_frequencies = $this->swiftmailSettings
->get('template_frequencies') ?: [];
$parameters['frequency'] = $template_frequencies[$message_template_id] ?? FREQUENCY_IMMEDIATELY;
$parameters['target_recipients'] = $remaining_users;
$this
->sendToFrequencyManager($parameters);
}
}
}
$this
->getLogger('activity_send_email_worker')
->notice('The job was finished correctly.');
return JobResult::success('The job was finished correctly.');
} catch (\Exception $e) {
$this
->getLogger('activity_send_email_worker')
->error($e
->getMessage());
return JobResult::failure($e
->getMessage());
}
}
private function sendToFrequencyManager(array $parameters) {
if (empty($parameters['target_recipients'])) {
$this
->getLogger('activity_send_email_worker')
->error('We expected some recipients. None were provided.');
return JobResult::failure('We expected some recipients. None were provided.');
}
$user_storage = $this->entityTypeManager
->getStorage('user');
if (!empty($parameters['langcode'])) {
$body_text = EmailActivityDestination::getSendEmailOutputText($parameters['message'], $parameters['langcode']);
}
else {
$body_text = EmailActivityDestination::getSendEmailOutputText($parameters['message']);
}
$target_accounts = $user_storage
->loadMultiple($parameters['target_recipients']);
if (!empty($target_accounts)) {
foreach ($target_accounts as $target_account) {
if ($target_account instanceof User && !$target_account
->isBlocked()) {
if ($parameters['activity']
->getRelatedEntity()
->access('view', $target_account)) {
if (empty($parameters['langcode']) && $this->languageManager
->isMultilingual()) {
$body_text = EmailActivityDestination::getSendEmailOutputText($parameters['message'], $target_account
->getPreferredLangcode());
}
$instance = $this->frequencyManager
->createInstance($parameters['frequency']);
$instance
->processItem($parameters['activity'], $parameters['message'], $target_account, $body_text);
}
}
}
return JobResult::success('We have successfully scheduled items to be processed by the Frequency Manager.');
}
}
private function prepareBatch(array $data, array $user_ids_per_language, $langcode = NULL) {
$batches = array_chunk($user_ids_per_language, 50);
foreach ($batches as $key => $batch_recipients) {
$batch_data = [
'entity_id' => $data['entity_id'],
'recipients' => $batch_recipients,
'langcode' => $langcode,
];
$job = Job::create('activity_send_email_worker', $batch_data);
if ($job instanceof Job) {
$queue = Queue::load('default');
$queue
->enqueueJob($job);
}
}
}
}