You are here

activity_send_email.module in Open Social 10.1.x

File

modules/custom/activity_send/modules/activity_send_email/activity_send_email.module
View source
<?php

/**
 * @file
 * Contains activity_basics.module..
 */
use Drupal\activity_creator\ActivityInterface;
use Drupal\activity_send_email\Plugin\ActivityDestination\EmailActivityDestination;
use Drupal\Core\Database\Database;
use Drupal\Core\Form\FormStateInterface;

/**
 * Email frequencies.
 */
const FREQUENCY_DAILY = 'daily';
const FREQUENCY_IMMEDIATELY = 'immediately';
const FREQUENCY_NONE = 'none';
const FREQUENCY_WEEKLY = 'weekly';

/**
 * Implements hook_cron().
 *
 * This cronjob handles creating digest queue items to process.
 */
function activity_send_email_cron() {

  // Get plugins and their intervals.
  $emailfrequencymanager = \Drupal::service('plugin.manager.emailfrequency');
  $plugins = $emailfrequencymanager
    ->getDefinitions();

  // Fill a sortable array with the data about the email frequency.
  foreach ($plugins as $frequency) {
    $instance = $emailfrequencymanager
      ->createInstance($frequency['id']);

    /** @var \Drupal\activity_send_email\EmailFrequencyInterface $instance */
    $interval = $instance
      ->getInterval();

    // If the interval of the EmailFrequency plugin is more than 0, we should
    // consider it to be a digest email.
    if ($interval > 0) {

      // Get last run time.
      $last_run = \Drupal::state()
        ->get('digest.' . $frequency['id'] . '.last_run', 0);

      // If interval of frequency passed since last time, try to create queue
      // items.
      if (time() - $last_run > $interval) {

        // Query to get the data to process per user per frequency. And we make
        // sure to check only for items that need to be sent.
        $db = Database::getConnection();
        $query = $db
          ->select('user_activity_digest', 'uad')
          ->fields('uad', [
          'uid',
          'activity',
        ])
          ->condition('uad.frequency', $frequency['id'])
          ->orderBy('uad.timestamp', 'DESC');
        $activitities = $query
          ->execute()
          ->fetchAll();
        if (!empty($activitities)) {
          $queue_items = [];

          // Fill the queue items.
          foreach ($activitities as $activitity) {
            $queue_items[$activitity->uid]['uid'] = $activitity->uid;
            $queue_items[$activitity->uid]['frequency'] = $frequency['id'];
            $queue_items[$activitity->uid]['activities'][] = $activitity->activity;
          }

          // Add queue items to the queue worker.
          foreach ($queue_items as $queue_item) {

            // Add the item to the queue.
            $queue = \Drupal::queue('activity_digest_worker');
            $queue
              ->createItem($queue_item);

            // Remove activities from digest table that we just put it in the
            // queue.
            $db
              ->delete('user_activity_digest')
              ->condition('uid', $queue_item['uid'])
              ->condition('activity', $queue_item['activities'], 'IN')
              ->execute();
          }
        }

        // Update last run.
        \Drupal::state()
          ->set('digest.' . $frequency['id'] . '.last_run', time());
      }
    }
  }
}

/**
 * Implements hook_theme().
 */
function activity_send_email_theme() {
  $items = [
    'digestmail' => [
      'template' => 'digestmail',
      'variables' => [
        'notification_count' => NULL,
        'notifications' => NULL,
        'notification_settings' => NULL,
      ],
    ],
    'directmail' => [
      'template' => 'directmail',
      'variables' => [
        'notification' => NULL,
        'notification_settings' => NULL,
      ],
    ],
  ];
  return $items;
}

/**
 * Implements hook_form_FORM_ID_alter() for user_form().
 */
function activity_send_email_form_user_form_alter(&$form, FormStateInterface $form_state) {

  /** @var \Drupal\social_user\Entity\User $account */
  $account = $form_state
    ->getFormObject()
    ->getEntity();

  // Only expose these settings to existing users so it's not shown on the
  // user create form.
  if ($account
    ->isNew()) {
    return;
  }
  $form['email_notifications'] = [
    '#type' => 'fieldset',
    '#title' => [
      'text' => [
        '#markup' => t('Email notifications'),
      ],
      'icon' => [
        '#markup' => '<svg class="icon icon-expand_more"><use xlink:href="#icon-expand_more" /></svg>',
        '#allowed_tags' => [
          'svg',
          'use',
        ],
      ],
    ],
    '#tree' => TRUE,
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#attributes' => [
      'class' => [
        'form-horizontal',
        'form-email-notification',
      ],
    ],
  ];
  $form['email_notifications']['description'] = [
    '#type' => 'html_tag',
    '#tag' => 'p',
    '#value' => t('For each email notification below, you can choose to turn it off, receive it immediately or in a daily or weekly digest. Email notifications will only be sent when you are not active in the platform.'),
  ];
  $items = _activity_send_email_default_template_items();
  $email_message_templates = EmailActivityDestination::getSendEmailMessageTemplates();

  // Give other modules the chance to add their own email notifications or
  // change the title or order of the e-mail notifications on this form.
  // Copy templates so that they can't be altered (arrays are assigned by copy).
  $context = $email_message_templates;
  \Drupal::moduleHandler()
    ->alter('activity_send_email_notifications', $items, $context);

  // Sort a list of email frequencies by weight.
  $email_frequencies = sort_email_frequency_options();
  $notification_options = [];

  // Place the sorted data in an actual form option.
  foreach ($email_frequencies as $option) {
    $notification_options[$option['id']] = $option['name'];
  }
  $user_email_settings = EmailActivityDestination::getSendEmailUserSettings($account);
  foreach ($items as $item_id => $item) {

    // Don't render the fieldset when there are no templates.
    if (empty($item['templates'])) {
      continue;
    }
    $form['email_notifications'][$item_id] = [
      '#type' => 'fieldset',
      '#title' => [
        'text' => [
          '#markup' => $item['title'],
        ],
        'icon' => [
          '#markup' => '<svg class="icon icon-expand_more"><use xlink:href="#icon-expand_more" /></svg>',
          '#allowed_tags' => [
            'svg',
            'use',
          ],
        ],
      ],
      '#attributes' => [
        'class' => [
          'form-fieldset',
        ],
      ],
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#open' => TRUE,
    ];
    $mail_configs = Drupal::config('social_swiftmail.settings');
    $template_frequencies = $mail_configs
      ->get('template_frequencies') ?: [];
    foreach ($item['templates'] as $template) {
      $default_frequency = isset($template_frequencies[$template]) ? $template_frequencies[$template] : FREQUENCY_IMMEDIATELY;
      $form['email_notifications'][$item_id][$template] = [
        '#type' => 'select',
        '#title' => $email_message_templates[$template],
        '#options' => $notification_options,
        '#default_value' => isset($user_email_settings[$template]) ? $user_email_settings[$template] : $default_frequency,
      ];
    }
  }

  // Submit function to save send email settings.
  $form['actions']['submit']['#submit'][] = '_activity_send_email_form_user_form_submit';

  // Attach library.
  $form['#attached']['library'][] = 'activity_send_email/admin';
}

