Collector.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Quote\Model\Quote\Address\Total;
  7. use Magento\Framework\Serialize\SerializerInterface;
  8. /**
  9. * Address Total Collector model
  10. */
  11. class Collector extends \Magento\Sales\Model\Config\Ordered
  12. {
  13. /**
  14. * Path to sort order values of checkout totals
  15. */
  16. const XML_PATH_SALES_TOTALS_SORT = 'sales/totals_sort';
  17. /**
  18. * Total models array ordered for right display sequence
  19. *
  20. * @var array
  21. */
  22. protected $_retrievers = [];
  23. /**
  24. * Corresponding store object
  25. *
  26. * @var \Magento\Store\Model\Store
  27. */
  28. protected $_store;
  29. /**
  30. * Config group for totals declaration
  31. *
  32. * @var string
  33. */
  34. protected $_configGroup = 'totals';
  35. /**
  36. * @var string
  37. */
  38. protected $_configSection = 'quote';
  39. /**
  40. * Cache key for collectors
  41. *
  42. * @var string
  43. */
  44. protected $_collectorsCacheKey = 'sorted_quote_collectors';
  45. /**
  46. * Core store config
  47. *
  48. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  49. */
  50. protected $_scopeConfig;
  51. /**
  52. * @var \Magento\Quote\Model\Quote\Address\TotalFactory
  53. */
  54. protected $_totalFactory;
  55. /**
  56. * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
  57. * @param \Psr\Log\LoggerInterface $logger
  58. * @param \Magento\Sales\Model\Config $salesConfig
  59. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  60. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  61. * @param \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory
  62. * @param \Magento\Framework\Simplexml\Element|mixed $sourceData
  63. * @param mixed $store
  64. * @param SerializerInterface $serializer
  65. */
  66. public function __construct(
  67. \Magento\Framework\App\Cache\Type\Config $configCacheType,
  68. \Psr\Log\LoggerInterface $logger,
  69. \Magento\Sales\Model\Config $salesConfig,
  70. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  71. \Magento\Store\Model\StoreManagerInterface $storeManager,
  72. \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory,
  73. $sourceData = null,
  74. $store = null,
  75. SerializerInterface $serializer = null
  76. ) {
  77. $this->_scopeConfig = $scopeConfig;
  78. $this->_totalFactory = $totalFactory;
  79. parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer);
  80. $this->_store = $store ?: $storeManager->getStore();
  81. $this->_initModels()->_initCollectors()->_initRetrievers();
  82. }
  83. /**
  84. * Get total models array ordered for right calculation logic
  85. *
  86. * @return array
  87. */
  88. public function getCollectors()
  89. {
  90. return $this->_collectors;
  91. }
  92. /**
  93. * Get total models array ordered for right display sequence
  94. *
  95. * @return \Magento\Quote\Model\Quote\Address\Total\AbstractTotal[]
  96. */
  97. public function getRetrievers()
  98. {
  99. return $this->_retrievers;
  100. }
  101. /**
  102. * Init model class by configuration
  103. *
  104. * @param string $class
  105. * @param string $totalCode
  106. * @param array $totalConfig
  107. * @return \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
  108. * @throws \Magento\Framework\Exception\LocalizedException
  109. */
  110. protected function _initModelInstance($class, $totalCode, $totalConfig)
  111. {
  112. $model = $this->_totalFactory->create($class);
  113. if (!$model instanceof \Magento\Quote\Model\Quote\Address\Total\AbstractTotal) {
  114. throw new \Magento\Framework\Exception\LocalizedException(
  115. __(
  116. 'The address total model should be extended from
  117. \Magento\Quote\Model\Quote\Address\Total\AbstractTotal.'
  118. )
  119. );
  120. }
  121. $model->setCode($totalCode);
  122. $this->_modelsConfig[$totalCode] = $this->_prepareConfigArray($totalCode, $totalConfig);
  123. $this->_modelsConfig[$totalCode] = $model->processConfigArray($this->_modelsConfig[$totalCode], $this->_store);
  124. return $model;
  125. }
  126. /**
  127. * Initialize retrievers array
  128. *
  129. * @return $this
  130. * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
  131. */
  132. private function _initRetrievers()
  133. {
  134. $sorts = $this->_scopeConfig->getValue(
  135. self::XML_PATH_SALES_TOTALS_SORT,
  136. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  137. $this->_store
  138. );
  139. foreach ($sorts as $code => $sortOrder) {
  140. if (isset($this->_models[$code])) {
  141. // Reserve enough space for collisions
  142. $retrieverId = 100 * (int)$sortOrder;
  143. // Check if there is a retriever with such id and find next available position if needed
  144. while (isset($this->_retrievers[$retrieverId])) {
  145. $retrieverId++;
  146. }
  147. $this->_retrievers[$retrieverId] = $this->_models[$code];
  148. }
  149. }
  150. ksort($this->_retrievers);
  151. $notSorted = array_diff(array_keys($this->_models), array_keys($sorts));
  152. foreach ($notSorted as $code) {
  153. $this->_retrievers[] = $this->_models[$code];
  154. }
  155. return $this;
  156. }
  157. }