PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php

https://github.com/codecrumb/magento-mirror
PHP | 346 lines | 192 code | 35 blank | 119 comment | 20 complexity | 6bf9ce90e9e656b8c3939342d46e1955 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Catalog
  23. * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Category resource collection
  28. *
  29. * @category Mage
  30. * @package Mage_Catalog
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Collection_Abstract
  34. {
  35. /**
  36. * Event prefix
  37. *
  38. * @var string
  39. */
  40. protected $_eventPrefix = 'catalog_category_collection';
  41. /**
  42. * Event object name
  43. *
  44. * @var string
  45. */
  46. protected $_eventObject = 'category_collection';
  47. protected $_productTable;
  48. /**
  49. * Store id, that we should count products on
  50. *
  51. * @var int
  52. */
  53. protected $_productStoreId;
  54. protected $_productWebsiteTable;
  55. protected $_loadWithProductCount = false;
  56. /**
  57. * Init collection and determine table names
  58. *
  59. */
  60. protected function _construct()
  61. {
  62. $this->_init('catalog/category');
  63. /**
  64. * @todo Why 'core/resource' is used here ? What if catalog will use another resource ?
  65. */
  66. $this->_productWebsiteTable = Mage::getSingleton('core/resource')->getTableName('catalog/product_website');
  67. $this->_productTable = Mage::getSingleton('core/resource')->getTableName('catalog/category_product');
  68. }
  69. /**
  70. * Enter description here...
  71. *
  72. * @param array $categoryIds
  73. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  74. */
  75. public function addIdFilter($categoryIds)
  76. {
  77. if (is_array($categoryIds)) {
  78. if (empty($categoryIds)) {
  79. $condition = '';
  80. } else {
  81. $condition = array('in' => $categoryIds);
  82. }
  83. } elseif (is_numeric($categoryIds)) {
  84. $condition = $categoryIds;
  85. } elseif (is_string($categoryIds)) {
  86. $ids = explode(',', $categoryIds);
  87. if (empty($ids)) {
  88. $condition = $categoryIds;
  89. } else {
  90. $condition = array('in' => $ids);
  91. }
  92. }
  93. $this->addFieldToFilter('entity_id', $condition);
  94. return $this;
  95. }
  96. /**
  97. * Enter description here...
  98. *
  99. * @param boolean $flag
  100. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  101. */
  102. public function setLoadProductCount($flag)
  103. {
  104. $this->_loadWithProductCount = $flag;
  105. return $this;
  106. }
  107. /**
  108. * Before collection load
  109. *
  110. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  111. */
  112. protected function _beforeLoad()
  113. {
  114. Mage::dispatchEvent($this->_eventPrefix . '_load_before',
  115. array($this->_eventObject => $this));
  116. return parent::_beforeLoad();
  117. }
  118. /**
  119. * After collection load
  120. *
  121. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  122. */
  123. protected function _afterLoad()
  124. {
  125. Mage::dispatchEvent($this->_eventPrefix . '_load_after',
  126. array($this->_eventObject => $this));
  127. return parent::_afterLoad();
  128. }
  129. /**
  130. * Set id of the store that we should count products on
  131. *
  132. * @param int $storeId
  133. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  134. */
  135. public function setProductStoreId($storeId)
  136. {
  137. $this->_productStoreId = $storeId;
  138. return $this;
  139. }
  140. /**
  141. * Get id of the store that we should count products on
  142. *
  143. * @return int
  144. */
  145. public function getProductStoreId()
  146. {
  147. if (is_null($this->_productStoreId)) {
  148. $this->_productStoreId = 0;
  149. }
  150. return $this->_productStoreId;
  151. }
  152. /**
  153. * Enter description here...
  154. *
  155. * @param boolean $printQuery
  156. * @param boolean $logQuery
  157. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  158. */
  159. public function load($printQuery = false, $logQuery = false)
  160. {
  161. if ($this->_loadWithProductCount) {
  162. $this->addAttributeToSelect('all_children');
  163. $this->addAttributeToSelect('is_anchor');
  164. }
  165. parent::load($printQuery, $logQuery);
  166. if ($this->_loadWithProductCount) {
  167. $this->_loadProductCount();
  168. }
  169. return $this;
  170. }
  171. /**
  172. * Load categories product count
  173. *
  174. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  175. */
  176. protected function _loadProductCount()
  177. {
  178. $this->loadProductCount($this->_items, true, true);
  179. }
  180. /**
  181. * Load product count for specified items
  182. *
  183. * @param array $items
  184. * @param boolean $countRegular get product count for regular (non-anchor) categories
  185. * @param boolean $countAnchor get product count for anchor categories
  186. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  187. */
  188. public function loadProductCount($items, $countRegular = true, $countAnchor = true)
  189. {
  190. $anchor = array();
  191. $regular = array();
  192. foreach ($items as $item) {
  193. if ($item->getIsAnchor()) {
  194. $anchor[$item->getId()] = $item;
  195. } else {
  196. $regular[$item->getId()] = $item;
  197. }
  198. }
  199. if ($countRegular) {
  200. // Retrieve regular categories product counts
  201. $regularIds = array_keys($regular);
  202. if (!empty($regularIds)) {
  203. $select = $this->_conn->select();
  204. $select->from(
  205. array('main_table'=>$this->_productTable),
  206. array('category_id', new Zend_Db_Expr('COUNT(main_table.product_id)'))
  207. )
  208. ->where($this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds))
  209. ->group('main_table.category_id');
  210. $counts = $this->_conn->fetchPairs($select);
  211. foreach ($regular as $item) {
  212. if (isset($counts[$item->getId()])) {
  213. $item->setProductCount($counts[$item->getId()]);
  214. } else {
  215. $item->setProductCount(0);
  216. }
  217. }
  218. }
  219. }
  220. if ($countAnchor) {
  221. // Retrieve Anchor categories product counts
  222. foreach ($anchor as $item) {
  223. if ($allChildren = $item->getAllChildren()) {
  224. $select = $this->_conn->select();
  225. $select->from(
  226. array('main_table' => $this->_productTable),
  227. new Zend_Db_Expr('COUNT( DISTINCT main_table.product_id)')
  228. )
  229. ->joinInner(array('e' => $this->getTable('catalog/category')), 'main_table.category_id=e.entity_id', array())
  230. ->where('e.entity_id=? OR ' . $this->_conn->quoteInto('e.path LIKE CONCAT(?)', array($item->getPath(), '/%')), $item->getId());
  231. $item->setProductCount((int) $this->_conn->fetchOne($select));
  232. } else {
  233. $item->setProductCount(0);
  234. }
  235. }
  236. }
  237. return $this;
  238. }
  239. /**
  240. * Enter description here...
  241. *
  242. * @param string $regexp
  243. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  244. */
  245. public function addPathFilter($regexp)
  246. {
  247. $this->getSelect()->where(new Zend_Db_Expr("path regexp '{$regexp}'"));
  248. return $this;
  249. }
  250. /**
  251. * Joins url rewrite rules to collection
  252. *
  253. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  254. */
  255. public function joinUrlRewrite()
  256. {
  257. $storeId = Mage::app()->getStore()->getId();
  258. $this->joinTable(
  259. 'core/url_rewrite',
  260. 'category_id=entity_id',
  261. array('request_path'),
  262. '{{table}}.is_system=1 AND {{table}}.product_id IS NULL AND {{table}}.store_id="'.$storeId.'" AND id_path LIKE "category/%"',
  263. 'left'
  264. );
  265. return $this;
  266. }
  267. public function addIsActiveFilter()
  268. {
  269. $this->addAttributeToFilter('is_active', 1);
  270. Mage::dispatchEvent($this->_eventPrefix . '_add_is_active_filter',
  271. array($this->_eventObject => $this));
  272. return $this;
  273. }
  274. public function addNameToResult()
  275. {
  276. $this->addAttributeToSelect('name');
  277. return $this;
  278. }
  279. public function addUrlRewriteToResult()
  280. {
  281. $this->joinUrlRewrite();
  282. return $this;
  283. }
  284. public function addPathsFilter($paths)
  285. {
  286. if (!is_array($paths)) {
  287. $paths = array($paths);
  288. }
  289. $select = $this->getSelect();
  290. $orWhere = false;
  291. foreach ($paths as $path) {
  292. if ($orWhere) {
  293. $select->orWhere('e.path LIKE ?', "$path%");
  294. } else {
  295. $select->where('e.path LIKE ?', "$path%");
  296. $orWhere = true;
  297. }
  298. }
  299. return $this;
  300. }
  301. public function addLevelFilter($level)
  302. {
  303. $this->getSelect()->where('e.level <= ?', $level);
  304. return $this;
  305. }
  306. public function addOrderField($field)
  307. {
  308. $this->setOrder($field, 'ASC');
  309. return $this;
  310. }
  311. }