Importer.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Store\Model\Config;
  7. use Magento\Framework\App\CacheInterface;
  8. use Magento\Framework\App\DeploymentConfig\ImporterInterface;
  9. use Magento\Framework\Exception\State\InvalidTransitionException;
  10. use Magento\Store\Model\Config\Importer\DataDifferenceCalculator;
  11. use Magento\Store\Model\Config\Importer\Processor\ProcessorFactory;
  12. use Magento\Store\Model\ScopeInterface;
  13. use Magento\Store\Model\StoreManagerInterface;
  14. use Magento\Store\Model\ResourceModel\Website;
  15. /**
  16. * Imports stores, websites and groups from transmitted data.
  17. */
  18. class Importer implements ImporterInterface
  19. {
  20. /**
  21. * The data difference calculator.
  22. *
  23. * @var DataDifferenceCalculator
  24. */
  25. private $dataDifferenceCalculator;
  26. /**
  27. * The factory for processors.
  28. *
  29. * @var ProcessorFactory
  30. */
  31. private $processFactory;
  32. /**
  33. * The manager for operations with store.
  34. *
  35. * @var StoreManagerInterface
  36. */
  37. private $storeManager;
  38. /**
  39. * The resource of transaction.
  40. *
  41. * @var Website
  42. */
  43. private $resource;
  44. /**
  45. * The application cache manager.
  46. *
  47. * @var CacheInterface
  48. */
  49. private $cacheManager;
  50. /**
  51. * @param DataDifferenceCalculator $dataDifferenceCalculator The factory for data difference calculators
  52. * @param ProcessorFactory $processFactory The factory for processes
  53. * @param StoreManagerInterface $storeManager The manager for operations with store
  54. * @param CacheInterface $cacheManager The application cache manager
  55. * @param Website $resource The resource of transaction
  56. */
  57. public function __construct(
  58. DataDifferenceCalculator $dataDifferenceCalculator,
  59. ProcessorFactory $processFactory,
  60. StoreManagerInterface $storeManager,
  61. CacheInterface $cacheManager,
  62. Website $resource
  63. ) {
  64. $this->dataDifferenceCalculator = $dataDifferenceCalculator;
  65. $this->processFactory = $processFactory;
  66. $this->storeManager = $storeManager;
  67. $this->cacheManager = $cacheManager;
  68. $this->resource = $resource;
  69. }
  70. /**
  71. * Imports the store data into the application.
  72. * After the import it flushes the store caches.
  73. *
  74. * {@inheritdoc}
  75. */
  76. public function import(array $data)
  77. {
  78. $actions = [
  79. ProcessorFactory::TYPE_CREATE,
  80. ProcessorFactory::TYPE_DELETE,
  81. ProcessorFactory::TYPE_UPDATE
  82. ];
  83. $messages = ['Stores were processed'];
  84. try {
  85. $newGroups = $this->getGroupsToCreate($data);
  86. if ($newGroups) {
  87. $messages[] = sprintf(
  88. $this->getStoreGroupAssignMessage(),
  89. implode(', ', array_column($newGroups, 'name'))
  90. );
  91. }
  92. // during import websites/stores database already has new entities
  93. // but cache is outdated which can cause to error in some cases
  94. $this->reinitStores();
  95. $this->resource->beginTransaction();
  96. foreach ($actions as $action) {
  97. $this->processFactory->create($action)->run($data);
  98. }
  99. } catch (\Exception $exception) {
  100. $this->resource->rollBack();
  101. $this->reinitStores();
  102. throw new InvalidTransitionException(__('%1', $exception->getMessage()), $exception);
  103. }
  104. $this->resource->commit();
  105. $this->reinitStores();
  106. return $messages;
  107. }
  108. /**
  109. * Reinitialize store list.
  110. *
  111. * @return void
  112. */
  113. private function reinitStores()
  114. {
  115. $this->storeManager->reinitStores();
  116. $this->cacheManager->clean();
  117. }
  118. /**
  119. * Retrieves message reminder about root category assigning.
  120. *
  121. * @return string
  122. */
  123. private function getStoreGroupAssignMessage()
  124. {
  125. return 'The following new store groups must be associated with a root category: %s. '
  126. . PHP_EOL
  127. . 'Associate a store group with a root category in the Admin Panel: Stores > Settings > All Stores.';
  128. }
  129. /**
  130. * Checks which new store groups will be created.
  131. *
  132. * @param array $data The data set.
  133. * @return array
  134. */
  135. private function getGroupsToCreate(array $data)
  136. {
  137. if (!isset($data[ScopeInterface::SCOPE_GROUPS])) {
  138. return [];
  139. }
  140. $groups = $this->dataDifferenceCalculator->getItemsToCreate(
  141. ScopeInterface::SCOPE_GROUPS,
  142. $data[ScopeInterface::SCOPE_GROUPS]
  143. );
  144. return $groups;
  145. }
  146. /**
  147. * Retrieves all affected entities during the import procedure.
  148. *
  149. * {@inheritdoc}
  150. */
  151. public function getWarningMessages(array $data)
  152. {
  153. $messages = [];
  154. foreach ($data as $scope => $scopeData) {
  155. $messageMap = [
  156. 'These %s will be deleted: %s' => $this->dataDifferenceCalculator->getItemsToDelete($scope, $scopeData),
  157. 'These %s will be updated: %s' => $this->dataDifferenceCalculator->getItemsToUpdate($scope, $scopeData),
  158. 'These %s will be created: %s' => $this->dataDifferenceCalculator->getItemsToCreate($scope, $scopeData),
  159. ];
  160. foreach ($messageMap as $message => $items) {
  161. if (!$items) {
  162. continue;
  163. }
  164. $messages[] = $this->formatMessage($message, $items, $scope);
  165. }
  166. }
  167. return $messages;
  168. }
  169. /**
  170. * Formats message to appropriate format.
  171. *
  172. * @param string $message The message to display
  173. * @param array $items The items to be used
  174. * @param string $scope The given scope
  175. * @return string
  176. */
  177. private function formatMessage($message, array $items, $scope)
  178. {
  179. return sprintf(
  180. $message,
  181. ucfirst($scope),
  182. implode(', ', array_column($items, 'name'))
  183. );
  184. }
  185. }