diff --git a/core/core.services.yml b/core/core.services.yml index 459503e44c..c8f74d6f4e 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1646,5 +1646,5 @@ services: tags: - { name: event_subscriber } messenger: - class: Drupal\Core\Messenger\LegacyMessenger - arguments: ['@page_cache_kill_switch'] + class: Drupal\Core\Messenger\Messenger + arguments: ['@session.flash_bag'] diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 6c8ee5e5f2..a1a53a6585 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -455,8 +455,13 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia * * @see drupal_get_messages() * @see status-messages.html.twig + * @see https://www.drupal.org/node/2774931 + * + * @deprecated in Drupal 8.5.0, will be removed before Drupal 9.0.0. + * Use \Drupal::service('messenger')->addMessage() instead. */ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) { + @trigger_error("drupal_set_message() is deprecated Drupal 8.5.0, will be removed before Drupal 9.0.0. Use \Drupal::service('messenger')->addMessage() instead. See https://www.drupal.org/node/2774931", E_USER_DEPRECATED); /* @var \Drupal\Core\Messenger\MessengerInterface $messenger */ $messenger = \Drupal::service('messenger'); $messenger->addMessage($message, $type, $repeat); @@ -487,8 +492,14 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) * * @see drupal_set_message() * @see status-messages.html.twig + * @see https://www.drupal.org/node/2774931 + * + * @deprecated in Drupal 8.5.0, will be removed before Drupal 9.0.0. + * Use \Drupal::service('messenger')>getMessages() or + * \Drupal::service('messenger')>getMessagesByType() instead. */ function drupal_get_messages($type = NULL, $clear_queue = TRUE) { + @trigger_error("drupal_get_message() is deprecated Drupal 8.5.0, will be removed before Drupal 9.0.0. Use \Drupal::service('messenger')->addMessage() instead. See https://www.drupal.org/node/2774931", E_USER_DEPRECATED); /** @var \Drupal\Core\Messenger\MessengerInterface $messenger */ $messenger = \Drupal::hasService('messenger') ? \Drupal::service('messenger') : NULL; if ($messenger && ($messages = $messenger->all())) { diff --git a/core/lib/Drupal/Core/Messenger/LegacyMessenger.php b/core/lib/Drupal/Core/Messenger/LegacyMessenger.php deleted file mode 100644 index 8c9751f3d8..0000000000 --- a/core/lib/Drupal/Core/Messenger/LegacyMessenger.php +++ /dev/null @@ -1,212 +0,0 @@ -killSwitch = $killSwitch; - } - - /** - * {@inheritdoc} - */ - public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) { - $this->setMessage($message, $type, $repeat); - } - - /** - * {@inheritdoc} - */ - public function addStatus($message, $repeat = FALSE) { - return $this->addMessage($message, static::TYPE_STATUS); - } - - /** - * {@inheritdoc} - */ - public function addError($message, $repeat = FALSE) { - return $this->addMessage($message, static::TYPE_ERROR); - } - - /** - * {@inheritdoc} - */ - public function addWarning($message, $repeat = FALSE) { - return $this->addMessage($message, static::TYPE_WARNING); - } - - /** - * {@inheritdoc} - */ - public function all() { - return $this->getMessages(NULL, FALSE); - } - - /** - * {@inheritdoc} - */ - public function messagesByType($type) { - return $this->getMessages($type, FALSE); - } - - /** - * {@inheritdoc} - */ - public function deleteAll() { - return $this->getMessages(NULL, TRUE); - } - - /** - * {@inheritdoc} - */ - public function deleteByType($type) { - return $this->getMessages($type, TRUE); - } - - /** - * Sets a message to display to the user. - * - * Messages are stored in a session variable and displayed in the page template - * via the $messages theme variable. - * - * Example usage: - * @code - * drupal_set_message(t('An error occurred and processing did not complete.'), 'error'); - * @endcode - * - * @param string|\Drupal\Component\Render\MarkupInterface $message - * (optional) The translated message to be displayed to the user. For - * consistency with other messages, it should begin with a capital letter and - * end with a period. - * @param string $type - * (optional) The message's type. Defaults to 'status'. These values are - * supported: - * - 'status' - * - 'warning' - * - 'error' - * @param bool $repeat - * (optional) If this is FALSE and the message is already set, then the - * message won't be repeated. Defaults to FALSE. - * - * @return array|null - * A multidimensional array with keys corresponding to the set message types. - * The indexed array values of each contain the set messages for that type, - * and each message is an associative array with the following format: - * - safe: Boolean indicating whether the message string has been marked as - * safe. Non-safe strings will be escaped automatically. - * - message: The message string. - * So, the following is an example of the full return array structure: - * @code - * array( - * 'status' => array( - * array( - * 'safe' => TRUE, - * 'message' => 'A safe markup string.', - * ), - * array( - * 'safe' => FALSE, - * 'message' => "$arbitrary_user_input to escape.", - * ), - * ), - * ); - * @endcode - * If there are no messages set, the function returns NULL. - * - * @internal - */ - private function setMessage($message = NULL, $type = 'status', $repeat = FALSE) { - if (isset($message)) { - if (!isset($_SESSION['messages'][$type])) { - $_SESSION['messages'][$type] = []; - } - - // Convert strings which are safe to the simplest Markup objects. - if (!($message instanceof Markup) && $message instanceof MarkupInterface) { - $message = Markup::create((string) $message); - } - - // Do not use strict type checking so that equivalent string and - // MarkupInterface objects are detected. - if ($repeat || !in_array($message, $_SESSION['messages'][$type])) { - $_SESSION['messages'][$type][] = $message; - } - - // Mark this page as being uncacheable. - $this->killSwitch->trigger(); - } - - // Messages not set when DB connection fails. - return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL; - } - - /** - * Returns all messages that have been set with drupal_set_message(). - * - * @param string $type - * (optional) Limit the messages returned by type. Defaults to NULL, meaning - * all types. These values are supported: - * - NULL - * - 'status' - * - 'warning' - * - 'error' - * @param bool $clear_queue - * (optional) If this is TRUE, the queue will be cleared of messages of the - * type specified in the $type parameter. Otherwise the queue will be left - * intact. Defaults to TRUE. - * - * @return array - * An associative, nested array of messages grouped by message type, with - * the top-level keys as the message type. The messages returned are - * limited to the type specified in the $type parameter, if any. If there - * are no messages of the specified type, an empty array is returned. See - * drupal_set_message() for the array structure of individual messages. - * - * @see drupal_set_message() - * @see status-messages.html.twig - * - * @internal - */ - private function getMessages($type = NULL, $clear_queue = TRUE) { - if ($messages = $this->setMessage()) { - if ($type) { - if ($clear_queue) { - unset($_SESSION['messages'][$type]); - } - if (isset($messages[$type])) { - return [$type => $messages[$type]]; - } - } - else { - if ($clear_queue) { - unset($_SESSION['messages']); - } - return $messages; - } - } - return []; - } - -} diff --git a/core/lib/Drupal/Core/Messenger/Messenger.php b/core/lib/Drupal/Core/Messenger/Messenger.php new file mode 100644 index 0000000000..454c269142 --- /dev/null +++ b/core/lib/Drupal/Core/Messenger/Messenger.php @@ -0,0 +1,103 @@ +flashBag = $flash_bag; + } + + /** + * {@inheritdoc} + */ + public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) { + // Convert strings which are safe to the simplest Markup objects. + if (!($message instanceof Markup) && $message instanceof MarkupInterface) { + $message = Markup::create((string) $message); + } + // Do not use strict type checking so that equivalent string and + // MarkupInterface objects are detected. + if ($repeat || !in_array($message, $this->flashBag->peek($type))) { + $this->flashBag->add($type, $message); + } + + // Mark this page as being uncacheable. + \Drupal::service('page_cache_kill_switch')->trigger(); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addStatus($message, $repeat = FALSE) { + return $this->addMessage($message, static::TYPE_STATUS); + } + + /** + * {@inheritdoc} + */ + public function addError($message, $repeat = FALSE) { + return $this->addMessage($message, static::TYPE_ERROR); + } + + /** + * {@inheritdoc} + */ + public function addWarning($message, $repeat = FALSE) { + return $this->addMessage($message, static::TYPE_WARNING); + } + + /** + * {@inheritdoc} + */ + public function all() { + return $this->flashBag->peekAll(); + } + + /** + * {@inheritdoc} + */ + public function messagesByType($type) { + return $this->flashBag->peek($type); + } + + /** + * {@inheritdoc} + */ + public function deleteAll() { + return $this->flashBag->clear(); + } + + /** + * {@inheritdoc} + */ + public function deleteByType($type) { + // Flash bag gets and clears flash messages from the stack. + return $this->flashBag->get($type); + } + +} diff --git a/core/lib/Drupal/Core/Messenger/MessengerInterface.php b/core/lib/Drupal/Core/Messenger/MessengerInterface.php index 216835bcea..217da76575 100644 --- a/core/lib/Drupal/Core/Messenger/MessengerInterface.php +++ b/core/lib/Drupal/Core/Messenger/MessengerInterface.php @@ -109,11 +109,15 @@ public function all(); * or self::TYPE_ERROR. * * @return string[]|\Drupal\Component\Render\MarkupInterface[] + * The messages of given type. */ public function messagesByType($type); /** * Deletes all messages. + * + * @return string[]|\Drupal\Component\Render\MarkupInterface[] + * The deleted messages. */ public function deleteAll(); @@ -123,6 +127,9 @@ public function deleteAll(); * @param string $type * The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING, or * self::TYPE_ERROR. + * + * @return string[]|\Drupal\Component\Render\MarkupInterface[] + * The deleted messages of given type.. */ public function deleteByType($type); diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php index 37eb87585d..e350bc2eaf 100644 --- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php +++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php @@ -5,6 +5,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\CacheableResponse; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Render\Markup; use Drupal\Core\Session\AccountInterface; @@ -48,6 +49,13 @@ class SystemTestController extends ControllerBase { */ protected $renderer; + /** + * The messenger service. + * + * @var \Drupal\Core\Messenger\MessengerInterface + */ + protected $messenger; + /** * Constructs the SystemTestController. * @@ -59,12 +67,15 @@ class SystemTestController extends ControllerBase { * The current user. * @param \Drupal\Core\Render\RendererInterface $renderer * The renderer. + * @param \Drupal\Core\Messenger\MessengerInterface $messenger + * The messenger service. */ - public function __construct(LockBackendInterface $lock, LockBackendInterface $persistent_lock, AccountInterface $current_user, RendererInterface $renderer) { + public function __construct(LockBackendInterface $lock, LockBackendInterface $persistent_lock, AccountInterface $current_user, RendererInterface $renderer, MessengerInterface $messenger) { $this->lock = $lock; $this->persistentLock = $persistent_lock; $this->currentUser = $current_user; $this->renderer = $renderer; + $this->messenger = $messenger; } /** @@ -75,7 +86,8 @@ public static function create(ContainerInterface $container) { $container->get('lock'), $container->get('lock.persistent'), $container->get('current_user'), - $container->get('renderer') + $container->get('renderer'), + $container->get('messenger') ); } @@ -99,9 +111,13 @@ public function drupalSetMessageTest() { // Set two messages. drupal_set_message('First message (removed).'); drupal_set_message(t('Second message with markup! (not removed).')); - + $messages = $this->messenger->deleteByType('status'); // Remove the first. - unset($_SESSION['messages']['status'][0]); + unset($messages[0]); + + foreach ($messages as $message) { + $this->messenger->addStatus($message); + } // Duplicate message check. drupal_set_message('Non Duplicated message', 'status', FALSE); diff --git a/core/tests/Drupal/KernelTests/Core/Common/DrupalSetMessageTest.php b/core/tests/Drupal/KernelTests/Core/Common/DrupalSetMessageTest.php index 59470e6563..7a15fc3e04 100644 --- a/core/tests/Drupal/KernelTests/Core/Common/DrupalSetMessageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Common/DrupalSetMessageTest.php @@ -20,10 +20,4 @@ public function testDrupalSetMessage() { $this->assertEquals('A message: bar', (string) $messages['status'][0]); } - protected function tearDown() { - // Clear session to prevent global leakage. - unset($_SESSION['messages']); - parent::tearDown(); - } - }