message_subscribe_example.module in Message Subscribe 8
Holds hook implementation for the Message Subscribe Example module.
File
message_subscribe_example/message_subscribe_example.moduleView source
<?php
/**
* @file
* Holds hook implementation for the Message Subscribe Example module.
*/
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\node\Entity\Node;
use Drupal\comment\Entity\Comment;
use Drupal\user\Entity\User;
use Drupal\message\Entity\Message;
use Drupal\message\MessageInterface;
use Drupal\message_subscribe\Subscribers\DeliveryCandidate;
/**
* Implements hook_message_subscribe_get_subscribers_alter().
*
* Alter the subscribers list.
*
* @param \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[] &$uids
* The array of delivery candidates as defined by
* `hook_message_subscribe_get_subscribers()`.
* @param array $values
* A keyed array of values containing:
* - 'context' - The context array.
* - 'entity_type' - The entity type ID.
* - 'entity' - The entity object
* - 'subscribe_options' - The subscribe options array.
*/
function message_subscribe_example_message_subscribe_get_subscribers_alter(array &$uids, array $values) {
// Update each subscriber to use the only available delivery method, email.
// This code could be adjusted later if other delivery methods are added.
// For instance, you could add a field to the user to allow each user to
// set their own preferred notification method, then implement it here.
// Alternatively, enable the message_subscription_email module and skip this
// line. That module will create a second 'email' flag on each piece of
// content and then require users to select both 'subscribe' and 'email' if
// they want to be notified by email. But if we want everyone to be notified
// by email skipping that module and doing it this way is simpler all around.
foreach ($uids as $uid => $delivery_candidate) {
$delivery_candidate
->addNotifier('email');
}
// Add administrators to every subscription list. Doing it this way
// means they won't be able to unsubscribe, so use this judiciously.
// Perhaps create a special role for users who should always be subscribed
// to everything so that role can be removed for those who don't want this.
// There are other ways to solve this problem. You could automatically flag
// them to all new content in hook_ENTITY_TYPE_insert(), or send messages to
// a custom list (see hook_user_insert() below). This is just an
// illustration of another solution.
$query = \Drupal::entityQuery('user')
->condition('status', 1);
$query
->condition('roles', 'administrators');
$admin_uids = $query
->execute();
foreach ($admin_uids as $uid) {
$uids[$uid] = new DeliveryCandidate([], [
'email',
], $uid);
}
return $uids;
}
/**
* Implements hook_node_insert().
*/
function message_subscribe_example_node_insert(Node $node) {
$subscribers = \Drupal::service('message_subscribe.subscribers');
// Add a message for the node author.
$template = $node
->isPublished() ? 'publish_node' : 'create_node';
$message = Message::create([
'template' => $template,
'uid' => $node
->getOwnerId(),
]);
$message
->set('field_node_reference', $node);
$message
->set('field_published', $node
->isPublished());
$message
->save();
// Automatically subscribe all active users to new articles. They can
// unsubscribe later if they want to. This is one work-around to the
// fact that nobody can subscribe to content until it's published, so they
// won't otherwise get notified about new content.
// You could create a field on the user profile where users could choose
// whether to be automatically subscribed to new content, then check the
// value of that field here before flagging them.
if (in_array($node
->bundle(), [
'article',
])) {
// Find all active users.
$query = \Drupal::entityQuery('user')
->condition('status', 1);
$uids = $query
->execute();
$users = User::loadMultiple($uids);
// Add a content subscription flag for each user.
// If there are a lot of users this should probably be queued, which would
// require more custom code. For this example we'll assume the list is
// a manageable size.
$flag_service = \Drupal::service('flag');
foreach ($users as $account) {
$flag_id = 'subscribe_node';
$flag = $flag_service
->getFlagById($flag_id);
// Check if already flagged to avoid exception error.
$flagging = $flag_service
->getFlagging($flag, $node, $account);
if (!$flagging) {
$flag_service
->flag($flag, $node, $account);
}
}
}
// Do nothing more for unpublished nodes.
if (!$node
->isPublished()) {
return;
}
// Queue messages to notify all the node subscribers about published node.
$subscribers
->sendMessage($node, $message);
}
/**
* Implements hook_node_update().
*/
function message_subscribe_example_node_update(Node $node) {
$notifier = \Drupal::service('message_notify.sender');
$subscribers = \Drupal::service('message_subscribe.subscribers');
// Match publication status of message to status of source entity.
message_subscribe_example_update_message_status($node);
// Create a message for the node author.
// See if this is a newly-published node.
if ($node
->isPublished() && !empty($node->original) && !$node->original
->isPublished()) {
$template = 'publish_node';
}
else {
$template = 'update_node';
}
$message = Message::create([
'template' => $template,
'uid' => $node
->getOwnerId(),
]);
$message
->set('field_node_reference', $node);
$message
->set('field_published', $node
->isPublished());
$message
->save();
// Immediately notify message creator (node author) about update.
// This is probably most interesting if someone else made updated or
// published it.
$notifier
->send($message, [], 'email');
// Do nothing more for unpublished node.
if (!$node
->isPublished()) {
return;
}
// Queue messages to the regular node subscribers about changes in published
// nodes.
$subscribers
->sendMessage($node, $message);
}
/**
* Implements hook_comment_insert().
*/
function message_subscribe_example_comment_insert(Comment $comment) {
$notifier = \Drupal::service('message_notify.sender');
$subscribers = \Drupal::service('message_subscribe.subscribers');
// Create a message for the node author.
$node = $comment
->get('entity_id')
->first()
->get('entity')
->getTarget()
->getValue();
$message = Message::create([
'template' => 'create_comment',
'uid' => $node
->getOwnerId(),
]);
$message
->set('field_comment_reference', $comment);
$message
->set('field_published', $comment
->isPublished());
$message
->save();
// Immediately notify message creator (node author) about new comment.
$notifier
->send($message, [], 'email');
// Queue messages to notify all the node subscribers about new comment.
$subscribers
->sendMessage($comment, $message);
}
/**
* Implements hook_user_insert().
*/
function message_subscribe_example_user_insert(User $account) {
$subscribers = \Drupal::service('message_subscribe.subscribers');
// Create a custom subscriber list to notify administrators about new users.
// This is an end run around the normal flag subscription system.
// Hard-coding 'uids' in $subscribe_options will cause message_subscribe to
// skip other subscribers and send to just this list, so this allows us
// to create a custom subscription list for this purpose.
// This is not needed if you're automatically adding administrators in either
// hook_subscribe_get_subscribers() or hook_subscribe_get_subscribers_alter(),
// or if you're automatically flagging administrators. It's just another
// illustration of things that can be done.
$query = \Drupal::entityQuery('user')
->condition('status', 1);
$query
->condition('roles', 'administrator');
$admin_uids = $query
->execute();
$flags = [
'subscribe_user',
];
$notifiers = [
'email',
];
$notify_options = [];
$subscribe_options = [
'notify message owner' => FALSE,
'uids' => [],
];
foreach ($admin_uids as $uid) {
$subscribe_options['uids'][$uid] = new DeliveryCandidate($flags, $notifiers, $uid);
}
// Queue messages to our custom list of subscribers.
$message = Message::create([
'template' => 'user_register',
'uid' => $account
->id(),
]);
$message
->set('field_user', $account);
$message
->set('field_published', $account
->isActive());
$message
->save();
$subscribers
->sendMessage($account, $message, $notify_options, $subscribe_options);
}
/**
* Set message entity published field when it changes in the related entity.
*
* @param \Drupal\Core\Entity\ContentEntityBase $entity
* The entity object.
*/
function message_subscribe_example_update_message_status(ContentEntityBase $entity) {
if (!empty($entity->original) && $entity
->isPublished() == $entity->original
->isPublished()) {
return;
}
$query = \Drupal::entityQuery('message');
$field = 'field_' . $entity
->getEntityType()
->id() . '_reference';
$query
->condition($field . '.target_id', $entity
->id());
$results = $query
->execute();
if (empty($results)) {
return;
}
$messages = Message::loadMultiple($results);
foreach ($messages as $message) {
$message
->set('field_published', $entity
->isPublished());
$message
->save();
}
}
Functions
Name | Description |
---|---|
message_subscribe_example_comment_insert | Implements hook_comment_insert(). |
message_subscribe_example_message_subscribe_get_subscribers_alter | Implements hook_message_subscribe_get_subscribers_alter(). |
message_subscribe_example_node_insert | Implements hook_node_insert(). |
message_subscribe_example_node_update | Implements hook_node_update(). |
message_subscribe_example_update_message_status | Set message entity published field when it changes in the related entity. |
message_subscribe_example_user_insert | Implements hook_user_insert(). |