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_Tag_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
36: {
37: 38: 39: 40: 41:
42: protected $_customerFilterId;
43:
44: 45: 46: 47: 48:
49: protected $_tagIdFilter;
50:
51: 52: 53: 54: 55:
56: protected $_joinFlags = array();
57:
58: 59: 60: 61: 62:
63: protected function _initSelect()
64: {
65: parent::_initSelect();
66:
67: $this->_joinFields();
68: $this->getSelect()->group('e.entity_id');
69:
70: 71: 72:
73: $this->_useAnalyticFunction = true;
74:
75: return $this;
76: }
77:
78: 79: 80: 81: 82: 83: 84: 85: 86:
87: public function setJoinFlag($table)
88: {
89: $this->setFlag($table, true);
90: return $this;
91: }
92:
93: 94: 95: 96: 97: 98: 99: 100: 101:
102: public function getJoinFlag($table)
103: {
104: return $this->getFlag($table);
105: }
106:
107: 108: 109: 110: 111: 112: 113: 114: 115:
116: public function unsetJoinFlag($table = null)
117: {
118: $this->setFlag($table, false);
119: return $this;
120: }
121:
122: 123: 124: 125: 126:
127: public function addStoresVisibility()
128: {
129: $this->setFlag('add_stores_after', true);
130: return $this;
131: }
132:
133: 134: 135: 136: 137:
138: protected function _addStoresVisibility()
139: {
140: $tagIds = array();
141: foreach ($this as $item) {
142: $tagIds[] = $item->getTagId();
143: }
144:
145: $tagsStores = array();
146: if (sizeof($tagIds) > 0) {
147: $select = $this->getConnection()->select()
148: ->from($this->getTable('tag/relation'), array('store_id', 'tag_id'))
149: ->where('tag_id IN(?)', $tagIds);
150: $tagsRaw = $this->getConnection()->fetchAll($select);
151: foreach ($tagsRaw as $tag) {
152: if (!isset($tagsStores[$tag['tag_id']])) {
153: $tagsStores[$tag['tag_id']] = array();
154: }
155:
156: $tagsStores[$tag['tag_id']][] = $tag['store_id'];
157: }
158: }
159:
160: foreach ($this as $item) {
161: if (isset($tagsStores[$item->getTagId()])) {
162: $item->setStores($tagsStores[$item->getTagId()]);
163: } else {
164: $item->setStores(array());
165: }
166: }
167:
168: return $this;
169: }
170:
171: 172: 173: 174: 175:
176: public function addGroupByTag()
177: {
178: $this->getSelect()->group('relation.tag_relation_id');
179: return $this;
180: }
181:
182: 183: 184: 185: 186: 187:
188: public function addStoreFilter($store = null)
189: {
190: if (!is_null($store)) {
191: $this->getSelect()->where('relation.store_id IN (?)', $store);
192: }
193: return $this;
194: }
195:
196: 197: 198: 199: 200: 201: 202: 203: 204:
205: public function addCustomerFilter($customerId)
206: {
207: if (is_array($customerId) && isset($customerId['null'])) {
208: $condition = ($customerId['null']) ? 'IS NULL' : 'IS NOT NULL';
209: $this->getSelect()->where('relation.customer_id ' . $condition);
210: return $this;
211: }
212: $this->getSelect()->where('relation.customer_id IN(?)', $customerId);
213: $this->_customerFilterId = $customerId;
214: return $this;
215: }
216:
217: 218: 219: 220: 221: 222:
223: public function addTagFilter($tagId)
224: {
225: $this->getSelect()->where('relation.tag_id = ?', $tagId);
226: $this->setFlag('distinct', true);
227: return $this;
228: }
229:
230: 231: 232: 233: 234: 235:
236: public function addStatusFilter($status)
237: {
238: $this->getSelect()->where('t.status = ?', $status);
239: return $this;
240: }
241:
242: 243: 244: 245: 246: 247:
248: public function setDescOrder($dir = 'DESC')
249: {
250: $this->setOrder('relation.tag_relation_id', $dir);
251: return $this;
252: }
253:
254: 255: 256: 257: 258: 259: 260:
261: public function addPopularity($tagId, $storeId = null)
262: {
263: $tagRelationTable = $this->getTable('tag/relation');
264:
265: $condition = array(
266: 'prelation.product_id=e.entity_id'
267: );
268:
269: if (!is_null($storeId)) {
270: $condition[] = $this->getConnection()->quoteInto('prelation.store_id = ?', $storeId);
271: }
272: $condition = join(' AND ', $condition);
273: $innerSelect = $this->getConnection()->select()
274: ->from(
275: array('relation' => $tagRelationTable),
276: array('product_id', 'store_id', 'popularity' => 'COUNT(DISTINCT relation.tag_relation_id)')
277: )
278: ->where('relation.tag_id = ?', $tagId)
279: ->group(array('product_id', 'store_id'));
280:
281: $this->getSelect()
282: ->joinLeft(
283: array('prelation' => $innerSelect),
284: $condition,
285: array('popularity' => 'prelation.popularity')
286: );
287:
288: $this->_tagIdFilter = $tagId;
289: $this->setFlag('prelation', true);
290: return $this;
291: }
292:
293: 294: 295: 296: 297: 298:
299: public function addPopularityFilter($condition)
300: {
301: $tagRelationTable = Mage::getSingleton('core/resource')
302: ->getTableName('tag/relation');
303:
304: $select = $this->getConnection()->select()
305: ->from($tagRelationTable, array('product_id', 'popularity' => 'COUNT(DISTINCT tag_relation_id)'))
306: ->where('tag_id = :tag_id')
307: ->group('product_id')
308: ->having($this->_getConditionSql('popularity', $condition));
309:
310: $prodIds = array();
311: foreach ($this->getConnection()->fetchAll($select, array('tag_id' => $this->_tagIdFilter)) as $item) {
312: $prodIds[] = $item['product_id'];
313: }
314:
315: if (sizeof($prodIds) > 0) {
316: $this->getSelect()->where('e.entity_id IN(?)', $prodIds);
317: } else {
318: $this->getSelect()->where('e.entity_id IN(0)');
319: }
320:
321: return $this;
322: }
323:
324: 325: 326: 327: 328:
329: public function setActiveFilter()
330: {
331: $active = Mage_Tag_Model_Tag_Relation::STATUS_ACTIVE;
332: $this->getSelect()->where('relation.active = ?', $active);
333: if ($this->getFlag('prelation')) {
334: $this->getSelect()->where('prelation.active = ?', $active);
335: }
336: return $this;
337: }
338:
339: 340: 341: 342: 343: 344:
345: public function addProductTags($storeId = null)
346: {
347: foreach ($this->getItems() as $item) {
348: $tagsCollection = Mage::getModel('tag/tag')->getResourceCollection();
349:
350: if (!is_null($storeId)) {
351: $tagsCollection->addStoreFilter($storeId);
352: }
353:
354: $tagsCollection->addPopularity()
355: ->addProductFilter($item->getEntityId())
356: ->addCustomerFilter($this->_customerFilterId)
357: ->setActiveFilter();
358:
359: $tagsCollection->load();
360: $item->setProductTags($tagsCollection);
361: }
362:
363: return $this;
364: }
365:
366: 367: 368: 369: 370:
371: protected function _joinFields()
372: {
373: $tagTable = $this->getTable('tag/tag');
374: $tagRelationTable = $this->getTable('tag/relation');
375:
376: $this->addAttributeToSelect('name')
377: ->addAttributeToSelect('price')
378: ->addAttributeToSelect('small_image');
379:
380: $this->getSelect()
381: ->join(array('relation' => $tagRelationTable), 'relation.product_id = e.entity_id', array(
382: 'product_id' => 'product_id',
383: 'item_store_id' => 'store_id',
384: ))
385: ->join(array('t' => $tagTable),
386: 't.tag_id = relation.tag_id',
387: array(
388: 'tag_id',
389: 'tag_status' => 'status',
390: 'tag_name' => 'name',
391: 'store_id' => $this->getConnection()->getCheckSql(
392: 't.first_store_id = 0',
393: 'relation.store_id',
394: 't.first_store_id'
395: )
396: )
397: );
398:
399: return $this;
400: }
401:
402: 403: 404: 405: 406:
407: protected function _afterLoad()
408: {
409: parent::_afterLoad();
410:
411: if ($this->getFlag('add_stores_after')) {
412: $this->_addStoresVisibility();
413: }
414:
415: if (count($this) > 0) {
416: Mage::dispatchEvent('tag_tag_product_collection_load_after', array(
417: 'collection' => $this
418: ));
419: }
420:
421: return $this;
422: }
423:
424: 425: 426: 427: 428:
429: public function getSelectCountSql()
430: {
431: $countSelect = clone $this->getSelect();
432:
433: $countSelect->reset(Zend_Db_Select::COLUMNS);
434: $countSelect->reset(Zend_Db_Select::ORDER);
435: $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
436: $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
437: $countSelect->reset(Zend_Db_Select::GROUP);
438:
439: if ($this->getFlag('group_tag')) {
440: $field = 'relation.tag_id';
441: } else {
442: $field = 'e.entity_id';
443: }
444: $expr = new Zend_Db_Expr('COUNT('
445: . ($this->getFlag('distinct') ? 'DISTINCT ' : '')
446: . $field . ')');
447:
448: $countSelect->columns($expr);
449:
450: return $countSelect;
451: }
452:
453: 454: 455: 456: 457: 458: 459:
460: public function setOrder($attribute, $dir = 'desc')
461: {
462: if ($attribute == 'popularity') {
463: $this->getSelect()->order($attribute . ' ' . $dir);
464: } else {
465: parent::setOrder($attribute, $dir);
466: }
467: return $this;
468: }
469:
470: 471: 472: 473: 474:
475: public function setRelationId()
476: {
477: $this->_setIdFieldName('tag_relation_id');
478: return $this;
479: }
480: }
481: