You are here

message_digest_ui.module in Message Digest 8

Hook implementations for the Message Digest UI module.

File

message_digest_ui/message_digest_ui.module
View source
<?php

/**
 * @file
 * Hook implementations for the Message Digest UI module.
 */
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\message_digest\Plugin\Notifier\DigestInterface;

/**
 * Implements callback_allowed_values_function().
 */
function message_digest_allowed_values_callback(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = NULL) {

  // Always add an 'immediate' option.
  $values = [
    t('Send immediately'),
  ];

  /** @var \Drupal\message_notify\Plugin\Notifier\Manager $notifier_manager */
  $notifier_manager = \Drupal::service('plugin.message_notify.notifier.manager');
  foreach ($notifier_manager
    ->getDefinitions() as $plugin_id => $plugin_definition) {

    /** @var \Drupal\message_notify\Plugin\Notifier\MessageNotifierInterface $notifier */
    $notifier = $notifier_manager
      ->createInstance($plugin_id, []);
    if ($notifier instanceof DigestInterface) {
      $values[$plugin_id] = $plugin_definition['title'];
    }
  }
  return $values;
}

/**
 * Default value callback for message_digest field.
 */
function message_digest_default_value_callback(FieldableEntityInterface $entity, FieldDefinitionInterface $definition) {
  $value = '0';
  if (\Drupal::currentUser()
    ->id()) {
    $account = \Drupal::entityTypeManager()
      ->getStorage('user')
      ->load(\Drupal::currentUser()
      ->id());
    $value = $account->message_digest->value ?: '0';
  }
  return [
    [
      'value' => $value,
    ],
  ];
}

/**
 * Implements hook_module_implements_alter().
 */
function message_digest_ui_module_implements_alter(&$implementations, $hook) {

  // Ensure this module's implementation runs after message_subscribe_email.
  if ($hook === 'message_subscribe_get_subscribers_alter') {
    $digest = $implementations['message_digest_ui'];
    unset($implementations['message_digest_ui']);
    $implementations['message_digest_ui'] = $digest;
  }
}

/**
 * Implements hook_message_subscribe_get_subscribers_alter().
 *
 * Change notifier to the selected digest for users that have changed their
 * notification interval.
 */
function message_digest_ui_message_subscribe_get_subscribers_alter(array &$uids, array $values) {
  if (empty($uids)) {

    // Nobody is subscribed to the content.
    return;
  }

  // Find users that have selected a digest for notification interval on this
  // flagging.

  /** @var \Drupal\flag\FlagInterface[] $flags */
  if (!($flags = \Drupal::service('message_subscribe_email.manager')
    ->getFlags())) {

    // No subscribe email related flags.
    return;
  }
  $flag_ids = [];
  foreach ($flags as $flag) {
    $flag_ids[] = $flag
      ->id();
  }
  $digest_mapping = [];
  foreach ($values['context'] as $entity_type => $entity_ids) {
    if (empty($entity_ids)) {
      continue;
    }
    $query = \Drupal::entityTypeManager()
      ->getStorage('flagging')
      ->getQuery();
    $result = $query
      ->condition('flag_id', $flag_ids, 'IN')
      ->condition('uid', array_keys($uids), 'IN')
      ->condition('entity_type', $entity_type)
      ->condition('entity_id', $entity_ids, 'IN')
      ->sort('message_digest')
      ->execute();

    /** @var \Drupal\flag\FlaggingInterface[] $flaggings */
    $flaggings = \Drupal::entityTypeManager()
      ->getStorage('flagging')
      ->loadMultiple($result);

    // Construct a user to digest mapping.
    foreach ($flaggings as $flagging) {

      // If any of the results have a '0', then this message should be sent
      // immediately.
      if (!$flagging->message_digest->value) {
        $digest_mapping[$flagging
          ->getOwnerId()] = FALSE;
      }
      elseif (!isset($digest_mapping[$flagging
        ->getOwnerId()])) {
        $digest_mapping[$flagging
          ->getOwnerId()] = $flagging->message_digest->value;
      }
    }
  }

  /** @var \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface $delivery_candidate */
  foreach ($uids as $uid => $delivery_candidate) {
    if (isset($digest_mapping[$uid]) && $digest_mapping[$uid]) {
      $notifier = $digest_mapping[$uid];

      // Completely replace all notifiers with the digest one.
      $delivery_candidate
        ->setNotifiers([
        $notifier,
      ]);
    }
  }
}