Notifications.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\ReleaseNotification\Ui\DataProvider\Modifier;
  7. use Magento\ReleaseNotification\Model\ContentProviderInterface;
  8. use Magento\ReleaseNotification\Ui\Renderer\NotificationRenderer;
  9. use Magento\Ui\DataProvider\Modifier\ModifierInterface;
  10. use Magento\Framework\Serialize\SerializerInterface;
  11. use Magento\Framework\App\CacheInterface;
  12. use Magento\Ui\Component;
  13. use Magento\Framework\App\ProductMetadataInterface;
  14. use Magento\Backend\Model\Auth\Session;
  15. use Psr\Log\LoggerInterface;
  16. /**
  17. * Modifies the metadata returning to the Release Notification data provider
  18. */
  19. class Notifications implements ModifierInterface
  20. {
  21. /**
  22. * @var ContentProviderInterface
  23. */
  24. private $contentProvider;
  25. /**
  26. * @var NotificationRenderer
  27. */
  28. private $renderer;
  29. /**
  30. * Prefix for cache
  31. *
  32. * @var string
  33. */
  34. private static $cachePrefix = 'release-notification-content-';
  35. /**
  36. * @var CacheInterface
  37. */
  38. private $cacheStorage;
  39. /**
  40. * @var SerializerInterface
  41. */
  42. private $serializer;
  43. /**
  44. * @var ProductMetadataInterface
  45. */
  46. private $productMetadata;
  47. /**
  48. * @var Session
  49. */
  50. private $session;
  51. /**
  52. * @var LoggerInterface
  53. */
  54. private $logger;
  55. /**
  56. * @param ContentProviderInterface $contentProvider
  57. * @param NotificationRenderer $render
  58. * @param CacheInterface $cacheStorage
  59. * @param SerializerInterface $serializer
  60. * @param ProductMetadataInterface $productMetadata
  61. * @param Session $session
  62. * @param LoggerInterface $logger
  63. */
  64. public function __construct(
  65. ContentProviderInterface $contentProvider,
  66. NotificationRenderer $render,
  67. CacheInterface $cacheStorage,
  68. SerializerInterface $serializer,
  69. ProductMetadataInterface $productMetadata,
  70. Session $session,
  71. LoggerInterface $logger
  72. ) {
  73. $this->contentProvider = $contentProvider;
  74. $this->renderer = $render;
  75. $this->cacheStorage = $cacheStorage;
  76. $this->serializer = $serializer;
  77. $this->productMetadata = $productMetadata;
  78. $this->session = $session;
  79. $this->logger = $logger;
  80. }
  81. /**
  82. * {@inheritdoc}
  83. */
  84. public function modifyData(array $data)
  85. {
  86. return $data;
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public function modifyMeta(array $meta)
  92. {
  93. $modalContent = $this->getNotificationContent();
  94. if ($modalContent) {
  95. $pages = $modalContent['pages'];
  96. $pageCount = count($pages);
  97. $counter = 1;
  98. foreach ($pages as $page) {
  99. $meta = $this->buildNotificationMeta($meta, $page, $counter++ == $pageCount);
  100. }
  101. } else {
  102. $meta = $this->hideNotification($meta);
  103. }
  104. return $meta;
  105. }
  106. /**
  107. * Builds the notification modal by modifying $meta for the ui component
  108. *
  109. * @param array $meta
  110. * @param array $page
  111. * @param bool $isLastPage
  112. * @return array
  113. */
  114. private function buildNotificationMeta(array $meta, array $page, $isLastPage)
  115. {
  116. $meta['notification_modal_' . $page['name']]['arguments']['data']['config'] = [
  117. 'isTemplate' => false,
  118. 'componentType' => Component\Modal::NAME
  119. ];
  120. $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children']
  121. ['notification_text']['arguments']['data']['config'] = [
  122. 'text' => $this->renderer->getNotificationContent($page)
  123. ];
  124. if ($isLastPage) {
  125. $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [
  126. 'title' => $this->renderer->getNotificationTitle($page),
  127. 'buttons' => [
  128. [
  129. 'text' => 'Done',
  130. 'actions' => [
  131. [
  132. 'targetName' => '${ $.name }',
  133. 'actionName' => 'closeReleaseNotes'
  134. ]
  135. ],
  136. 'class' => 'release-notification-button-next'
  137. ]
  138. ],
  139. ];
  140. $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children']
  141. ['notification_buttons']['children']['notification_button_next']['arguments']['data']['config'] = [
  142. 'buttonClasses' => 'hide-release-notification'
  143. ];
  144. } else {
  145. $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [
  146. 'title' => $this->renderer->getNotificationTitle($page)
  147. ];
  148. }
  149. return $meta;
  150. }
  151. /**
  152. * Sets the modal to not display if no content is available.
  153. *
  154. * @param array $meta
  155. * @return array
  156. */
  157. private function hideNotification(array $meta)
  158. {
  159. $meta['notification_modal_1']['arguments']['data']['config']['options'] = [
  160. 'autoOpen' => false
  161. ];
  162. return $meta;
  163. }
  164. /**
  165. * Returns the notification modal content data
  166. *
  167. * @returns array|false
  168. */
  169. private function getNotificationContent()
  170. {
  171. $version = strtolower($this->getTargetVersion());
  172. $edition = strtolower($this->productMetadata->getEdition());
  173. $locale = strtolower($this->session->getUser()->getInterfaceLocale());
  174. $cacheKey = self::$cachePrefix . $version . "-" . $edition . "-" . $locale;
  175. $modalContent = $this->cacheStorage->load($cacheKey);
  176. if ($modalContent === false) {
  177. $modalContent = $this->contentProvider->getContent($version, $edition, $locale);
  178. $this->cacheStorage->save($modalContent, $cacheKey);
  179. }
  180. return !$modalContent ? $modalContent : $this->unserializeContent($modalContent);
  181. }
  182. /**
  183. * Unserializes the notification modal content to be used for rendering
  184. *
  185. * @param string $modalContent
  186. * @return array|false
  187. */
  188. private function unserializeContent($modalContent)
  189. {
  190. $result = false;
  191. try {
  192. $result = $this->serializer->unserialize($modalContent);
  193. } catch (\InvalidArgumentException $e) {
  194. $this->logger->warning(
  195. sprintf(
  196. 'Failed to unserialize the release notification content. The error is: %s',
  197. $e->getMessage()
  198. )
  199. );
  200. }
  201. return $result;
  202. }
  203. /**
  204. * Returns the current Magento version used to retrieve the release notification content.
  205. * Version information after the dash (-) character is removed (ex. -dev or -rc).
  206. *
  207. * @return string
  208. */
  209. private function getTargetVersion()
  210. {
  211. $metadataVersion = $this->productMetadata->getVersion();
  212. $version = strstr($metadataVersion, '-', true);
  213. return !$version ? $metadataVersion : $version;
  214. }
  215. }