MessagePlugin.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Theme\Controller\Result;
  7. use Magento\Framework\App\ObjectManager;
  8. use Magento\Framework\Controller\Result\Json;
  9. use Magento\Framework\Controller\ResultInterface;
  10. use Magento\Framework\Message\MessageInterface;
  11. use Magento\Framework\Translate\Inline\ParserInterface;
  12. use Magento\Framework\Translate\InlineInterface;
  13. /**
  14. * Plugin for putting messages to cookies
  15. */
  16. class MessagePlugin
  17. {
  18. /**
  19. * Cookies name for messages
  20. */
  21. const MESSAGES_COOKIES_NAME = 'mage-messages';
  22. /**
  23. * @var \Magento\Framework\Stdlib\CookieManagerInterface
  24. */
  25. private $cookieManager;
  26. /**
  27. * @var \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory
  28. */
  29. private $cookieMetadataFactory;
  30. /**
  31. * @var \Magento\Framework\Message\ManagerInterface
  32. */
  33. private $messageManager;
  34. /**
  35. * @var \Magento\Framework\View\Element\Message\InterpretationStrategyInterface
  36. */
  37. private $interpretationStrategy;
  38. /**
  39. * @var \Magento\Framework\Serialize\Serializer\Json
  40. */
  41. private $serializer;
  42. /**
  43. * @var InlineInterface
  44. */
  45. private $inlineTranslate;
  46. /**
  47. * @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
  48. * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
  49. * @param \Magento\Framework\Message\ManagerInterface $messageManager
  50. * @param \Magento\Framework\View\Element\Message\InterpretationStrategyInterface $interpretationStrategy
  51. * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
  52. * @param InlineInterface|null $inlineTranslate
  53. */
  54. public function __construct(
  55. \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
  56. \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
  57. \Magento\Framework\Message\ManagerInterface $messageManager,
  58. \Magento\Framework\View\Element\Message\InterpretationStrategyInterface $interpretationStrategy,
  59. \Magento\Framework\Serialize\Serializer\Json $serializer = null,
  60. InlineInterface $inlineTranslate = null
  61. ) {
  62. $this->cookieManager = $cookieManager;
  63. $this->cookieMetadataFactory = $cookieMetadataFactory;
  64. $this->messageManager = $messageManager;
  65. $this->serializer = $serializer ?: ObjectManager::getInstance()
  66. ->get(\Magento\Framework\Serialize\Serializer\Json::class);
  67. $this->interpretationStrategy = $interpretationStrategy;
  68. $this->inlineTranslate = $inlineTranslate ?: ObjectManager::getInstance()->get(InlineInterface::class);
  69. }
  70. /**
  71. * Set 'mage-messages' cookie
  72. *
  73. * Checks the result that controller actions must return. If result is not JSON type, then
  74. * sets 'mage-messages' cookie.
  75. *
  76. * @param ResultInterface $subject
  77. * @param ResultInterface $result
  78. * @return ResultInterface
  79. */
  80. public function afterRenderResult(
  81. ResultInterface $subject,
  82. ResultInterface $result
  83. ) {
  84. if (!($subject instanceof Json)) {
  85. $this->setCookie($this->getMessages());
  86. }
  87. return $result;
  88. }
  89. /**
  90. * Set 'mage-messages' cookie with 'messages' array
  91. *
  92. * Checks the $messages argument. If $messages is not an empty array, then
  93. * sets 'mage-messages' public cookie:
  94. *
  95. * Cookie Name: 'mage-messages';
  96. * Cookie Duration: 1 year;
  97. * Cookie Path: /;
  98. * Cookie HTTP Only flag: FALSE. Cookie can be accessed by client-side APIs.
  99. *
  100. * The 'messages' list has format:
  101. * [
  102. * [
  103. * 'type' => 'type_value',
  104. * 'text' => 'cookie_value',
  105. * ],
  106. * ]
  107. *
  108. *
  109. * @param array $messages List of Magento messages that must be set as 'mage-messages' cookie.
  110. * @return void
  111. */
  112. private function setCookie(array $messages)
  113. {
  114. if (!empty($messages)) {
  115. if ($this->inlineTranslate->isAllowed()) {
  116. foreach ($messages as &$message) {
  117. $message['text'] = $this->convertMessageText($message['text']);
  118. }
  119. }
  120. $publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata();
  121. $publicCookieMetadata->setDurationOneYear();
  122. $publicCookieMetadata->setPath('/');
  123. $publicCookieMetadata->setHttpOnly(false);
  124. $this->cookieManager->setPublicCookie(
  125. self::MESSAGES_COOKIES_NAME,
  126. $this->serializer->serialize($messages),
  127. $publicCookieMetadata
  128. );
  129. }
  130. }
  131. /**
  132. * Replace wrapping translation with html body.
  133. *
  134. * @param string $text
  135. * @return string
  136. */
  137. private function convertMessageText(string $text): string
  138. {
  139. if (preg_match('#' . ParserInterface::REGEXP_TOKEN . '#', $text, $matches)) {
  140. $text = $matches[1];
  141. }
  142. return $text;
  143. }
  144. /**
  145. * Return messages array and clean message manager messages
  146. *
  147. * @return array
  148. */
  149. protected function getMessages()
  150. {
  151. $messages = $this->getCookiesMessages();
  152. /** @var MessageInterface $message */
  153. foreach ($this->messageManager->getMessages(true)->getItems() as $message) {
  154. $messages[] = [
  155. 'type' => $message->getType(),
  156. 'text' => $this->interpretationStrategy->interpret($message),
  157. ];
  158. }
  159. return $messages;
  160. }
  161. /**
  162. * Return messages stored in cookies
  163. *
  164. * @return array
  165. */
  166. protected function getCookiesMessages()
  167. {
  168. $messages = $this->cookieManager->getCookie(self::MESSAGES_COOKIES_NAME);
  169. if (!$messages) {
  170. return [];
  171. }
  172. $messages = $this->serializer->unserialize($messages);
  173. if (!is_array($messages)) {
  174. $messages = [];
  175. }
  176. return $messages;
  177. }
  178. }