/**
 * Form submit for user_form.
 *
 * @param array $form
 *   Commnent on a post form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Form state interface.
 */
function _activity_send_email_form_user_form_submit(array $form, FormStateInterface $form_state) {
  $account = \Drupal::routeMatch()
    ->getParameter('user');
  $values = $form_state
    ->getValue('email_notifications');
  $values = array_merge($values['message_to_me'], $values['what_manage'], $values['what_follow'], $values['system_notifications']);
  if (is_object($account) && !empty($values)) {
    EmailActivityDestination::setSendEmailUserSettings($account, $values);
  }
}

/**
 * Sort the email frequencies by weight.
 *
 * @return array
 *   A sorted array of frequency options by weight.
 */
function sort_email_frequency_options() {
  $emailfrequencymanager = \Drupal::service('plugin.manager.emailfrequency');
  $plugins = $emailfrequencymanager
    ->getDefinitions();
  $emailfrequencies = [];

  // Fill a sortable array with the data about the email frequency.
  foreach ($plugins as $frequency) {

    /** @var \Drupal\activity_send_email\EmailFrequencyInterface $instance */
    $instance = $emailfrequencymanager
      ->createInstance($frequency['id']);
    $emailfrequencies[] = [
      'id' => $frequency['id'],
      'name' => $instance
        ->getName(),
      'weight' => $instance
        ->getWeight(),
    ];
  }

  // Sort the email frequencies by their weight.
  uasort($emailfrequencies, [
    'Drupal\\Component\\Utility\\SortArray',
    'sortByWeightElement',
  ]);
  return $emailfrequencies;
}

/**
 * Implements hook_mail().
 */
function activity_send_email_mail($key, &$message, $params) {
  $options = [
    'langcode' => $message['langcode'],
  ];
  $variables = [
    '%site_name' => \Drupal::config('system.site')
      ->get('name'),
  ];
  switch ($key) {
    case 'activity_send_email':

      // Mail subject.
      $message['subject'] = t('Notification from %site_name', $variables, $options);

      // Mail body.
      $message['body'][] = $params['body'];
      break;
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function activity_send_email_activity_insert(ActivityInterface $activity) {
  if (!in_array('email', $activity
    ->getDestinations())) {
    return;
  }

  /** @var \Drupal\activity_send\Plugin\ActivitySendManager $activity_send_factory */
  $activity_send_factory = \Drupal::service('plugin.manager.activity_send.processor');

  // Trigger the create action for entities.

  /** @var \Drupal\activity_send_email\Plugin\ActivitySend\EmailActivitySend $create_action */
  $create_action = $activity_send_factory
    ->createInstance('email_activity_send');
  $create_action
    ->create($activity);
}

/**
 * Returns default templates grouped by specific category.
 *
 * @return array[]
 *   Grouped default templates.
 */
function _activity_send_email_default_template_items() {
  return [
    'message_to_me' => [
      'title' => t('Message to me'),
      'templates' => [
        'create_post_profile',
        'create_mention_post',
        'create_mention_comment',
        'create_comment_reply_mention',
        'create_comment_reply',
        'create_comment_post_profile',
        'create_like_node_or_post',
      ],
    ],
    'what_manage' => [
      'title' => t('What I manage'),
      'templates' => [
        'create_comment_author_node_post',
        'join_to_group',
        'request_event_enrollment',
      ],
    ],
    'what_follow' => [
      'title' => t('What I follow'),
      'templates' => [
        'create_comment_following_node',
        'create_content_in_joined_group',
      ],
    ],
    'system_notifications' => [
      'title' => t('System notifications'),
      'templates' => [],
    ],
  ];
}

Functions

Namesort descending Description
activity_send_email_activity_insert Implements hook_ENTITY_TYPE_insert().
activity_send_email_cron Implements hook_cron().
activity_send_email_form_user_form_alter Implements hook_form_FORM_ID_alter() for user_form().
activity_send_email_mail Implements hook_mail().
activity_send_email_theme Implements hook_theme().
sort_email_frequency_options Sort the email frequencies by weight.
_activity_send_email_default_template_items Returns default templates grouped by specific category.
_activity_send_email_form_user_form_submit Form submit for user_form.

Constants