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_Tag extends Mage_Core_Model_Resource_Db_Abstract
36: {
37: 38: 39: 40:
41: protected function _construct()
42: {
43: $this->_init('tag/tag', 'tag_id');
44: }
45:
46: 47: 48: 49: 50:
51: protected function _initUniqueFields()
52: {
53: $this->_uniqueFields = array(array(
54: 'field' => 'name',
55: 'title' => Mage::helper('tag')->__('Tag')
56: ));
57: return $this;
58: }
59:
60: 61: 62: 63: 64: 65: 66:
67: public function loadByName($model, $name)
68: {
69: if ( $name ) {
70: $read = $this->_getReadAdapter();
71: $select = $read->select();
72: if (Mage::helper('core/string')->strlen($name) > 255) {
73: $name = Mage::helper('core/string')->substr($name, 0, 255);
74: }
75:
76: $select->from($this->getMainTable())
77: ->where('name = :name');
78: $data = $read->fetchRow($select, array('name' => $name));
79:
80: $model->setData(( is_array($data) ) ? $data : array());
81: } else {
82: return false;
83: }
84: }
85:
86: 87: 88: 89: 90: 91:
92: protected function _beforeSave(Mage_Core_Model_Abstract $object)
93: {
94: if (!$object->getId() && $object->getStatus() == $object->getApprovedStatus()) {
95: $searchTag = new Varien_Object();
96: $this->loadByName($searchTag, $object->getName());
97: if ($searchTag->getData($this->getIdFieldName())
98: && $searchTag->getStatus() == $object->getPendingStatus()) {
99: $object->setId($searchTag->getData($this->getIdFieldName()));
100: }
101: }
102:
103: if (Mage::helper('core/string')->strlen($object->getName()) > 255) {
104: $object->setName(Mage::helper('core/string')->substr($object->getName(), 0, 255));
105: }
106:
107: return parent::_beforeSave($object);
108: }
109:
110: 111: 112: 113: 114: 115:
116: protected function _afterSave(Mage_Core_Model_Abstract $object)
117: {
118: if (!$object->getStore() || !Mage::app()->getStore()->isAdmin()) {
119: return parent::_afterSave($object);
120: }
121:
122: $tagId = ($object->isObjectNew()) ? $object->getTagId() : $object->getId();
123:
124: $writeAdapter = $this->_getWriteAdapter();
125: $writeAdapter->insertOnDuplicate($this->getTable('tag/properties'), array(
126: 'tag_id' => $tagId,
127: 'store_id' => $object->getStore(),
128: 'base_popularity' => (!$object->getBasePopularity()) ? 0 : $object->getBasePopularity()
129: ));
130:
131: return parent::_afterSave($object);
132: }
133:
134: 135: 136: 137: 138: 139: 140: 141:
142: protected function _getExistingBasePopularity($tagId)
143: {
144: $read = $this->_getReadAdapter();
145: $selectSummary = $read->select()
146: ->from(
147: array('main' => $this->getTable('tag/summary')),
148: array('store_id', 'base_popularity')
149: )
150: ->where('main.tag_id = :tag_id')
151: ->where('main.store_id != 0');
152:
153: return $read->fetchAssoc($selectSummary, array('tag_id' => $tagId));
154: }
155:
156: 157: 158: 159: 160: 161: 162: 163:
164: protected function _getAggregationPerStoreView($tagId)
165: {
166: $readAdapter = $this->_getReadAdapter();
167: $selectLocal = $readAdapter->select()
168: ->from(
169: array('main' => $this->getTable('tag/relation')),
170: array(
171: 'customers' => 'COUNT(DISTINCT main.customer_id)',
172: 'products' => 'COUNT(DISTINCT main.product_id)',
173: 'store_id',
174: 'uses' => 'COUNT(main.tag_relation_id)'
175: )
176: )
177: ->join(array('store' => $this->getTable('core/store')),
178: 'store.store_id = main.store_id AND store.store_id > 0',
179: array()
180: )
181: ->join(array('product_website' => $this->getTable('catalog/product_website')),
182: 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
183: array()
184: )
185: ->where('main.tag_id = :tag_id')
186: ->where('main.active = 1')
187: ->group('main.store_id');
188:
189: $selectLocalResult = $readAdapter->fetchAll($selectLocal, array('tag_id' => $tagId));
190:
191: $selectHistorical = $readAdapter->select()
192: ->from(
193: array('main' => $this->getTable('tag/relation')),
194: array('historical_uses' => 'COUNT(main.tag_relation_id)',
195: 'store_id')
196: )
197: ->join(array('store' => $this->getTable('core/store')),
198: 'store.store_id = main.store_id AND store.store_id > 0',
199: array()
200: )
201: ->join(array('product_website' => $this->getTable('catalog/product_website')),
202: 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
203: array()
204: )
205: ->group('main.store_id')
206: ->where('main.tag_id = :tag_id')
207: ->where('main.active = 1');
208:
209: $selectHistoricalResult = $readAdapter->fetchAll($selectHistorical, array('tag_id' => $tagId));
210:
211: foreach ($selectHistoricalResult as $historical) {
212: foreach ($selectLocalResult as $key => $local) {
213: if ($local['store_id'] == $historical['store_id']) {
214: $selectLocalResult[$key]['historical_uses'] = $historical['historical_uses'];
215: break;
216: }
217: }
218: }
219:
220: return $selectLocalResult;
221: }
222:
223: 224: 225: 226: 227: 228: 229: 230:
231: protected function _getGlobalAggregation($tagId)
232: {
233: $readAdapter = $this->_getReadAdapter();
234:
235: $selectGlobal = $readAdapter->select()
236: ->from(
237: array('main' => $this->getTable('tag/relation')),
238: array(
239: 'customers' => 'COUNT(DISTINCT main.customer_id)',
240: 'products' => 'COUNT(DISTINCT main.product_id)',
241: 'store_id' => new Zend_Db_Expr(0),
242: 'uses' => 'COUNT(main.tag_relation_id)'
243: )
244: )
245: ->join(array('store' => $this->getTable('core/store')),
246: 'store.store_id=main.store_id AND store.store_id>0',
247: array()
248: )
249: ->join(array('product_website' => $this->getTable('catalog/product_website')),
250: 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
251: array()
252: )
253: ->where('main.tag_id = :tag_id')
254: ->where('main.active = 1');
255: $result = $readAdapter->fetchRow($selectGlobal, array('tag_id' => $tagId));
256: if (!$result) {
257: return array();
258: }
259:
260:
261: $selectHistoricalGlobal = $readAdapter->select()
262: ->from(
263: array('main' => $this->getTable('tag/relation')),
264: array('historical_uses' => 'COUNT(main.tag_relation_id)')
265: )
266: ->join(array('store' => $this->getTable('core/store')),
267: 'store.store_id = main.store_id AND store.store_id > 0',
268: array()
269: )
270: ->join(array('product_website' => $this->getTable('catalog/product_website')),
271: 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
272: array()
273: )
274: ->where('main.tag_id = :tag_id')
275: ->where('main.active = 1');
276: $result['historical_uses'] = (int) $readAdapter->fetchOne($selectHistoricalGlobal, array('tag_id' => $tagId));
277:
278: return $result;
279: }
280:
281: 282: 283: 284: 285: 286: 287: 288: 289:
290: public function aggregate($object)
291: {
292: $tagId = (int)$object->getId();
293: $storeId = (int)$object->getStore();
294:
295:
296: $finalSummary = $this->_getExistingBasePopularity($tagId);
297: if ($object->hasBasePopularity() && $storeId) {
298: $finalSummary[$storeId]['store_id'] = $storeId;
299: $finalSummary[$storeId]['base_popularity'] = $object->getBasePopularity();
300: }
301:
302:
303: $summaries = $this->_getAggregationPerStoreView($tagId);
304: $summariesGlobal = $this->_getGlobalAggregation($tagId);
305: if ($summariesGlobal) {
306: $summaries[] = $summariesGlobal;
307: }
308:
309:
310: foreach ($summaries as $row) {
311: $storeId = (int)$row['store_id'];
312: foreach ($row as $key => $value) {
313: $finalSummary[$storeId][$key] = $value;
314: }
315: }
316:
317:
318: foreach ($finalSummary as $key => $row) {
319: $finalSummary[$key]['tag_id'] = $tagId;
320: foreach (array('base_popularity', 'popularity', 'historical_uses', 'uses', 'products', 'customers') as $k) {
321: if (!isset($row[$k])) {
322: $finalSummary[$key][$k] = 0;
323: }
324: }
325: $finalSummary[$key]['popularity'] = $finalSummary[$key]['historical_uses'];
326: }
327:
328:
329: $write = $this->_getWriteAdapter();
330: $write->delete(
331: $this->getTable('tag/summary'), array('tag_id = ?' => $tagId)
332: );
333: $write->insertMultiple($this->getTable('tag/summary'), $finalSummary);
334:
335: return $object;
336: }
337:
338: 339: 340: 341: 342: 343:
344: public function decrementProducts(array $tagsId)
345: {
346: $writeAdapter = $this->_getWriteAdapter();
347: if (empty($tagsId)) {
348: return 0;
349: }
350:
351: return $writeAdapter->update(
352: $this->getTable('tag/summary'),
353: array('products' => new Zend_Db_Expr('products - 1')),
354: array('tag_id IN (?)' => $tagsId)
355: );
356: }
357:
358: 359: 360: 361: 362: 363: 364: 365:
366: public function addSummary($object)
367: {
368: $read = $this->_getReadAdapter();
369: $select = $read->select()
370: ->from(array('relation' => $this->getTable('tag/relation')), array())
371: ->joinLeft(
372: array('summary' => $this->getTable('tag/summary')),
373: 'relation.tag_id = summary.tag_id AND relation.store_id = summary.store_id',
374: array(
375: 'customers',
376: 'products',
377: 'popularity'
378: )
379: )
380: ->where('relation.tag_id = :tag_id')
381: ->where('relation.store_id = :store_id')
382: ->limit(1);
383: $bind = array(
384: 'tag_id' => (int)$object->getId(),
385: 'store_id' => (int)$object->getStoreId()
386: );
387: $row = $read->fetchRow($select, $bind);
388: if ($row) {
389: $object->addData($row);
390: }
391: return $object;
392: }
393:
394: 395: 396: 397: 398: 399: 400: 401: 402:
403: protected function _getLoadSelect($field, $value, $object)
404: {
405: $select = parent::_getLoadSelect($field, $value, $object);
406: if ($object->getAddBasePopularity() && $object->hasStoreId()) {
407: $select->joinLeft(
408: array('properties' => $this->getTable('tag/properties')),
409: "properties.tag_id = {$this->getMainTable()}.tag_id AND properties.store_id = {$object->getStoreId()}",
410: 'base_popularity'
411: );
412: }
413: return $select;
414: }
415:
416: 417: 418: 419: 420: 421:
422: protected function _afterLoad(Mage_Core_Model_Abstract $object)
423: {
424: $read = $this->_getReadAdapter();
425: $select = $read->select()
426: ->from($this->getTable('tag/summary'), array('store_id'))
427: ->where('tag_id = :tag_id');
428: $storeIds = $read->fetchCol($select, array('tag_id' => $object->getId()));
429:
430: $object->setVisibleInStoreIds($storeIds);
431:
432: return $this;
433: }
434: }
435: