diff --git a/core/core.services.yml b/core/core.services.yml index 58cf9e841b..d08bf80a31 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1660,5 +1660,5 @@ services: tags: - { name: event_subscriber } messenger: - class: Drupal\Core\Messenger\SessionMessenger + class: Drupal\Core\Messenger\LegacyMessenger arguments: ['@page_cache_kill_switch'] diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 2cf951e08e..4e7da29362 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -11,6 +11,7 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Config\BootstrapConfigStorageFactory; use Drupal\Core\Logger\RfcLogLevel; +use Drupal\Core\Messenger\LegacyMessenger; use Drupal\Core\Test\TestDatabase; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Site\Settings; @@ -438,34 +439,36 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia * - message: The message string. * So, the following is an example of the full return array structure: * @code - * [ - * 'status' => [ - * [ + * 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. * * @see drupal_get_messages() * @see status-messages.html.twig * - * @deprecated Deprecated as of Drupal 8.2. + * @deprecated Deprecated as of Drupal 8.4. * Use \Drupal::service('messenger')->addMessage() instead. */ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) { // Workaround for code that can not check if the service exists. - if (!\Drupal::hasService('messenger')) { - return []; - } /* @var \Drupal\Core\Messenger\MessengerInterface $messenger */ - $messenger = \Drupal::service('messenger'); + if (\Drupal::hasService('messenger')) { + $messenger = \Drupal::service('messenger'); + } + else { + $messenger = new LegacyMessenger(); + } $messenger->addMessage($message, $type, $repeat); return $messenger->getMessages(); } @@ -495,7 +498,7 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) * @see drupal_set_message() * @see status-messages.html.twig * - * @deprecated Deprecated as of Drupal 8.2. + * @deprecated Deprecated as of Drupal 8.4. * Use \Drupal::service('messenger')->getMessages() or * \Drupal::service('messenger')->getMessagesByType() instead. */ diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php index a6262d1560..48341492bd 100644 --- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php +++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php @@ -5,7 +5,6 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceProviderInterface; use Drupal\Core\DependencyInjection\ServiceModifierInterface; -use Drupal\Core\Messenger\StaticMessenger; use Symfony\Component\DependencyInjection\Reference; /** @@ -35,9 +34,6 @@ public function register(ContainerBuilder $container) { ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); $container ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory'); - $definition = $container->getDefinition('messenger'); - $definition->setClass(StaticMessenger::class); - $definition->setArguments([new Reference('page_cache_kill_switch')]); // Replace services with no-op implementations. $container diff --git a/core/lib/Drupal/Core/Messenger/LegacyMessenger.php b/core/lib/Drupal/Core/Messenger/LegacyMessenger.php new file mode 100644 index 0000000000..c3eaf2f715 --- /dev/null +++ b/core/lib/Drupal/Core/Messenger/LegacyMessenger.php @@ -0,0 +1,153 @@ +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 getMessages() { + return _drupal_get_messages(NULL, FALSE); + } + + /** + * {@inheritdoc} + */ + public function getMessagesByType($type) { + return _drupal_get_messages($type, FALSE); + } + + /** + * {@inheritdoc} + */ + public function deleteMessages() { + return _drupal_get_messages(NULL, TRUE); + } + + /** + * {@inheritdoc} + */ + public function deleteMessagesByType($type) { + return _drupal_get_messages($type, TRUE); + } + +} + +/** + * @internal + */ +function _drupal_set_message($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. + \Drupal::service('page_cache_kill_switch')->trigger(); + } + + // Messages not set when DB connection fails. + return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL; +} + +/** + * The old implementation of drupal_get_messages + * + * /** + * 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 + * @deprecated Deprecated as of Drupal 8.2. + * Use \Drupal::service('messenger')->getMessages() or + * \Drupal::service('messenger')->getMessagesByType() instead. + */ +function _drupal_get_messages($type = NULL, $clear_queue = TRUE) { + if ($messages = drupal_set_message()) { + 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/MessengerInterface.php b/core/lib/Drupal/Core/Messenger/MessengerInterface.php index da36f04216..8e15dc19c8 100644 --- a/core/lib/Drupal/Core/Messenger/MessengerInterface.php +++ b/core/lib/Drupal/Core/Messenger/MessengerInterface.php @@ -43,6 +43,51 @@ public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE); /** + * Adds a new status message to the queue. + * + * @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 bool $repeat + * (optional) If this is FALSE and the message is already set, then the + * message won't be repeated. Defaults to FALSE. + * + * @return $this + */ + public function addStatus($message, $repeat = FALSE); + + /** + * Adds a new error message to the queue. + * + * @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 bool $repeat + * (optional) If this is FALSE and the message is already set, then the + * message won't be repeated. Defaults to FALSE. + * + * @return $this + */ + public function addError($message, $repeat = FALSE); + + /** + * Adds a new warning message to the queue. + * + * @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 bool $repeat + * (optional) If this is FALSE and the message is already set, then the + * message won't be repeated. Defaults to FALSE. + * + * @return $this + */ + public function addWarning($message, $repeat = FALSE); + + /** * Gets all messages. * * @return string[][]|\Drupal\Component\Render\MarkupInterface[][] @@ -65,8 +110,6 @@ public function getMessagesByType($type); /** * Deletes all messages. - * - * @return $this */ public function deleteMessages(); @@ -76,8 +119,6 @@ public function deleteMessages(); * @param string $type * The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING, or * self::TYPE_ERROR. - * - * @return $this */ public function deleteMessagesByType($type); diff --git a/core/lib/Drupal/Core/Messenger/SessionMessenger.php b/core/lib/Drupal/Core/Messenger/SessionMessenger.php deleted file mode 100644 index 6b8886bccf..0000000000 --- a/core/lib/Drupal/Core/Messenger/SessionMessenger.php +++ /dev/null @@ -1,93 +0,0 @@ -pageCacheKillSwitch = $page_cache_kill_switch; - } - - /** - * {@inheritdoc} - */ - public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) { - 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 - // \Drupal\Core\Render\Markup objects are detected. - if ($repeat || !in_array($message, $_SESSION['messages'][$type])) { - $_SESSION['messages'][$type][] = $message; - $this->pageCacheKillSwitch->trigger(); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getMessages() { - $messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : []; - foreach ($messages as $type => $messages_by_type) { - $messages[$type] = $messages_by_type; - } - - return $messages; - } - - /** - * {@inheritdoc} - */ - public function getMessagesByType($type) { - $messages = isset($_SESSION['messages']) && isset($_SESSION['messages'][$type]) ? $_SESSION['messages'][$type] : []; - - return $messages; - } - - /** - * {@inheritdoc} - */ - public function deleteMessages() { - unset($_SESSION['messages']); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function deleteMessagesByType($type) { - unset($_SESSION['messages'][$type]); - - return $this; - } - -} diff --git a/core/lib/Drupal/Core/Messenger/StaticMessenger.php b/core/lib/Drupal/Core/Messenger/StaticMessenger.php deleted file mode 100644 index f2e0f51101..0000000000 --- a/core/lib/Drupal/Core/Messenger/StaticMessenger.php +++ /dev/null @@ -1,104 +0,0 @@ -pageCacheKillSwitch = $page_cache_kill_switch; - } - - /** - * {@inheritdoc} - */ - public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) { - if (!isset($this->messages[$type])) { - $this->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, $this->messages[$type])) { - $this->messages[$type][] = $message; - $this->pageCacheKillSwitch->trigger(); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getMessages() { - $messages = isset($this->messages) ? $this->messages : []; - foreach ($messages as $type => $messages_by_type) { - $messages[$type] = $messages_by_type; - } - - return $messages; - } - - /** - * {@inheritdoc} - */ - public function getMessagesByType($type) { - $messages = isset($this->messages) && isset($this->messages[$type]) ? $this->messages[$type] : []; - - return $messages; - } - - /** - * {@inheritdoc} - */ - public function deleteMessages() { - unset($this->messages); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function deleteMessagesByType($type) { - unset($this->messages[$type]); - - return $this; - } - -} diff --git a/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php b/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php deleted file mode 100644 index c9b943f98d..0000000000 --- a/core/tests/Drupal/Tests/Core/Messenger/StaticMessengerTest.php +++ /dev/null @@ -1,78 +0,0 @@ -pageCacheKillSwitch = $this->prophesize(KillSwitch::class); - } - - /** - * @covers ::addMessage - * @covers ::getMessages - * @covers ::getMessagesByType - * @covers ::deleteMessages - * @covers ::deleteMessagesByType - */ - public function testMessenger() { - $message_a = $this->randomMachineName(); - $type_a = $this->randomMachineName(); - $message_b = $this->randomMachineName(); - $type_b = $this->randomMachineName(); - - $this->pageCacheKillSwitch->trigger()->shouldBeCalled(); - - $this->messenger = new StaticMessenger($this->pageCacheKillSwitch->reveal()); - - // Test that if there are no messages, the default is an empty array. - $this->assertEquals($this->messenger->getMessages(), []); - - // Test that adding a message returns the messenger and that the message can - // be retrieved. - $this->assertSame($this->messenger->addMessage($message_a, $type_a), $this->messenger); - $this->messenger->addMessage($message_a, $type_a); - $this->messenger->addMessage($message_a, $type_a, TRUE); - $this->messenger->addMessage($message_b, $type_b, TRUE); - $this->assertEquals([ - $type_a => [$message_a, $message_a], - $type_b => [$message_b], - ], $this->messenger->getMessages()); - - // Test deleting messages of a certain type. - $this->assertEquals($this->messenger->deleteMessagesByType($type_a), $this->messenger); - $this->assertEquals([ - $type_b => [$message_b], - ], $this->messenger->getMessages()); - - // Test deleting all messages. - $this->assertEquals($this->messenger->deleteMessages(), $this->messenger); - $this->assertEquals([], $this->messenger->getMessages()); - } - -}