View source
<?php
namespace Drupal\search_api_saved_searches\Plugin\search_api_saved_searches\notification;
use Drupal\Component\Utility\Html;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Utility\Token;
use Drupal\search_api\Plugin\PluginFormTrait;
use Drupal\search_api\Query\ResultSetInterface;
use Drupal\search_api_saved_searches\BundleFieldDefinition;
use Drupal\search_api_saved_searches\Entity\SavedSearchAccessControlHandler;
use Drupal\search_api_saved_searches\Notification\NotificationPluginBase;
use Drupal\search_api_saved_searches\SavedSearchInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Email extends NotificationPluginBase implements PluginFormInterface {
use PluginFormTrait;
const MAIL_ACTIVATE = 'activate';
const MAIL_NEW_RESULTS = 'new_results';
protected $mailService;
protected $configFactory;
protected $tokenService;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$plugin
->setMailService($container
->get('plugin.manager.mail'));
$plugin
->setConfigFactory($container
->get('config.factory'));
$plugin
->setTokenService($container
->get('token'));
return $plugin;
}
public function getMailService() {
return $this->mailService ?: \Drupal::service('plugin.manager.mail');
}
public function setMailService(MailManagerInterface $mail_service) {
$this->mailService = $mail_service;
return $this;
}
public function getConfigFactory() {
return $this->configFactory ?: \Drupal::service('config.factory');
}
public function setConfigFactory(ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
return $this;
}
public function getTokenService() {
return $this->tokenService ?: \Drupal::service('token');
}
public function setTokenService(Token $token_service) {
$this->tokenService = $token_service;
return $this;
}
public function defaultConfiguration() {
$configuration = parent::defaultConfiguration();
$configuration += [
'registered_choose_mail' => FALSE,
'activate' => [
'send' => TRUE,
'title' => NULL,
'body' => NULL,
],
'notification' => [
'title' => NULL,
'body' => NULL,
],
];
return $configuration;
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form['registered_choose_mail'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Let logged-in users also enter a different mail address'),
'#default_value' => $this->configuration['registered_choose_mail'],
];
$form['activate'] = [
'#type' => 'details',
'#title' => $this
->t('Activation mail'),
'#open' => !$this->configuration['activate']['title'],
];
$form['activate']['send'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Use activation mail for anonymous users'),
'#description' => $this
->t("Will require that saved searches created by anonymous users, or by normal users with an e-mail address that isn't their own, are activated by clicking a link in an e-mail."),
'#default_value' => $this->configuration['activate']['send'],
];
$states = [
'visible' => [
':input[name="activate[send]"]' => [
'checked' => TRUE,
],
],
];
$args = [
'@site_name' => '[site:name]',
];
$default_title = $this->configuration['activate']['title'] ?: $this
->t('Activate your saved search at @site_name', $args);
$args['@user_name'] = '[user:display-name]';
$args['@activation_link'] = '[search-api-saved-search:activate-url]';
$default_body = $this->configuration['activate']['body'] ?: $this
->t("@user_name,\n\nA saved search on @site_name with this e-mail address was created.\nTo activate this saved search, click the following link:\n\n@activation_link\n\nIf you didn't create this saved search, just ignore this mail and the saved search will be deleted.\n\n-- @site_name team", $args);
$form['activate']['title'] = [
'#type' => 'textfield',
'#title' => $this
->t('Subject'),
'#description' => $this
->t("Enter the mail's subject.") . ' ' . $this
->t('See below for available replacements.'),
'#default_value' => $default_title,
'#required' => TRUE,
'#states' => $states,
];
$form['activate']['body'] = [
'#type' => 'textarea',
'#title' => $this
->t('Body'),
'#description' => $this
->t("Enter the mail's body.") . ' ' . $this
->t('See below for available replacements.'),
'#default_value' => $default_body,
'#rows' => 12,
'#required' => TRUE,
'#states' => $states,
];
$types = [
'site',
'user',
'search-api-saved-search',
];
$available_tokens = $this
->getAvailableTokensList($types);
$form['activate']['available_tokens'] = $available_tokens;
$form['notification'] = [
'#type' => 'details',
'#title' => $this
->t('Notification mail'),
'#open' => !$this->configuration['notification']['title'],
];
$args = [
'@site_name' => '[site:name]',
];
$default_title = $this->configuration['notification']['title'] ?: $this
->t('New results for your saved search at @site_name', $args);
$args['@user_name'] = '[user:display-name]';
$args['@search_label'] = '[search-api-saved-search:label]';
$args['@results_links'] = '[search-api-saved-search-results:links]';
$default_body = $this->configuration['notification']['body'] ?: $this
->t('@user_name,
There are new results for your saved search "@search_label":
@results_links
-- @site_name team', $args);
$form['notification']['title'] = [
'#type' => 'textfield',
'#title' => $this
->t('Subject'),
'#description' => $this
->t("Enter the mail's subject.") . ' ' . $this
->t('See below for available replacements.'),
'#default_value' => $default_title,
'#required' => TRUE,
];
$form['notification']['body'] = [
'#type' => 'textarea',
'#title' => $this
->t('Body'),
'#description' => $this
->t("Enter the mail's body.") . ' ' . $this
->t('See below for available replacements.'),
'#default_value' => $default_body,
'#rows' => 12,
'#required' => TRUE,
];
$types[] = 'search-api-saved-search-results';
$available_tokens = $this
->getAvailableTokensList($types);
$form['notification']['available_tokens'] = $available_tokens;
return $form;
}
protected function getAvailableTokensList(array $types) {
$token_items = [];
$infos = $this
->getTokenService()
->getInfo();
foreach ($infos['tokens'] as $type => $tokens) {
if (!in_array($type, $types)) {
continue;
}
$item = [
'#markup' => Html::escape($type),
'children' => [],
];
foreach ($tokens as $name => $info) {
$item['children'][$name] = "[{$type}:{$name}] - {$info['name']}: {$info['description']}";
}
$token_items[$type] = $item;
}
$available_tokens = [
'#type' => 'details',
'#title' => $this
->t('Available token replacements'),
];
$available_tokens['list'] = [
'#theme' => 'item_list',
'#items' => $token_items,
];
return $available_tokens;
}
public function getFieldDefinitions() {
$fields['mail'] = BundleFieldDefinition::create('email')
->setLabel(t('E-mail'))
->setDescription(t('The email address to which notifications should be sent.'))
->setDefaultValueCallback(static::class . '::getDefaultMail')
->setRequired(TRUE)
->setDisplayOptions('view', [
'type' => 'timestamp',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'datetime_timestamp',
'weight' => 10,
])
->setDisplayConfigurable('form', TRUE);
return $fields;
}
public static function getDefaultMail() {
$mail = \Drupal::currentUser()
->getEmail();
return $mail ? [
$mail,
] : [];
}
public function getDefaultFieldFormDisplay() {
return [
'mail' => [
'type' => 'email_default',
'weight' => 2,
'region' => 'content',
'settings' => [
'size' => 60,
'placeholder' => 'user@example.com',
],
'third_party_settings' => [],
],
];
}
public function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
if ($field_definition
->getName() !== 'mail') {
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}
if (!$this->configuration['registered_choose_mail']) {
$permission = SavedSearchAccessControlHandler::ADMIN_PERMISSION;
return AccessResult::allowedIf($account
->isAnonymous())
->addCacheableDependency($account)
->orIf(AccessResult::allowedIfHasPermission($account, $permission));
}
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}
public function notify(SavedSearchInterface $search, ResultSetInterface $results) {
$params = [
'search' => $search,
'results' => $results,
'plugin' => $this,
];
$this
->getMailService()
->mail('search_api_saved_searches', self::MAIL_NEW_RESULTS, $search
->get('mail')->value, $this
->getPreferredLangcode($search), $params);
}
public function getNewResultsMail(&$message, $params) {
$search = $params['search'];
$account = $search
->getOwner();
$results = $params['results'];
$data = [
'search_api_saved_search' => $search,
'search_api_results' => $results,
'user' => $account,
];
$options['langcode'] = $this
->getPreferredLangcode($search);
$options['clear'] = TRUE;
$subject = $this->configuration['notification']['title'];
$subject = $this
->getTokenService()
->replace($subject, $data, $options);
$body = $this->configuration['notification']['body'];
$body = $this
->getTokenService()
->replace($body, $data, $options);
$message['subject'] = $subject;
$message['body'][] = $body;
}
public function getActivationMail(&$message, $params) {
$search = $params['search'];
$account = $search
->getOwner();
$data = [
'search_api_saved_search' => $search,
'user' => $account,
];
$options['langcode'] = $this
->getPreferredLangcode($search);
$options['clear'] = TRUE;
$subject = $this->configuration['activate']['title'];
$subject = $this
->getTokenService()
->replace($subject, $data, $options);
$body = $this->configuration['activate']['body'];
$body = Html::escape($body);
$body = $this
->getTokenService()
->replace($body, $data, $options);
$message['subject'] = $subject;
$message['body'][] = Html::decodeEntities($body);
}
protected function getPreferredLangcode(SavedSearchInterface $search) {
$account = $search
->getOwner();
if ($account) {
return $account
->getPreferredLangcode();
}
return \Drupal::languageManager()
->getDefaultLanguage()
->getId();
}
}