danse_moderation_notifications-1.0.x-dev/src/Notification.php
src/Notification.php
<?php
namespace Drupal\danse_moderation_notifications;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\Group;
use Drupal\flag\FlagService;
use Drupal\token\TokenEntityMapperInterface;
use Drupal\user\Entity\User;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\RoleInterface;
/**
* General service for moderation-related questions about Entity API.
*/
class Notification implements NotificationInterface {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The mail manager service.
*
* @var \Drupal\Core\Mail\MailManagerInterface
*/
protected $mailManager;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The notification information service.
*
* @var \Drupal\danse_moderation_notifications\NotificationInformationInterface
*/
protected $notificationInformation;
/**
* The token entity mapper, if available.
*
* @var \Drupal\token\TokenEntityMapperInterface
*/
protected $tokenEntityMapper;
/**
* @var \Drupal\Core\Plugin\Context\ContextProviderInterface
*/
protected $contextProvider;
/**
* The Flag service.
*
* @var \Drupal\flag\FlagService
*/
protected $flagService;
/**
* Creates a new ModerationInformation instance.
*
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Mail\MailManagerInterface $mail_manager
* The mail manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\danse_moderation_notifications\NotificationInformationInterface $notification_information
* The notification information service.
* @param \Drupal\token\TokenEntityMapperInterface $token_entity_mappper
* The token entity mapper service.
* @param \Drupal\flag\FlagService $flag_service
* The Flag service.
*/
public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, MailManagerInterface $mail_manager, ModuleHandlerInterface $module_handler, NotificationInformationInterface $notification_information, TokenEntityMapperInterface $token_entity_mappper = NULL, ContextProviderInterface $context_provider = NULL, FlagService $flag_service = NULL) {
$this->currentUser = $current_user;
$this->entityTypeManager = $entity_type_manager;
$this->mailManager = $mail_manager;
$this->moduleHandler = $module_handler;
$this->notificationInformation = $notification_information;
$this->tokenEntityMapper = $token_entity_mappper;
$this->contextProvider = $context_provider;
$this->flagService = $flag_service;
}
/**
* {@inheritdoc}
*/
public function processEntity(EntityInterface $entity) {
$notifications = $this->notificationInformation->getNotifications($entity);
if (!empty($notifications)) {
$this->sendNotification($entity, $notifications);
}
}
/**
* {@inheritdoc}
*/
public function getNotificationRecipients(EntityInterface $entity, array $notifications) {
$data['to'] = [];
/** @var \Drupal\content_moderation_notifications\ContentModerationNotificationInterface $notification */
foreach ($notifications as $notification) {
$data['langcode'] = $this->currentUser->getPreferredLangcode();
$data['notification'] = $notification;
// Setup the email subject and body content.
// Add the entity as context to aid in token and Twig replacement.
if ($this->tokenEntityMapper) {
$data['params']['context'] = [
'entity' => $entity,
'user' => $this->currentUser,
$this->tokenEntityMapper->getTokenTypeForEntityType($entity->getEntityTypeId()) => $entity,
];
}
else {
$data['params']['context'] = [
'entity' => $entity,
'user' => $this->currentUser,
$entity->getEntityTypeId() => $entity,
];
}
// Get Subject and process any Twig templating.
$subject = $notification->getSubject();
$template = [
'#type' => 'inline_template',
'#template' => $subject,
'#context' => $data['params']['context'],
];
$subject = \Drupal::service('renderer')->renderPlain($template);
// Remove any newlines from Subject.
$subject = trim(str_replace("\n", ' ', $subject));
$data['params']['subject'] = $subject;
// Get Message, process any Twig templating, and apply input filter.
$message = $notification->getMessage();
$template = [
'#type' => 'inline_template',
'#template' => $message,
'#context' => $data['params']['context'],
];
$message = \Drupal::service('renderer')->renderPlain($template);
$data['params']['message'] = check_markup($message, $notification->getMessageFormat());
// Figure out who the email should be going to.
// Get Author.
if ($notification->author and ($entity instanceof EntityOwnerInterface)) {
if ($entity->getOwner()->isActive()) {
$data['to'][] = $entity->getOwner()->id();
}
}
if ($notification->revision_author and ($entity instanceof EntityOwnerInterface)) {
if (!$entity->getOwner()->isAnonymous()) {
$revisionListIds = $this->entityTypeManager->getStorage($entity->getEntityTypeId())
->revisionIds($entity);
// Sort $revisionListIds current revision to oldest.
$revisionListIds = array_reverse($revisionListIds);
if (isset($revisionListIds[1])) {
// Load the previous revision.
$revision = $this->entityTypeManager->getStorage('node')
->loadRevision($revisionListIds[1]);
}
else {
$revision = $this->entityTypeManager->getStorage('node')
->loadRevision($revisionListIds[0]);
}
$data['to'][] = $revision->getRevisionUser()->id();
}
}
// Get Roles.
foreach ($notification->getRoleIds() as $role) {
/** @var \Drupal\Core\Entity\EntityStorageInterface $user_storage */
$user_storage = $this->entityTypeManager->getStorage('user');
if ($role === RoleInterface::AUTHENTICATED_ID) {
$uids = \Drupal::entityQuery('user')
->condition('status', 1)
->accessCheck(FALSE)
->execute();
/** @var \Drupal\user\UserInterface[] $role_users */
$role_users = $user_storage->loadMultiple(array_filter($uids));
}
else {
/** @var \Drupal\user\UserInterface[] $role_users */
$role_users = $user_storage->loadByProperties(['roles' => $role]);
}
foreach ($role_users as $role_user) {
if ($role_user->isActive()) {
// Check for access to view the entity.
if ($entity->access('view', $role_user)) {
$data['to'][] = $role_user->id();
}
}
}
}
// Specific part to use group module functionality.
// TODO: This needs to be updated to get user ids, not emails.
if ($this->moduleHandler->moduleExists('group')
&& $notification->isGroupUse()) {
$group_contents = $this->entityTypeManager
->getStorage('group_content')
->loadByEntity($entity);
if ($group_contents) {
foreach ($group_contents as $group_content) {
/** @var \Drupal\group\Entity\Group $group */
$group = $group_content->getGroup();
$this->setGroupData($notification, $entity, $group, $data);
}
}
elseif ($contexts = $this->contextProvider->getRuntimeContexts(['group'])) {
$context = $contexts['group'];
$group = $context->getContextValue();
if (!is_null($group)) {
$this->setGroupData($notification, $entity, $group, $data);
}
}
}
// Specific part to use flag module functionality
if ($this->moduleHandler->moduleExists('flag')
&& !empty($notification->getFlags())) {
// To get all users who have flagged the entity we need to get the flag.
$flag_ids = $notification->getFlags();
/** @var \Drupal\flag\Entity\Flag[] $flags */
$flags = $this->entityTypeManager
->getStorage('flag')
->loadMultiple($flag_ids);
foreach ($flags as $flag) {
/** @var \Drupal\user\Entity\User[] $users */
$users = $this->flagService->getFlaggingUsers($entity, $flag);
foreach ($users as $user) {
$data['to'][] = $user->id();
}
}
}
// Let other modules to alter the email data.
$this->moduleHandler->alter('danse_moderation_notification_mail_data', $entity, $data);
// Remove any null values that have crept in.
$data['to'] = array_filter($data['to']);
// Remove any duplicates.
$data['to'] = array_unique($data['to']);
// Force to BCC.
$data['params']['headers']['Bcc'] = implode(',', $data['to']);
}
return $data;
}
/**
* Add the group entity to the mail context in token replacement.
*
* @param \Drupal\danse_moderation_notifications\DanseModerationNotificationsInterface $notification
* @param \Drupal\Core\Entity\EntityInterface $entity
* @param \Drupal\group\Entity\Group $group
* @param array $data
*/
public function setGroupData(DanseModerationNotificationsInterface $notification, EntityInterface $entity, Group $group, array &$data) {
if ($this->tokenEntityMapper) {
$data['params']['context'] = [
'entity' => $entity,
'user' => $this->currentUser,
'group' => $group,
$this->tokenEntityMapper->getTokenTypeForEntityType($entity->getEntityTypeId()) => $entity,
];
}
else {
$data['params']['context'] = [
'entity' => $entity,
'user' => $this->currentUser,
'group' => $group,
$entity->getEntityTypeId() => $entity,
];
}
// Get all the group members.
$notification_roles = array_values(array_filter($notification->getGroupRoles()));
foreach ($group->getMembers() as $member) {
// Add user if they have a role from the notification configuration.
if (array_intersect(array_keys($member->getRoles()), $notification_roles)) {
$member_user = $member->getUser();
if ($member_user->isActive()) {
// Add the group member to the email receiver.
$data['to'][] = $member_user->id();
}
}
}
}
}
