private_message.module in Private Message 8.2
Same filename and directory in other branches
Contains hooks for the private message module.
File
private_message.moduleView source
<?php
/**
* @file
* Contains hooks for the private message module.
*/
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\user\Entity\User;
use Drupal\private_message\Entity\PrivateMessage;
/**
* Implements hook_entity_extra_field_info().
*/
function private_message_entity_extra_field_info() {
$private_message_thread_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('private_message_thread');
foreach (array_keys($private_message_thread_bundles) as $bundle) {
$fields['private_message_thread'][$bundle]['display']['last_message'] = [
'label' => t('Last Message'),
'description' => t('Displays the last message in the thread'),
'weight' => 100,
'visible' => TRUE,
];
$fields['private_message_thread'][$bundle]['display']['private_message_form'] = [
'label' => t('Form'),
'description' => t('The form to create a new message'),
'weight' => 100,
'visible' => FALSE,
];
$fields['private_message_thread'][$bundle]['display']['no_active_users'] = [
'label' => t('No active users'),
'description' => t('The notice that there are no active users'),
'weight' => 100,
'visible' => FALSE,
];
$fields['private_message_thread'][$bundle]['display']['delete_link'] = [
'label' => t('Delete link'),
'description' => t('The link to delete the thread'),
'weight' => -100,
'visible' => TRUE,
];
}
$private_message_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('private_message');
foreach (array_keys($private_message_bundles) as $bundle) {
$fields['private_message'][$bundle]['form']['members'] = [
'label' => t('Members'),
'description' => t('The widget to add members to the private message thread'),
'weight' => -100,
'visible' => TRUE,
];
}
$user_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('user');
foreach (array_keys($user_bundles) as $bundle) {
$fields['user'][$bundle]['display']['linked_username'] = [
'label' => t('Username (linked if viewer has permission)'),
'description' => t('Displays the username, linked to the user profile if the viewer has permission to access user profiles'),
'weight' => 0,
'visible' => FALSE,
];
$fields['user'][$bundle]['display']['private_message_link'] = [
'label' => t('Private message thread link'),
'description' => t('Displays a link to send a private message to the user'),
'weight' => 0,
'visible' => FALSE,
];
$fields['user'][$bundle]['form']['private_messages'] = [
'label' => t('Private messages'),
'description' => t('Settings related to private messages'),
'weight' => 0,
'visible' => TRUE,
];
}
$node_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('node');
foreach (array_keys($node_bundles) as $bundle) {
$fields['node'][$bundle]['display']['private_message_link'] = [
'label' => t('Private message thread link'),
'description' => t('Displays a link to send a private message to the node author'),
'weight' => 0,
'visible' => FALSE,
];
}
$node_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('comment');
foreach (array_keys($node_bundles) as $bundle) {
$fields['comment'][$bundle]['display']['private_message_link'] = [
'label' => t('Private message thread link'),
'description' => t('Displays a link to send a private message to the node author'),
'weight' => 0,
'visible' => FALSE,
];
}
$profile_bundles = \Drupal::service('entity_type.bundle.info')
->getBundleInfo('profile');
foreach (array_keys($profile_bundles) as $bundle) {
$fields['profile'][$bundle]['display']['private_message_link'] = [
'label' => t('Private message thread link'),
'description' => t('Displays a link to send a private message to the profile owner'),
'weight' => 0,
'visible' => FALSE,
];
}
return $fields;
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* @see hook_entity_view()
*/
function private_message_private_message_thread_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($display
->getComponent('last_message')) {
$messages = $entity
->getMessages();
if ($messages) {
$last_message = array_pop($messages);
$view_builder = \Drupal::entityTypeManager()
->getViewBuilder('private_message');
$build['last_message'] = $view_builder
->view($last_message, 'inbox');
}
}
if ($display
->getComponent('private_message_form')) {
$currentUser = \Drupal::currentUser();
$members = $entity
->getMembers();
$activeMembers = [];
foreach ($members as $member) {
if ($member
->isActive() && $member
->id() != $currentUser
->id()) {
$activeMembers[] = $member;
}
}
if (empty($activeMembers)) {
$build['no_active_users'] = [
'#theme' => 'private_message_no_active_users_notice',
];
}
else {
$private_message = PrivateMessage::create();
$form_object = \Drupal::entityTypeManager()
->getFormObject('private_message', 'add')
->setEntity($private_message);
$build['private_message_form'] = Drupal::formBuilder()
->getForm($form_object, $entity);
}
}
if ($display
->getComponent('delete_link')) {
$url = Url::fromRoute('entity.private_message_thread.delete_form', [
'private_message_thread' => $entity
->id(),
]);
$build['delete_link'] = [
'#prefix' => '<div class="private_message_thread_delete_link_wrapper">',
'#suffix' => '</div>',
'#type' => 'link',
'#url' => $url,
'#title' => t('Delete thread'),
];
}
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* Adds new elements to the User entity.
*
* @see hook_entity_view()
*/
function private_message_user_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($display
->getComponent('linked_username')) {
if (\Drupal::currentUser()
->hasPermission('access user profiles')) {
$url = Url::fromRoute('entity.user.canonical', [
'user' => $entity
->id(),
]);
$build['linked_username'] = [
'#prefix' => '<p class="username">',
'#suffix' => '</p>',
'#type' => 'link',
'#url' => $url,
'#title' => $entity
->getDisplayName(),
];
}
else {
$build['linked_username'] = [
'#prefix' => '<p class="username">',
'#suffix' => '</p>',
'#markup' => $entity
->getDisplayName(),
];
}
}
\Drupal::service('private_message.service')
->createRenderablePrivateMessageThreadLink($build, $entity, $display, $view_mode);
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* Adds new elements to the Node entity.
*
* @see hook_entity_view()
*/
function private_message_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
\Drupal::service('private_message.service')
->createRenderablePrivateMessageThreadLink($build, $entity, $display, $view_mode);
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* Adds new elements to the Comment entity.
*
* @see hook_entity_view()
*/
function private_message_comment_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
\Drupal::service('private_message.service')
->createRenderablePrivateMessageThreadLink($build, $entity, $display, $view_mode);
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* Adds new elements to the Profile entity.
*
* @see hook_entity_view()
*/
function private_message_profile_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
\Drupal::service('private_message.service')
->createRenderablePrivateMessageThreadLink($build, $entity, $display, $view_mode);
}
/**
* Implements hook_form_alter().
*/
function private_message_form_alter(&$form, FormStateInterface $formState, $form_id) {
// Act on any implementation of the private message entity form. This form
// can potentially exist multiple times on a page, so the form ID will be
// dynamic in such a case.
if (preg_match('/^private_message_add_form/', $form_id)) {
// The form is only ajaxified if/when thread_members has been set.
if ($formState
->get('thread_members')) {
// Add a unique wrapper around the entire form. The build ID will always
// be unique.
$form['#prefix'] = '<div id="' . $form['#build_id'] . '">';
$form['#suffix'] = '</div>';
// Set the wrapper to the #ajax on the form button.
$form['actions']['submit']['#ajax']['wrapper'] = $form['#build_id'];
// Ensure ajax loaded buttons have a unique ID on every ajax load.
$form['actions']['submit-' . \Drupal::time()
->getRequestTime()] = $form['actions']['submit'];
$form['actions']['submit']['#access'] = FALSE;
}
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Add private message module specific form elements to the user form.
*
* @see hook_form_alter()
*/
function private_message_form_user_form_alter(array &$form, FormStateInterface $formState) {
$config = \Drupal::config('private_message.settings');
// Get the user whose account is being modified.
$user = $formState
->getFormObject()
->getEntity();
// The form elements are only added if/when notifications have been enabled,
// and the account being edited has permission to use the private message
// system.
if ($config
->get('enable_notifications') && $user
->hasPermission('use private messaging system')) {
$form['private_messages'] = [
'#type' => 'fieldset',
'#title' => t('Private Messages'),
'#tree' => TRUE,
];
// User specific settings are stored and retrieved using the UserData
// service.
$user_data = \Drupal::service('user.data');
$user_setting = $user_data
->get('private_message', $user
->id(), 'receive_notification');
// If the user has not set a value, the system-wide default is used.
$default_value = is_null($user_setting) ? $config
->get('notify_by_default') : $user_setting;
$form['private_messages']['receive_notification'] = [
'#type' => 'checkbox',
'#title' => t('Receive notification of private messages'),
'#default_value' => $default_value,
];
$user_setting = $user_data
->get('private_message', $user
->id(), 'notify_when_using');
// If the user has not set a value, the system-wide default is used.
$default_value = is_null($user_setting) ? $config
->get('notify_when_using') : $user_setting;
$form['private_messages']['notify_when_using'] = [
'#type' => 'radios',
'#title' => t('Send notifications of new messages in a thread'),
'#options' => [
'yes' => t('For every private message'),
'no' => t('Only when not viewing the thread'),
],
'#default_value' => $default_value,
'#description' => t('Whether or not notifications should be sent when you are viewing a thread'),
'#states' => [
'visible' => [
':input[name="private_messages[receive_notification]"]' => [
'checked' => TRUE,
],
],
],
];
$options = [
60 => t('1 minute'),
180 => t('3 minutes'),
300 => t('5 minutes'),
600 => t('10 minutes'),
1800 => t('30 minutes'),
3600 => t('1 hour'),
14400 => t('4 hours'),
21600 => t('6 hours'),
43200 => t('12 hours'),
86400 => t('1 day'),
];
$user_setting = (int) $user_data
->get('private_message', $user
->id(), 'number_of_seconds_considered_away');
// If the user has not set a value, the system-wide default is used.
$default_value = is_null($user_setting) ? $config
->get('number_of_seconds_considered_away') : $user_setting;
// The system default used by administrators is a free value, whereas users
// have a limited set of values. If the default value is not in that limited
// set of values, then a default of five minutes is used.
$default_value = isset($options[$default_value]) ? $default_value : 300;
$form['private_messages']['number_of_seconds_considered_away'] = [
'#type' => 'select',
'#title' => t('Amount of time after leaving a thread that the system starts sending notifications of new messages'),
'#options' => $options,
'#default_value' => $default_value,
'#states' => [
'visible' => [
':input[name="private_messages[receive_notification]"]' => [
'checked' => TRUE,
],
':input[name="private_messages[notify_when_using]"]' => [
'value' => 'no',
],
],
],
];
// Add a custom submit handler so the form values can be saved.
$form['actions']['submit']['#submit'][] = 'private_message_user_form_submit';
}
}
/**
* Custom submit handler, saves user settings for the private message module.
*
* @see private_message_form_user_form_alter()
*/
function private_message_user_form_submit(array &$form, FormStateInterface $formState) {
// Get the user whose account object is being modified.
$user = $formState
->getFormObject()
->getEntity();
$user_data = \Drupal::service('user.data');
// Save the submitted data to the user's UserData.
$user_data
->set('private_message', $user
->id(), 'receive_notification', $formState
->getValue([
'private_messages',
'receive_notification',
]));
$user_data
->set('private_message', $user
->id(), 'notify_when_using', $formState
->getValue([
'private_messages',
'notify_when_using',
]));
$user_data
->set('private_message', $user
->id(), 'number_of_seconds_considered_away', $formState
->getValue([
'private_messages',
'number_of_seconds_considered_away',
]));
}
/**
* Implements hook_theme().
*/
function private_message_theme() {
return [
'private_message_thread' => [
'render element' => 'elements',
],
'private_message' => [
'render element' => 'elements',
],
'private_message_notification_block' => [
'variables' => [
'new_message_count' => 0,
],
'file' => 'private_message.theme.inc',
],
'private_message_no_active_users_notice' => [
'render element' => 'elements',
],
];
}
/**
* Prepares variables for private_message_thread templates.
*
* Default template: private-message-thread.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An array of elements to display in view mode.
* - private_message_thread: The private message thread object.
* - view_mode: View mode; e.g., 'full', 'teaser', etc.
*/
function template_preprocess_private_message_thread(array &$variables) {
$variables['view_mode'] = $variables['elements']['#view_mode'];
// Provide a distinct $teaser boolean.
$variables['private_message_thread'] = $variables['elements']['#private_message_thread'];
/** @var \Drupal\private_message\Entity\PrivateMessageThreadInterface $private_message_thread */
$private_message_thread = $variables['private_message_thread'];
$variables['last_update'] = \Drupal::service('renderer')
->render($variables['elements']['updated']);
$variables['url'] = $private_message_thread
->toUrl('canonical', [
'language' => $private_message_thread
->language(),
]);
// Helpful $content variable for templates.
$variables += [
'content' => [],
];
foreach (Element::children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
}
/**
* Prepares variables for private_message templates.
*
* Default template: private-message.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An array of elements to display in view mode.
* - private_message: The private message object.
* - view_mode: View mode; e.g., 'full', 'teaser', etc.
*/
function template_preprocess_private_message(array &$variables) {
$variables['view_mode'] = $variables['elements']['#view_mode'];
// Provide a distinct $teaser boolean.
$variables['private_message'] = $variables['elements']['#private_message'];
/** @var \Drupal\private_message\Entity\PrivateMessageInterface $private_message */
$private_message = $variables['private_message'];
$variables['url'] = $private_message
->toUrl('canonical', [
'language' => $private_message
->language(),
]);
// Helpful $content variable for templates.
$variables += [
'content' => [],
];
foreach (Element::children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
}
/**
* Implements hook_help().
*/
function private_message_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.private_message':
return t('<p>A private message system for users to send messages to each other. It has been written to be fully extendable using Drupal 8 APIs.</p>
<p>See the <a href=":project_page">project page on Drupal.org</a> for more details.</p>', [
':project_page' => 'https://www.drupal.org/project/private_message',
]);
}
}
/**
* Implements hook_preprocess_field().
*
* Adds a custom class to the field that can be targeted, as the default classes
* may be altered in themes/templates, and therefore should not be depended
* upon.
*/
function private_message_preprocess_field__private_message_thread__private_messages(&$vars) {
foreach (array_keys($vars['items']) as $index) {
$vars['items'][$index]['attributes']
->setAttribute('class', 'private-message-wrapper');
}
}
/**
* Implements hook_preprocess_container().
*
* Adds a custom class to the containers that can be targeted, as the default
* classes may be altered in themes/templates, and therefore should not be
* depended upon.
*/
function private_message_preprocess_container(&$vars) {
if (!empty($vars['element']['#id'])) {
if (strpos('edit-members-wrapper', $vars['element']['#id']) === 0) {
// Add a custom class to the private message members widget container.
$vars['attributes']['class'][] = 'private_message_members_widget_default_wrapper';
}
elseif (strpos('edit-message-wrapper', $vars['element']['#id']) === 0) {
// Add a custom class to the private message members widget container.
$vars['attributes']['class'][] = 'private_message_message_widget_default_wrapper';
}
}
}
/**
* Implements hook_message_view_alter().
*
* Swaps out tokens with values.
*/
function private_message_message_view_alter(array &$build) {
if ($build['#message']
->bundle() == 'private_message_notification') {
$data = [
'private_message' => $build['#message']
->get('field_message_private_message')->entity,
'private_message_thread' => $build['#message']
->get('field_message_pm_thread')->entity,
'user' => User::load($build['#message']
->getOwnerId()),
];
if ($build['#view_mode'] == 'mail_subject') {
$build['partial_0']['#markup'] = \Drupal::token()
->replace($build['partial_0']['#markup'], $data);
}
elseif ($build['#view_mode'] == 'mail_body') {
$build['partial_1']['#markup'] = \Drupal::token()
->replace($build['partial_1']['#markup'], $data);
}
}
}
/**
* Implements hook_suggestions_HOOK_alter().
*/
function private_message_theme_suggestions_private_message_thread_alter(&$suggestions, &$vars) {
$suggestions[] = 'private_message_thread__' . $vars['elements']['#view_mode'];
}
/**
* Implements hook_suggestions_HOOK_alter().
*/
function private_message_theme_suggestions_private_message_alter(&$suggestions, &$vars) {
$suggestions[] = 'private_message__' . $vars['elements']['#view_mode'];
}