You are here

function _comment_notify_mailalert in Comment Notify 8

Same name and namespace in other branches
  1. 5.2 comment_notify.module \_comment_notify_mailalert()
  2. 5 comment_notify.module \_comment_notify_mailalert()
  3. 6 comment_notify.module \_comment_notify_mailalert()
  4. 7 comment_notify.module \_comment_notify_mailalert()

Private function to send the notifications.

Parameters

\Drupal\comment\CommentInterface $comment: The comment entity.

3 calls to _comment_notify_mailalert()
comment_notify_comment_insert in ./comment_notify.module
Implements hook_comment_insert().
comment_notify_comment_publish in ./comment_notify.module
Sends the mail alerts if necessary.
comment_notify_comment_update in ./comment_notify.module
Implements hook_ENTITY_TYPE_update() for comment.

File

./comment_notify.module, line 375
This module provides comment follow-up e-mail notifications.

Code

function _comment_notify_mailalert(CommentInterface $comment) {
  module_load_include('inc', 'comment_notify', 'comment_notify');
  $config = \Drupal::config('comment_notify.settings');
  $user = \Drupal::currentUser();
  $entity_id = $comment
    ->getCommentedEntityId();
  $entity_type = $comment
    ->getCommentedEntityTypeId();
  $field_identifier = CommentNotifySettings::getCommentFieldIdentifier($comment);
  $comment_type = $comment
    ->get('comment_type')
    ->getString();

  // Check to see if a notification has already been sent for this
  // comment so that edits to a comment don't trigger an additional
  // notification.
  if (!empty($comment->notified)) {
    return;
  }

  /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
  $entity = \Drupal::entityTypeManager()
    ->getStorage($entity_type)
    ->load($entity_id);

  // No mails if this is not an enabled content type.
  $enabled_types = $config
    ->get('bundle_types');
  if (!empty($enabled_types) && !in_array($field_identifier, $enabled_types)) {
    return;
  }
  if (empty($comment
    ->getAuthorEmail())) {

    /** @var \Drupal\user\UserInterface $comment_account */
    if ($comment_account = user_load_by_name($comment
      ->getAuthorName())) {
      $comment_mail = $comment_account
        ->getEmail() ?: '';
    }
    else {
      $comment_mail = '';
    }
  }
  else {
    $comment_mail = $comment
      ->getAuthorEmail();
  }
  $sent_to = [];

  // @todo Add hook to allow entity types to specify their type's author field?
  $author_fields = [
    'uid',
    'user_id',
  ];
  foreach ($author_fields as $author_field) {

    // Send to a subscribed author if they are not the current commenter.
    if ($entity
      ->hasField($author_field)) {

      // If the entity is a user object, then the user object is the "author'.
      if ($entity instanceof User) {
        $author = $entity;
      }
      else {
        $author = $entity
          ->getOwner();
      }

      /** @var \Drupal\comment_notify\UserNotificationSettings $user_settings */
      $user_settings = \Drupal::service('comment_notify.user_settings');
      $author_notify_settings = $user_settings
        ->getSettings($author
        ->id()) ?: $user_settings
        ->getDefaultSettings();
      $author_email = $author
        ->getEmail();

      // Do they explicitly want this? Or is it default to send to users? Is
      // the comment author not the entity author? Do they have access? Do they
      // have an email (e.g. anonymous)?
      $entity_notify_a = !empty($author_notify_settings['entity_notify']) && $author_notify_settings['entity_notify'] == 1;
      $entity_notify_b = $config
        ->get('enable_default.entity_author') == 1 && !isset($author_notify_settings['entity_notify']);
      if (!empty($author_email) && ($entity_notify_a || $entity_notify_b) && $user
        ->id() != $author
        ->id() && $entity
        ->access('view', $author)) {
        if (in_array($author_email, $sent_to)) {
          continue;
        }
        $raw_values = $config
          ->get('mail_templates.entity_author.' . $entity
          ->getEntityTypeId());
        $token_data = [
          'comment' => $comment,
          'user' => $author,
        ];
        if ($entity_type == 'node') {
          $token_data['node'] = $entity;
        }
        $message['subject'] = PlainTextOutput::renderFromHtml(\Drupal::token()
          ->replace($raw_values['subject'], $token_data));
        $message['body'] = \Drupal::token()
          ->replace($raw_values['body'], $token_data);
        $language = $author
          ->getPreferredLangcode();
        \Drupal::service('plugin.manager.mail')
          ->mail('comment_notify', 'comment_notify_mail', $author
          ->getEmail(), $language, $message);
        $sent_to[] = strtolower($author
          ->getEmail());
      }

      // This field existed, so there's no need to try again.
      break;
    }
  }

  // For "reply to my comments" notifications, figure out what thread this is.
  $thread = $comment
    ->getThread() ?: '';

  // Get the list of commenters to notify.
  $watchers = comment_notify_get_watchers($entity_id, $comment_type);
  foreach ($watchers as $alert) {

    // If the user is not anonymous, always load the current e-mail address
    // from his or her user account instead of trusting $comment->mail.
    $recipient_user = $alert
      ->getOwner();
    $mail = !empty($recipient_user
      ->getEmail()) ? $recipient_user
      ->getEmail() : $alert
      ->getAuthorEmail();

    // Trim the trailing / off the thread, if present.
    $alert_thread = rtrim((string) $alert
      ->getThread(), '/');
    $relevant_thread = mb_substr($thread, 0, mb_strlen($alert_thread));
    if ($alert->notify == COMMENT_NOTIFY_COMMENT && strcmp($relevant_thread, $alert_thread) != 0) {
      continue;
    }
    if ($mail != $comment_mail && !in_array(strtolower($mail), $sent_to) && ($alert
      ->getOwnerId() != $comment
      ->getOwnerId() || $alert
      ->getOwnerId() == 0)) {
      $message = [];

      // Make sure they have access to this entity before showing a bunch of
      // entity information.
      if (!$entity
        ->access('view', $recipient_user)) {
        continue;
      }
      $raw_values = $config
        ->get('mail_templates.watcher.' . $entity
        ->getEntityTypeId());
      $token_data = [
        'comment' => $comment,
        'comment-subscribed' => $alert,
      ];
      if ($entity_type == 'node') {
        $token_data['node'] = $entity;
      }
      $message['subject'] = PlainTextOutput::renderFromHtml(\Drupal::token()
        ->replace($raw_values['subject'], $token_data));
      $message['body'] = \Drupal::token()
        ->replace($raw_values['body'], $token_data);
      $language = !empty($alert->uid) ? $recipient_user
        ->getPreferredLangcode() : LanguageInterface::LANGCODE_DEFAULT;
      \Drupal::service('plugin.manager.mail')
        ->mail('comment_notify', 'comment_notify_mail', $mail, $language, $message);
      $sent_to[] = strtolower($mail);

      // Make the mail link to user's /edit, unless it's an anonymous user.
      if ($alert
        ->getOwnerId() != 0) {
        $user_mail = $alert
          ->toLink($mail, 'edit-form')
          ->toString();
      }
      else {
        $user_mail = Html::escape($mail);
      }

      // Add an entry to the watchdog log.
      $args = [
        '@user_mail' => $user_mail,
        'link' => $alert
          ->toLink(t('source comment'))
          ->toString(),
      ];
      \Drupal::logger('comment_notify')
        ->notice('Notified: @user_mail', $args);
    }
  }

  // Record that a notification was sent for this comment so that
  // notifications aren't sent again if the comment is later edited.
  comment_notify_mark_comment_as_notified($comment);
}