Layer.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model;
  7. use Magento\Catalog\Api\CategoryRepositoryInterface;
  8. use Magento\Framework\Exception\NoSuchEntityException;
  9. use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
  10. /**
  11. * Catalog view layer model
  12. *
  13. * @api
  14. * @SuppressWarnings(PHPMD.LongVariable)
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. * @since 100.0.2
  17. */
  18. class Layer extends \Magento\Framework\DataObject
  19. {
  20. /**
  21. * Product collections array
  22. *
  23. * @var array
  24. */
  25. protected $_productCollections = [];
  26. /**
  27. * Key which can be used for load/save aggregation data
  28. *
  29. * @var string
  30. */
  31. protected $_stateKey = null;
  32. /**
  33. * Core registry
  34. *
  35. * @var \Magento\Framework\Registry
  36. */
  37. protected $registry = null;
  38. /**
  39. * Store manager
  40. *
  41. * @var \Magento\Store\Model\StoreManagerInterface
  42. */
  43. protected $_storeManager;
  44. /**
  45. * Catalog product
  46. *
  47. * @var \Magento\Catalog\Model\ResourceModel\Product
  48. */
  49. protected $_catalogProduct;
  50. /**
  51. * Attribute collection factory
  52. *
  53. * @var AttributeCollectionFactory
  54. */
  55. protected $_attributeCollectionFactory;
  56. /**
  57. * Layer state factory
  58. *
  59. * @var \Magento\Catalog\Model\Layer\StateFactory
  60. */
  61. protected $_layerStateFactory;
  62. /**
  63. * @var \Magento\Catalog\Model\Layer\ItemCollectionProviderInterface
  64. */
  65. protected $collectionProvider;
  66. /**
  67. * @var \Magento\Catalog\Model\Layer\Category\StateKey
  68. */
  69. protected $stateKeyGenerator;
  70. /**
  71. * @var \Magento\Catalog\Model\Layer\Category\CollectionFilter
  72. */
  73. protected $collectionFilter;
  74. /**
  75. * @var CategoryRepositoryInterface
  76. */
  77. protected $categoryRepository;
  78. /**
  79. * @param Layer\ContextInterface $context
  80. * @param Layer\StateFactory $layerStateFactory
  81. * @param AttributeCollectionFactory $attributeCollectionFactory
  82. * @param \Magento\Catalog\Model\ResourceModel\Product $catalogProduct
  83. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  84. * @param \Magento\Framework\Registry $registry
  85. * @param CategoryRepositoryInterface $categoryRepository
  86. * @param array $data
  87. */
  88. public function __construct(
  89. \Magento\Catalog\Model\Layer\ContextInterface $context,
  90. \Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
  91. AttributeCollectionFactory $attributeCollectionFactory,
  92. \Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
  93. \Magento\Store\Model\StoreManagerInterface $storeManager,
  94. \Magento\Framework\Registry $registry,
  95. CategoryRepositoryInterface $categoryRepository,
  96. array $data = []
  97. ) {
  98. $this->_layerStateFactory = $layerStateFactory;
  99. $this->_attributeCollectionFactory = $attributeCollectionFactory;
  100. $this->_catalogProduct = $catalogProduct;
  101. $this->_storeManager = $storeManager;
  102. $this->registry = $registry;
  103. $this->categoryRepository = $categoryRepository;
  104. $this->collectionProvider = $context->getCollectionProvider();
  105. $this->stateKeyGenerator = $context->getStateKey();
  106. $this->collectionFilter = $context->getCollectionFilter();
  107. parent::__construct($data);
  108. }
  109. /**
  110. * Get layer state key
  111. *
  112. * @return string
  113. */
  114. public function getStateKey()
  115. {
  116. if (!$this->_stateKey) {
  117. $this->_stateKey = $this->stateKeyGenerator->toString($this->getCurrentCategory());
  118. }
  119. return $this->_stateKey;
  120. }
  121. /**
  122. * Retrieve current layer product collection
  123. *
  124. * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
  125. */
  126. public function getProductCollection()
  127. {
  128. if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
  129. $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
  130. } else {
  131. $collection = $this->collectionProvider->getCollection($this->getCurrentCategory());
  132. $this->prepareProductCollection($collection);
  133. $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
  134. }
  135. return $collection;
  136. }
  137. /**
  138. * Initialize product collection
  139. *
  140. * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
  141. * @return \Magento\Catalog\Model\Layer
  142. */
  143. public function prepareProductCollection($collection)
  144. {
  145. $this->collectionFilter->filter($collection, $this->getCurrentCategory());
  146. return $this;
  147. }
  148. /**
  149. * Apply layer
  150. * Method is colling after apply all filters, can be used
  151. * for prepare some index data before getting information
  152. * about existing indexes
  153. *
  154. * @return \Magento\Catalog\Model\Layer
  155. */
  156. public function apply()
  157. {
  158. $stateSuffix = '';
  159. foreach ($this->getState()->getFilters() as $filterItem) {
  160. $stateSuffix .= '_' . $filterItem->getFilter()->getRequestVar() . '_' . $filterItem->getValueString();
  161. }
  162. if (!empty($stateSuffix)) {
  163. $this->_stateKey = $this->getStateKey() . $stateSuffix;
  164. }
  165. return $this;
  166. }
  167. /**
  168. * Retrieve current category model
  169. * If no category found in registry, the root will be taken
  170. *
  171. * @return \Magento\Catalog\Model\Category
  172. */
  173. public function getCurrentCategory()
  174. {
  175. $category = $this->getData('current_category');
  176. if ($category === null) {
  177. $category = $this->registry->registry('current_category');
  178. if ($category) {
  179. $this->setData('current_category', $category);
  180. } else {
  181. $category = $this->categoryRepository->get($this->getCurrentStore()->getRootCategoryId());
  182. $this->setData('current_category', $category);
  183. }
  184. }
  185. return $category;
  186. }
  187. /**
  188. * Change current category object
  189. *
  190. * @param mixed $category
  191. * @return \Magento\Catalog\Model\Layer
  192. * @throws \Magento\Framework\Exception\LocalizedException
  193. */
  194. public function setCurrentCategory($category)
  195. {
  196. if (is_numeric($category)) {
  197. try {
  198. $category = $this->categoryRepository->get($category);
  199. } catch (NoSuchEntityException $e) {
  200. throw new \Magento\Framework\Exception\LocalizedException(__('Please correct the category.'), $e);
  201. }
  202. } elseif ($category instanceof \Magento\Catalog\Model\Category) {
  203. if (!$category->getId()) {
  204. throw new \Magento\Framework\Exception\LocalizedException(__('Please correct the category.'));
  205. }
  206. } else {
  207. throw new \Magento\Framework\Exception\LocalizedException(
  208. __('Must be category model instance or its id.')
  209. );
  210. }
  211. if ($category->getId() != $this->getCurrentCategory()->getId()) {
  212. $this->setData('current_category', $category);
  213. }
  214. return $this;
  215. }
  216. /**
  217. * Retrieve current store model
  218. *
  219. * @return \Magento\Store\Model\Store
  220. */
  221. public function getCurrentStore()
  222. {
  223. return $this->_storeManager->getStore();
  224. }
  225. /**
  226. * Retrieve layer state object
  227. *
  228. * @return \Magento\Catalog\Model\Layer\State
  229. */
  230. public function getState()
  231. {
  232. $state = $this->getData('state');
  233. if ($state === null) {
  234. \Magento\Framework\Profiler::start(__METHOD__);
  235. $state = $this->_layerStateFactory->create();
  236. $this->setData('state', $state);
  237. \Magento\Framework\Profiler::stop(__METHOD__);
  238. }
  239. return $state;
  240. }
  241. }