PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-catalog/Model/ResourceModel/Category/Collection.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 442 lines | 246 code | 36 blank | 160 comment | 24 complexity | 36a46feb04ecb87353461c51da369ee6 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model\ResourceModel\Category;
  7. use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
  8. /**
  9. * Category resource collection
  10. *
  11. * @author Magento Core Team <core@magentocommerce.com>
  12. */
  13. class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection
  14. {
  15. /**
  16. * Event prefix
  17. *
  18. * @var string
  19. */
  20. protected $_eventPrefix = 'catalog_category_collection';
  21. /**
  22. * Event object name
  23. *
  24. * @var string
  25. */
  26. protected $_eventObject = 'category_collection';
  27. /**
  28. * Name of product table
  29. *
  30. * @var string
  31. */
  32. private $_productTable;
  33. /**
  34. * Store id, that we should count products on
  35. *
  36. * @var int
  37. */
  38. protected $_productStoreId;
  39. /**
  40. * Name of product website table
  41. *
  42. * @var string
  43. */
  44. private $_productWebsiteTable;
  45. /**
  46. * Load with product count flag
  47. *
  48. * @var boolean
  49. */
  50. protected $_loadWithProductCount = false;
  51. /**
  52. * Init collection and determine table names
  53. *
  54. * @return void
  55. */
  56. protected function _construct()
  57. {
  58. $this->_init('Magento\Catalog\Model\Category', 'Magento\Catalog\Model\ResourceModel\Category');
  59. }
  60. /**
  61. * Add Id filter
  62. *
  63. * @param array $categoryIds
  64. * @return $this
  65. */
  66. public function addIdFilter($categoryIds)
  67. {
  68. if (is_array($categoryIds)) {
  69. if (empty($categoryIds)) {
  70. $condition = '';
  71. } else {
  72. $condition = ['in' => $categoryIds];
  73. }
  74. } elseif (is_numeric($categoryIds)) {
  75. $condition = $categoryIds;
  76. } elseif (is_string($categoryIds)) {
  77. $ids = explode(',', $categoryIds);
  78. if (empty($ids)) {
  79. $condition = $categoryIds;
  80. } else {
  81. $condition = ['in' => $ids];
  82. }
  83. }
  84. $this->addFieldToFilter('entity_id', $condition);
  85. return $this;
  86. }
  87. /**
  88. * Set flag for loading product count
  89. *
  90. * @param boolean $flag
  91. * @return $this
  92. */
  93. public function setLoadProductCount($flag)
  94. {
  95. $this->_loadWithProductCount = $flag;
  96. return $this;
  97. }
  98. /**
  99. * Before collection load
  100. *
  101. * @return $this
  102. */
  103. protected function _beforeLoad()
  104. {
  105. $this->_eventManager->dispatch($this->_eventPrefix . '_load_before', [$this->_eventObject => $this]);
  106. return parent::_beforeLoad();
  107. }
  108. /**
  109. * After collection load
  110. *
  111. * @return $this
  112. */
  113. protected function _afterLoad()
  114. {
  115. $this->_eventManager->dispatch($this->_eventPrefix . '_load_after', [$this->_eventObject => $this]);
  116. return parent::_afterLoad();
  117. }
  118. /**
  119. * Set id of the store that we should count products on
  120. *
  121. * @param int $storeId
  122. * @return $this
  123. */
  124. public function setProductStoreId($storeId)
  125. {
  126. $this->_productStoreId = $storeId;
  127. return $this;
  128. }
  129. /**
  130. * Get id of the store that we should count products on
  131. *
  132. * @return int
  133. */
  134. public function getProductStoreId()
  135. {
  136. if ($this->_productStoreId === null) {
  137. $this->_productStoreId = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
  138. }
  139. return $this->_productStoreId;
  140. }
  141. /**
  142. * Load collection
  143. *
  144. * @param bool $printQuery
  145. * @param bool $logQuery
  146. * @return $this
  147. */
  148. public function load($printQuery = false, $logQuery = false)
  149. {
  150. if ($this->isLoaded()) {
  151. return $this;
  152. }
  153. if ($this->_loadWithProductCount) {
  154. $this->addAttributeToSelect('all_children');
  155. $this->addAttributeToSelect('is_anchor');
  156. }
  157. parent::load($printQuery, $logQuery);
  158. if ($this->_loadWithProductCount) {
  159. $this->_loadProductCount();
  160. }
  161. return $this;
  162. }
  163. /**
  164. * Load categories product count
  165. *
  166. * @return void
  167. */
  168. protected function _loadProductCount()
  169. {
  170. $this->loadProductCount($this->_items, true, true);
  171. }
  172. /**
  173. * Load product count for specified items
  174. *
  175. * @param array $items
  176. * @param boolean $countRegular get product count for regular (non-anchor) categories
  177. * @param boolean $countAnchor get product count for anchor categories
  178. * @return $this
  179. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  180. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  181. */
  182. public function loadProductCount($items, $countRegular = true, $countAnchor = true)
  183. {
  184. $anchor = [];
  185. $regular = [];
  186. $websiteId = $this->_storeManager->getStore($this->getProductStoreId())->getWebsiteId();
  187. foreach ($items as $item) {
  188. if ($item->getIsAnchor()) {
  189. $anchor[$item->getId()] = $item;
  190. } else {
  191. $regular[$item->getId()] = $item;
  192. }
  193. }
  194. if ($countRegular) {
  195. // Retrieve regular categories product counts
  196. $regularIds = array_keys($regular);
  197. if (!empty($regularIds)) {
  198. $select = $this->_conn->select();
  199. $select->from(
  200. ['main_table' => $this->getProductTable()],
  201. ['category_id', new \Zend_Db_Expr('COUNT(main_table.product_id)')]
  202. )->where(
  203. $this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds)
  204. )->group(
  205. 'main_table.category_id'
  206. );
  207. if ($websiteId) {
  208. $select->join(
  209. ['w' => $this->getProductWebsiteTable()],
  210. 'main_table.product_id = w.product_id',
  211. []
  212. )->where(
  213. 'w.website_id = ?',
  214. $websiteId
  215. );
  216. }
  217. $counts = $this->_conn->fetchPairs($select);
  218. foreach ($regular as $item) {
  219. if (isset($counts[$item->getId()])) {
  220. $item->setProductCount($counts[$item->getId()]);
  221. } else {
  222. $item->setProductCount(0);
  223. }
  224. }
  225. }
  226. }
  227. if ($countAnchor) {
  228. // Retrieve Anchor categories product counts
  229. foreach ($anchor as $item) {
  230. if ($allChildren = $item->getAllChildren()) {
  231. $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%'];
  232. $select = $this->_conn->select();
  233. $select->from(
  234. ['main_table' => $this->getProductTable()],
  235. new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
  236. )->joinInner(
  237. ['e' => $this->getTable('catalog_category_entity')],
  238. 'main_table.category_id=e.entity_id',
  239. []
  240. )->where(
  241. 'e.entity_id = :entity_id'
  242. )->orWhere(
  243. 'e.path LIKE :c_path'
  244. );
  245. if ($websiteId) {
  246. $select->join(
  247. ['w' => $this->getProductWebsiteTable()],
  248. 'main_table.product_id = w.product_id',
  249. []
  250. )->where(
  251. 'w.website_id = ?',
  252. $websiteId
  253. );
  254. }
  255. $item->setProductCount((int)$this->_conn->fetchOne($select, $bind));
  256. } else {
  257. $item->setProductCount(0);
  258. }
  259. }
  260. }
  261. return $this;
  262. }
  263. /**
  264. * Add category path filter
  265. *
  266. * @param string $regexp
  267. * @return $this
  268. */
  269. public function addPathFilter($regexp)
  270. {
  271. $this->addFieldToFilter('path', ['regexp' => $regexp]);
  272. return $this;
  273. }
  274. /**
  275. * Joins url rewrite rules to collection
  276. *
  277. * @return $this
  278. */
  279. public function joinUrlRewrite()
  280. {
  281. $this->joinTable(
  282. 'url_rewrite',
  283. 'entity_id = entity_id',
  284. ['request_path'],
  285. sprintf(
  286. '{{table}}.is_autogenerated = 1 AND {{table}}.store_id = %d AND {{table}}.entity_type = \'%s\'',
  287. $this->_storeManager->getStore()->getId(),
  288. CategoryUrlRewriteGenerator::ENTITY_TYPE
  289. ),
  290. 'left'
  291. );
  292. return $this;
  293. }
  294. /**
  295. * Add active category filter
  296. *
  297. * @return $this
  298. */
  299. public function addIsActiveFilter()
  300. {
  301. $this->addAttributeToFilter('is_active', 1);
  302. $this->_eventManager->dispatch(
  303. $this->_eventPrefix . '_add_is_active_filter',
  304. [$this->_eventObject => $this]
  305. );
  306. return $this;
  307. }
  308. /**
  309. * Add name attribute to result
  310. *
  311. * @return $this
  312. */
  313. public function addNameToResult()
  314. {
  315. $this->addAttributeToSelect('name');
  316. return $this;
  317. }
  318. /**
  319. * Add url rewrite rules to collection
  320. *
  321. * @return $this
  322. */
  323. public function addUrlRewriteToResult()
  324. {
  325. $this->joinUrlRewrite();
  326. return $this;
  327. }
  328. /**
  329. * Add category path filter
  330. *
  331. * @param array|string $paths
  332. * @return $this
  333. */
  334. public function addPathsFilter($paths)
  335. {
  336. if (!is_array($paths)) {
  337. $paths = [$paths];
  338. }
  339. $connection = $this->getResource()->getConnection();
  340. $cond = [];
  341. foreach ($paths as $path) {
  342. $cond[] = $connection->quoteInto('e.path LIKE ?', "{$path}%");
  343. }
  344. if ($cond) {
  345. $this->getSelect()->where(join(' OR ', $cond));
  346. }
  347. return $this;
  348. }
  349. /**
  350. * Add category level filter
  351. *
  352. * @param int|string $level
  353. * @return $this
  354. */
  355. public function addLevelFilter($level)
  356. {
  357. $this->addFieldToFilter('level', ['lteq' => $level]);
  358. return $this;
  359. }
  360. /**
  361. * Add root category filter
  362. *
  363. * @return $this
  364. */
  365. public function addRootLevelFilter()
  366. {
  367. $this->addFieldToFilter('path', ['neq' => '1']);
  368. $this->addLevelFilter(1);
  369. return $this;
  370. }
  371. /**
  372. * Add order field
  373. *
  374. * @param string $field
  375. * @return $this
  376. */
  377. public function addOrderField($field)
  378. {
  379. $this->setOrder($field, self::SORT_ORDER_ASC);
  380. return $this;
  381. }
  382. /**
  383. * Getter for _productWebsiteTable
  384. *
  385. * @return string
  386. */
  387. public function getProductWebsiteTable()
  388. {
  389. if (empty($this->_productWebsiteTable)) {
  390. $this->_productWebsiteTable = $this->getTable('catalog_product_website');
  391. }
  392. return $this->_productWebsiteTable;
  393. }
  394. /**
  395. * Getter for _productTable
  396. *
  397. * @return string
  398. */
  399. public function getProductTable()
  400. {
  401. if (empty($this->_productTable)) {
  402. $this->_productTable = $this->getTable('catalog_category_product');
  403. }
  404. return $this->_productTable;
  405. }
  406. }