You are here

function search_api_saved_searches_search_api_saved_search_presave in Search API Saved Searches 8

Implements hook_ENTITY_TYPE_presave() for type "search_api_saved_search".

Implemented on behalf of the "E-mail" notification plugin.

See also

\Drupal\search_api_saved_searches\Plugin\search_api_saved_searches\notification\Email

File

./search_api_saved_searches.module, line 341
Allows visitors to bookmark searches and get notifications for new results.

Code

function search_api_saved_searches_search_api_saved_search_presave(EntityInterface $search) {

  // Don't check searches that are already disabled.
  if (!$search
    ->get('status')->value) {
    return;
  }

  // Admins also generally don't have to activate saved searches they create.
  $admin_permission = SavedSearchAccessControlHandler::ADMIN_PERMISSION;
  if (\Drupal::currentUser()
    ->hasPermission($admin_permission)) {
    return;
  }
  try {

    /** @var \Drupal\search_api_saved_searches\SavedSearchInterface $search */
    $type = $search
      ->getType();

    // If the type doesn't use the "E-mail" notification plugin, we're done.
    if (!$type
      ->isValidNotificationPlugin('email')) {
      return;
    }

    // Otherwise, check whether the "Activation mail" setting is even enabled.
    $plugin = $type
      ->getNotificationPlugin('email');
    if (!$plugin
      ->getConfiguration()['activate']['send']) {
      return;
    }

    // Don't check searches that aren't new, unless the mail address changed.
    $mail = $search
      ->get('mail')->value;
    if (!$search
      ->isNew() && $mail == $search->original
      ->get('mail')->value) {
      return;
    }
    $owner = $search
      ->getOwner();

    // If we couldn't get the owner, we can't really check further, so bail.
    if (!$owner) {

      // To avoid having to duplicate the complicated logging logic below, just
      // throw an exception.
      throw new SavedSearchesException('Saved search does not specify a valid owner.');
    }

    // If the owner is a registered user and used their own e-mail address,
    // there's no need for an activation mail.
    if (!$owner
      ->isAnonymous() && $owner
      ->getEmail() === $mail) {
      return;
    }

    // De-activate the saved search.
    $search
      ->set('status', FALSE);

    // Unfortunately, we can't send the activation mail right away, as the saved
    // search doesn't have an ID set yet (unless this is an update), so we can't
    // get the activation URL. We therefore queue the mail to be sent at the end
    // of the page request.
    $params = [
      'search' => $search,
      'plugin' => $plugin,
    ];
    \Drupal::getContainer()
      ->get('search_api_saved_searches.email_queue')
      ->queueMail([
      'search_api_saved_searches',
      Email::MAIL_ACTIVATE,
      $mail,
      $owner
        ->getPreferredLangcode(),
      $params,
    ]);
  } catch (\Exception $e) {
    $context['%search_label'] = $search
      ->label();
    if (!$search
      ->isNew()) {
      $context['%search_label'] .= ' (#' . $search
        ->id() . ')';
      try {
        $context['link'] = $search
          ->toLink(t('View saved search'), 'edit-form')
          ->toString();
      } catch (EntityMalformedException $e) {

        // Ignore.
      }
    }
    watchdog_exception('search_api_saved_searches', $e, '%type while preprocessing saved search %search_label before saving: @message in %function (line %line of %file).', $context);
  }
}