content_sync-8.x-2.x-dev/src/Element/ContentSyncMessage.php
src/Element/ContentSyncMessage.php
<?php namespace Drupal\content_sync\Element; use Drupal\Core\Render\Element\RenderElement; use Drupal\Core\Render\Element; use Drupal\Core\Url; /** * Provides a render element for message. * * @FormElement("content_sync_message") */ class ContentSyncMessage extends RenderElement { /** * Storage none. */ const STORAGE_NONE = ''; /** * Storage local. */ const STORAGE_LOCAL = 'local'; /** * Storage session. */ const STORAGE_SESSION = 'session'; /** * Storage user (data). */ const STORAGE_USER = 'user'; /** * Storage state (API). */ const STORAGE_STATE = 'state'; /** * {@inheritdoc} */ public function getInfo() { $class = get_class($this); return [ '#message_type' => 'status', '#message_message' => '', '#message_close' => FALSE, '#message_close_effect' => 'slide', '#message_id' => '', '#message_storage' => '', '#status_headings' => [], '#pre_render' => [ [$class, 'preRenderContentSyncMessage'], ], '#theme_wrappers' => ['content_sync_message'], ]; } /** * Create status message for rendering. * * @param array $element * An associative array containing the properties and children of the * element. * * @return array * The modified element with status message. */ public static function preRenderContentSyncMessage(array $element) { $message_type = $element['#message_type']; $message_close = $element['#message_close']; $message_close_effect = $element['#message_close_effect']; $message_id = $element['#message_id']; $message_storage = $element['#message_storage']; $message_message = $element['#message_message']; $element['#attributes']['class'][] = 'content_sync-message'; $element['#attributes']['class'][] = 'js-content_sync-message'; // Ignore 'user' and 'state' storage is current user is anonymous. if (\Drupal::currentUser()->isAnonymous() && in_array($message_storage, [self::STORAGE_USER, self::STORAGE_STATE]) ) { $message_storage = ''; } // Build the messages render array. $messages = []; // Add close button as the first message. if ($message_close) { $element['#attributes']['data-message-close-effect'] = $message_close_effect; $element['#attributes']['class'][] = 'content_sync-message--close'; $element['#attributes']['class'][] = 'js-content_sync-message--close'; $close_attributes = [ 'aria-label' => t('close'), 'class' => ['js-content_sync-message__link', 'content_sync-message__link'], ]; if (in_array($message_storage, ['user', 'state'])) { $close_url = Url::fromRoute('content_sync.element.message.close', [ 'storage' => $message_storage, 'id' => $message_id, ]); } else { $close_url = Url::fromRoute('<none>', [], ['fragment' => 'close']); } $messages[] = [ '#type' => 'link', '#title' => '×', '#url' => $close_url, '#attributes' => $close_attributes, ]; // Add close attributes and check is message is closed. if ($message_storage && $message_id) { $element['#attributes']['data-message-id'] = $message_id; $element['#attributes']['data-message-storage'] = $message_storage; $element['#attributes']['class'][] = 'js-content_sync-message--close-storage'; if (static::isClosed($message_storage, $message_id)) { $element['#closed'] = TRUE; } } } // Add messages to container children. $messages[] = (!is_array($message_message)) ? ['#markup' => $message_message] : $message_message; foreach (Element::children($element) as $key) { $messages[] = $element[$key]; unset($element[$key]); } // Add status messages as the message. $element['#message'] = [ '#theme' => 'status_messages', '#message_list' => [$message_type => [$messages]], '#status_headings' => $element['#status_headings'] + [ 'status' => t('Status message'), 'error' => t('Error message'), 'warning' => t('Warning message'), ], ]; $element['#attached']['library'][] = 'content_sync/content_sync.element.message'; return $element; } /****************************************************************************/ // Manage closed functions. /****************************************************************************/ /** * Is message closed via User Data or State API. * * @param string $storage * The storage mechanism to check if a message is closed. * @param string $id * The ID of the message. * * @return bool * TRUE if the message is closed. */ public static function isClosed($storage, $id) { $account = \Drupal::currentUser(); $namespace = 'content_sync.element.message'; switch ($storage) { case self::STORAGE_STATE: /** @var \Drupal\Core\State\StateInterface $state */ $state = \Drupal::service('state'); $values = $state->get($namespace, []); return (isset($values[$id])) ? TRUE : FALSE; case self::STORAGE_USER: /** @var \Drupal\user\UserDataInterface $user_data */ $user_data = \Drupal::service('user.data'); $values = $user_data->get('content_sync', $account->id(), $namespace) ?: []; return (isset($values[$id])) ? TRUE : FALSE; } return FALSE; } /** * Set message closed via User Data or State API. * * @param string $storage * The storage mechanism save message closed. * @param string $id * The ID of the message. * * @see \Drupal\content_sync\Controller\ContentSyncElementController::close */ public static function setClosed($storage, $id) { $account = \Drupal::currentUser(); $namespace = 'content_sync.element.message'; switch ($storage) { case self::STORAGE_STATE: /** @var \Drupal\Core\State\StateInterface $state */ $state = \Drupal::service('state'); $values = $state->get($namespace, []); $values[$id] = TRUE; $state->set($namespace, $values); break; case self::STORAGE_USER: /** @var \Drupal\user\UserDataInterface $user_data */ $user_data = \Drupal::service('user.data'); $values = $user_data->get('content_sync', $account->id(), $namespace) ?: []; $values[$id] = TRUE; $user_data->set('content_sync', $account->id(), $namespace, $values); } } /** * Reset message closed via User Data or State API. * * @param string $storage * The storage mechanism save message closed. * @param string $id * The ID of the message. * * @see \Drupal\content_sync\Controller\ContentSyncElementController::close */ public static function resetClosed($storage, $id) { $account = \Drupal::currentUser(); $namespace = 'content_sync.element.message'; switch ($storage) { case self::STORAGE_STATE: /** @var \Drupal\Core\State\StateInterface $state */ $state = \Drupal::service('state'); $values = $state->get($namespace, []); unset($values[$id]); $state->set($namespace, $values); break; case self::STORAGE_USER: /** @var \Drupal\user\UserDataInterface $user_data */ $user_data = \Drupal::service('user.data'); $values = $user_data->get('content_sync', $account->id(), $namespace) ?: []; unset($values[$id]); $user_data->set('content_sync', $account->id(), $namespace, $values); } } }