1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: 29: 30: 31: 32: 33: 34:
35: class Mage_Catalog_Model_Resource_Category_Collection extends Mage_Catalog_Model_Resource_Collection_Abstract
36: {
37: 38: 39: 40: 41:
42: protected $_eventPrefix = 'catalog_category_collection';
43:
44: 45: 46: 47: 48:
49: protected $_eventObject = 'category_collection';
50:
51: 52: 53: 54: 55:
56: protected $_productTable;
57:
58: 59: 60: 61: 62:
63: protected $_productStoreId;
64:
65: 66: 67: 68: 69:
70: protected $_productWebsiteTable;
71:
72: 73: 74: 75: 76:
77: protected $_loadWithProductCount = false;
78:
79: 80: 81: 82:
83: protected function _construct()
84: {
85: $this->_init('catalog/category');
86:
87: $this->_productWebsiteTable = $this->getTable('catalog/product_website');
88: $this->_productTable = $this->getTable('catalog/category_product');
89: }
90:
91: 92: 93: 94: 95: 96:
97: public function addIdFilter($categoryIds)
98: {
99: if (is_array($categoryIds)) {
100: if (empty($categoryIds)) {
101: $condition = '';
102: } else {
103: $condition = array('in' => $categoryIds);
104: }
105: } elseif (is_numeric($categoryIds)) {
106: $condition = $categoryIds;
107: } elseif (is_string($categoryIds)) {
108: $ids = explode(',', $categoryIds);
109: if (empty($ids)) {
110: $condition = $categoryIds;
111: } else {
112: $condition = array('in' => $ids);
113: }
114: }
115: $this->addFieldToFilter('entity_id', $condition);
116: return $this;
117: }
118:
119: 120: 121: 122: 123: 124:
125: public function setLoadProductCount($flag)
126: {
127: $this->_loadWithProductCount = $flag;
128: return $this;
129: }
130:
131: 132: 133: 134: 135:
136: protected function _beforeLoad()
137: {
138: Mage::dispatchEvent($this->_eventPrefix . '_load_before',
139: array($this->_eventObject => $this));
140: return parent::_beforeLoad();
141: }
142:
143: 144: 145: 146: 147:
148: protected function _afterLoad()
149: {
150: Mage::dispatchEvent($this->_eventPrefix . '_load_after',
151: array($this->_eventObject => $this));
152:
153: return parent::_afterLoad();
154: }
155:
156: 157: 158: 159: 160: 161:
162: public function setProductStoreId($storeId)
163: {
164: $this->_productStoreId = $storeId;
165: return $this;
166: }
167:
168: 169: 170: 171: 172:
173: public function getProductStoreId()
174: {
175: if (is_null($this->_productStoreId)) {
176: $this->_productStoreId = Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID;
177: }
178: return $this->_productStoreId;
179: }
180:
181: 182: 183: 184: 185: 186: 187:
188: public function load($printQuery = false, $logQuery = false)
189: {
190: if ($this->isLoaded()) {
191: return $this;
192: }
193:
194: if ($this->_loadWithProductCount) {
195: $this->addAttributeToSelect('all_children');
196: $this->addAttributeToSelect('is_anchor');
197: }
198:
199: parent::load($printQuery, $logQuery);
200:
201: if ($this->_loadWithProductCount) {
202: $this->_loadProductCount();
203: }
204:
205: return $this;
206: }
207:
208: 209: 210: 211:
212: protected function _loadProductCount()
213: {
214: $this->loadProductCount($this->_items, true, true);
215: }
216:
217: 218: 219: 220: 221: 222: 223: 224:
225: public function loadProductCount($items, $countRegular = true, $countAnchor = true)
226: {
227: $anchor = array();
228: $regular = array();
229: $websiteId = Mage::app()->getStore($this->getProductStoreId())->getWebsiteId();
230:
231: foreach ($items as $item) {
232: if ($item->getIsAnchor()) {
233: $anchor[$item->getId()] = $item;
234: } else {
235: $regular[$item->getId()] = $item;
236: }
237: }
238:
239: if ($countRegular) {
240:
241: $regularIds = array_keys($regular);
242: if (!empty($regularIds)) {
243: $select = $this->_conn->select();
244: $select->from(
245: array('main_table' => $this->_productTable),
246: array('category_id', new Zend_Db_Expr('COUNT(main_table.product_id)'))
247: )
248: ->where($this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds))
249: ->group('main_table.category_id');
250: if ($websiteId) {
251: $select->join(
252: array('w' => $this->_productWebsiteTable),
253: 'main_table.product_id = w.product_id', array()
254: )
255: ->where('w.website_id = ?', $websiteId);
256: }
257: $counts = $this->_conn->fetchPairs($select);
258: foreach ($regular as $item) {
259: if (isset($counts[$item->getId()])) {
260: $item->setProductCount($counts[$item->getId()]);
261: } else {
262: $item->setProductCount(0);
263: }
264: }
265: }
266: }
267:
268: if ($countAnchor) {
269:
270: foreach ($anchor as $item) {
271: if ($allChildren = $item->getAllChildren()) {
272: $bind = array(
273: 'entity_id' => $item->getId(),
274: 'c_path' => $item->getPath() . '/%'
275: );
276: $select = $this->_conn->select();
277: $select->from(
278: array('main_table' => $this->_productTable),
279: new Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)')
280: )
281: ->joinInner(
282: array('e' => $this->getTable('catalog/category')),
283: 'main_table.category_id=e.entity_id',
284: array()
285: )
286: ->where('e.entity_id = :entity_id')
287: ->orWhere('e.path LIKE :c_path');
288: if ($websiteId) {
289: $select->join(
290: array('w' => $this->_productWebsiteTable),
291: 'main_table.product_id = w.product_id', array()
292: )
293: ->where('w.website_id = ?', $websiteId);
294: }
295: $item->setProductCount((int) $this->_conn->fetchOne($select, $bind));
296: } else {
297: $item->setProductCount(0);
298: }
299: }
300: }
301: return $this;
302: }
303:
304: 305: 306: 307: 308: 309:
310: public function addPathFilter($regexp)
311: {
312: $this->addFieldToFilter('path', array('regexp' => $regexp));
313: return $this;
314: }
315:
316: 317: 318: 319: 320:
321: public function joinUrlRewrite()
322: {
323: $storeId = Mage::app()->getStore()->getId();
324: $this->joinTable(
325: 'core/url_rewrite',
326: 'category_id=entity_id',
327: array('request_path'),
328: "{{table}}.is_system=1"
329: . " AND {{table}}.product_id IS NULL"
330: . " AND {{table}}.store_id='{$storeId}'"
331: . " AND id_path LIKE 'category/%'",
332: 'left'
333: );
334: return $this;
335: }
336:
337: 338: 339: 340: 341:
342: public function addIsActiveFilter()
343: {
344: $this->addAttributeToFilter('is_active', 1);
345: Mage::dispatchEvent($this->_eventPrefix . '_add_is_active_filter',
346: array($this->_eventObject => $this));
347: return $this;
348: }
349:
350: 351: 352: 353: 354:
355: public function addNameToResult()
356: {
357: $this->addAttributeToSelect('name');
358: return $this;
359: }
360:
361: 362: 363: 364: 365:
366: public function addUrlRewriteToResult()
367: {
368: $this->joinUrlRewrite();
369: return $this;
370: }
371:
372: 373: 374: 375: 376: 377:
378: public function addPathsFilter($paths)
379: {
380: if (!is_array($paths)) {
381: $paths = array($paths);
382: }
383: $write = $this->getResource()->getWriteConnection();
384: $cond = array();
385: foreach ($paths as $path) {
386: $cond[] = $write->quoteInto('e.path LIKE ?', "$path%");
387: }
388: if ($cond) {
389: $this->getSelect()->where(join(' OR ', $cond));
390: }
391: return $this;
392: }
393:
394: 395: 396: 397: 398: 399:
400: public function addLevelFilter($level)
401: {
402: $this->addFieldToFilter('level', array('lteq' => $level));
403: return $this;
404: }
405:
406: 407: 408: 409: 410:
411: public function addRootLevelFilter()
412: {
413: $this->addFieldToFilter('path', array('neq' => '1'));
414: $this->addLevelFilter(1);
415: return $this;
416: }
417:
418: 419: 420: 421: 422: 423:
424: public function addOrderField($field)
425: {
426: $this->setOrder($field, self::SORT_ORDER_ASC);
427: return $this;
428: }
429: }
430: