Skip to content
Snippets Groups Projects
Commit e1fc97e0 authored by Bryan Sharpe's avatar Bryan Sharpe
Browse files

Issue #3231343 by b_sharpe: Allow Per-Group Dispatcher Settings

parent d34a7c2e
No related branches found
No related tags found
1 merge request!14- Changes config setting to proper array type
......@@ -2,16 +2,67 @@
namespace Drupal\notification_system_dispatch\Form;
use Drupal;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\notification_system_dispatch\NotificationSystemDispatcherInterface;
use Drupal\notification_system_dispatch\NotificationSystemDispatcherPluginManager;
use Drupal\notification_system_dispatch\Service\UserSettingsService;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a Notification System Dispatch form.
*/
class UserSettingsForm extends FormBase {
/**
* The user setting service.
*
* @var \Drupal\notification_system_dispatch\Service\UserSettingsService
*/
protected $userService;
/**
* The dispatch plugin manager.
*
* @var \Drupal\notification_system_dispatch\NotificationSystemDispatcherPluginManager
*/
protected $dispatcherPluginManager;
/**
* The entity manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('notification_system_dispatch.user_settings'),
$container->get('plugin.manager.notification_system_dispatcher'),
$container->get('entity_type.manager')
);
}
/**
* Constructs a new user settings form.
*
* @param \Drupal\notification_system_dispatch\Service\UserSettingsService $user_service
* The user setting service.
* @param \Drupal\notification_system_dispatch\NotificationSystemDispatcherPluginManager $dispatcher_plugin_manager
* The dispatch plugin manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The Entity Manager.
*/
public function __construct(UserSettingsService $user_service, NotificationSystemDispatcherPluginManager $dispatcher_plugin_manager, EntityTypeManagerInterface $entity_type_manager) {
$this->userService = $user_service;
$this->dispatcherPluginManager = $dispatcher_plugin_manager;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
......@@ -23,26 +74,30 @@ class UserSettingsForm extends FormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
/** @var \Drupal\notification_system_dispatch\Service\UserSettingsService $userSettingsService */
$userSettingsService = Drupal::service('notification_system_dispatch.user_settings');
/** @var \Drupal\notification_system_dispatch\NotificationSystemDispatcherPluginManager $notificationSystemDispatcherPluginManager */
$notificationSystemDispatcherPluginManager = Drupal::service('plugin.manager.notification_system_dispatcher');
$pluginDefinitions = $notificationSystemDispatcherPluginManager->getDefinitions();
$pluginDefinitions = $this->dispatcherPluginManager->getDefinitions();
$groups = $this->entityTypeManager->getStorage('notification_group')->loadMultiple();
$group_settings = $this->userService->dispatcherGroupEnabled();
foreach ($pluginDefinitions as $definition) {
/** @var \Drupal\notification_system_dispatch\NotificationSystemDispatcherInterface $dispatcher */
$dispatcher = $notificationSystemDispatcherPluginManager->createInstance($definition['id']);
$dispatcher = $this->dispatcherPluginManager->createInstance($definition['id']);
$id = $dispatcher->id();
$form['container-' . $id] = [
'#type' => 'container',
'#attributes' => [
'class' => ['dispatcher-group'],
],
];
$form['dispatcher_' . $dispatcher->id()] = [
$form['container-' . $id]['dispatcher_' . $id] = [
'#type' => 'checkbox',
'#title' => $this->t('Receive notifications via @dispatcher', [
'@dispatcher' => $this->t($dispatcher->label(), [], [
'context' => 'notification_system dispatcher label',
]),
]),
'#default_value' => $userSettingsService->dispatcherEnabled($dispatcher->id()),
'#default_value' => $this->userService->dispatcherEnabled($id),
'#ajax' => [
'callback' => '::autosave',
'event' => 'change',
......@@ -53,10 +108,35 @@ class UserSettingsForm extends FormBase {
],
],
];
// Setting per dispatcher, per group.
foreach ($groups as $gid => $group) {
$form['container-' . $id]['dispatcher_' . $id . '_group_' . $gid] = [
'#type' => 'checkbox',
'#title' => $group->label(),
'#default_value' => $group_settings[$id][$gid] ?? TRUE,
'#ajax' => [
'callback' => '::autosave',
'event' => 'change',
'wrapper' => 'ajax_placeholder',
'progress' => [
'type' => 'throbber',
'message' => '',
],
],
'#wrapper_attributes' => [
'class' => ['group-item'],
],
'#states' => [
'disabled' => [
':input[name="dispatcher_' . $id . '"]' => ['checked' => FALSE],
],
],
];
}
}
$enableBundling = $this->config('notification_system_dispatch.settings')->get('enable_bundling');
if ($enableBundling) {
$form['send_mode'] = [
'#type' => 'select',
......@@ -66,7 +146,7 @@ class UserSettingsForm extends FormBase {
NotificationSystemDispatcherInterface::SEND_MODE_DAILY => $this->t('Daily summary'),
NotificationSystemDispatcherInterface::SEND_MODE_WEEKLY => $this->t('Weekly summary'),
],
'#default_value' => $userSettingsService->getSendMode(),
'#default_value' => $this->userService->getSendMode(),
'#ajax' => [
'callback' => '::autosave',
'event' => 'change',
......@@ -86,28 +166,31 @@ class UserSettingsForm extends FormBase {
* Autosave callback for the form.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*
* @return string[]
* The save message markup.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function autosave(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\notification_system_dispatch\Service\UserSettingsService $userSettingsService */
$userSettingsService = Drupal::service('notification_system_dispatch.user_settings');
/** @var \Drupal\notification_system_dispatch\NotificationSystemDispatcherPluginManager $notificationSystemDispatcherPluginManager */
$notificationSystemDispatcherPluginManager = Drupal::service('plugin.manager.notification_system_dispatcher');
$triggering_element = $form_state->getTriggeringElement();
if (str_starts_with($triggering_element['#name'], 'dispatcher_')) {
$pluginId = str_replace('dispatcher_', '', $triggering_element['#name']);
// We're dealing with dispatch settings.
if (strpos($triggering_element['#name'], 'dispatcher_') === 0) {
$trigger = str_replace('dispatcher_', '', $triggering_element['#name']);
/** @var \Drupal\notification_system_dispatch\NotificationSystemDispatcherInterface $dispatcher */
$dispatcher = $notificationSystemDispatcherPluginManager->createInstance($pluginId);
$userSettingsService->setDispatcherEnabled($dispatcher->id(), $triggering_element['#value']);
// A group setting.
if ($pluginId = strstr($trigger, '_group_', TRUE)) {
$group_id = str_replace($pluginId . '_group_', '', $trigger);
$this->userService->setDispatcherGroupEnabled($pluginId, $group_id, $triggering_element['#value']);
}
// Main Dispatcher checkbox.
else {
$this->userService->setDispatcherEnabled($trigger, $triggering_element['#value']);
}
}
if ($triggering_element['#name'] === 'send_mode') {
......@@ -115,7 +198,7 @@ class UserSettingsForm extends FormBase {
if ($enableBundling) {
$sendMode = $triggering_element['#value'];
$userSettingsService->setSendMode($sendMode);
$this->userService->setSendMode($sendMode);
}
}
......
......@@ -48,6 +48,13 @@ class NotificationDispatcherService {
*/
protected ImmutableConfig $config;
/**
* The dispatch group map.
*
* @var array
*/
protected array $groupMappings;
/**
* Constructs a NotificationDispatcherService instance.
*
......@@ -66,6 +73,7 @@ class NotificationDispatcherService {
$this->userSettingsService = $userSettingsService;
$this->state = $state;
$this->config = $config_factory->get('notification_system_dispatch.settings');
$this->groupMappings = $config_factory->get('notification_system.settings')->get('group_mappings');
$this->dispatchers = $notificationSystemDispatcherPluginManager->getDefinitions();
$this->queue = $queueFactory->get('notification_system_dispatch');
$this->queue->createQueue();
......@@ -122,6 +130,12 @@ class NotificationDispatcherService {
$alreadyDispatchedTo = $forcedDispatcher;
}
// Use group settings to determine if a user wants this notification.
$group_settings = $this->userSettingsService->dispatcherGroupEnabled(NULL, NULL, $userId);
$group_type_map = [];
foreach ($this->groupMappings as $mapping) {
$group_type_map[$mapping['notification_type']] = $mapping['notification_group'];
}
foreach ($this->dispatchers as $dispatcher) {
// If a user has disabled a dispatcher, don't create queue items.
......@@ -142,13 +156,24 @@ class NotificationDispatcherService {
$item->notifications = [];
foreach ($notifications as $notification) {
$group = $group_type_map[$notification->getType()] ?? FALSE;
$group_choice = $group_settings[$dispatcher['id']][$group] ?? NULL;
// If a user has declined this dispatcher/group, don't send.
// This only takes place if a setting exists (for BC).
if ($group_choice === 0 || $group_choice === FALSE) {
continue;
}
$data = new \stdClass();
$data->notification_provider = $notification->getProvider();
$data->notification_id = $notification->getId();
$item->notifications[] = $data;
}
$this->queue->createItem($item);
// Only queue if there's at least one notification.
if (!empty($item->notifications)) {
$this->queue->createItem($item);
}
}
}
......
......@@ -74,10 +74,49 @@ class UserSettingsService {
return $data === '1';
}
/**
* Check if a Group is enabled for a Dispatcher.
*
* @param string $dispatcherId
* The id of the dispatcher plugin.
* @param string $groupId
* The id of the group entity.
* @param mixed $userId
* The id of the user. If none given, it will be the current user.
*
* @return mixed|array
* The requested user group data, depending on the arguments passed:
* - For $dispatcherId, and $groupId, the stored value is returned, or NULL if
* no value was found.
* - For $dispatcherId, an associative array is returned that contains
* the stored data name/value pairs for the dispatch ID.
* - For none, an associative array is returned that contains
* the stored data name/value pairs.
*/
public function dispatcherGroupEnabled($dispatcherId = NULL, $groupId = NULL, $userId = NULL) {
if ($userId == NULL) {
$userId = $this->currentUser->id();
}
$data = $this->userData->get('notification_system_dispatcher', $userId, 'dispatch_groups_enabled');
// Just send the entire array.
if ($dispatcherId === NULL) {
return $data;
}
// Send entire Dispatcher data.
if ($groupId === NULL) {
return $data[$dispatcherId] ?? [];
}
// Single group.
return $data[$dispatcherId][$groupId] ?? NULL;
}
/**
* Set the status of a dispatcher.
*
* Indicates if the user want to receive notifications via this dispatcher.
* Indicates if the user wants to receive notifications via this dispatcher.
*
* @param string $dispatcherId
* The id of the dispatcher.
......@@ -94,6 +133,32 @@ class UserSettingsService {
$this->userData->set('notification_system_dispatcher', $userId, 'dispatcher_enabled_' . $dispatcherId, $enabled);
}
/**
* Set the status of the dispatcher group.
*
* Indicates if the user wantes to receive notifications for this group per
* dispatcher.
*
* @param string $dispatcherId
* The id of the dispatcher.
* @param string $groupId
* The id of the group entity.
* @param mixed $enabled
* The status.
* @param mixed $userId
* The id of the user. If none given, it will be the current user.
*/
public function setDispatcherGroupEnabled($dispatcherId, $groupId, $enabled, $userId = NULL) {
if ($userId == NULL) {
$userId = $this->currentUser->id();
}
// Load existing and set new value.
$existing_data = $this->dispatcherGroupEnabled(NULL, NULL, $userId) ?? [];
$existing_data[$dispatcherId][$groupId] = $enabled;
$this->userData->set('notification_system_dispatcher', $userId, 'dispatch_groups_enabled', $existing_data);
}
/**
* Return the send mode, the current user has set.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment