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_Review_Model_Resource_Review extends Mage_Core_Model_Resource_Db_Abstract
36: {
37: 38: 39: 40: 41:
42: protected $_reviewTable;
43:
44: 45: 46: 47: 48:
49: protected $_reviewDetailTable;
50:
51: 52: 53: 54: 55:
56: protected $_reviewStatusTable;
57:
58: 59: 60: 61: 62:
63: protected $_reviewEntityTable;
64:
65: 66: 67: 68: 69:
70: protected $_reviewStoreTable;
71:
72: 73: 74: 75: 76:
77: protected $_aggregateTable;
78:
79: 80: 81: 82: 83:
84: private $_deleteCache = array();
85:
86: 87: 88: 89:
90: protected function _construct()
91: {
92: $this->_init('review/review', 'review_id');
93: $this->_reviewTable = $this->getTable('review/review');
94: $this->_reviewDetailTable = $this->getTable('review/review_detail');
95: $this->_reviewStatusTable = $this->getTable('review/review_status');
96: $this->_reviewEntityTable = $this->getTable('review/review_entity');
97: $this->_reviewStoreTable = $this->getTable('review/review_store');
98: $this->_aggregateTable = $this->getTable('review/review_aggregate');
99: }
100:
101: 102: 103: 104: 105: 106: 107: 108:
109: protected function _getLoadSelect($field, $value, $object)
110: {
111: $select = parent::_getLoadSelect($field, $value, $object);
112: $select->join(
113: $this->_reviewDetailTable,
114: $this->getMainTable().".review_id = {$this->_reviewDetailTable}.review_id"
115: );
116: return $select;
117: }
118:
119: 120: 121: 122: 123: 124:
125: protected function _beforeSave(Mage_Core_Model_Abstract $object)
126: {
127: if (!$object->getId()) {
128: $object->setCreatedAt(Mage::getSingleton('core/date')->gmtDate());
129: }
130: if ($object->hasData('stores') && is_array($object->getStores())) {
131: $stores = $object->getStores();
132: $stores[] = 0;
133: $object->setStores($stores);
134: } elseif ($object->hasData('stores')) {
135: $object->setStores(array($object->getStores(), 0));
136: }
137: return $this;
138: }
139:
140: 141: 142: 143: 144: 145:
146: protected function _afterSave(Mage_Core_Model_Abstract $object)
147: {
148: $adapter = $this->_getWriteAdapter();
149: 150: 151:
152: $detail = array(
153: 'title' => $object->getTitle(),
154: 'detail' => $object->getDetail(),
155: 'nickname' => $object->getNickname(),
156: );
157: $select = $adapter->select()
158: ->from($this->_reviewDetailTable, 'detail_id')
159: ->where('review_id = :review_id');
160: $detailId = $adapter->fetchOne($select, array(':review_id' => $object->getId()));
161:
162: if ($detailId) {
163: $condition = array("detail_id = ?" => $detailId);
164: $adapter->update($this->_reviewDetailTable, $detail, $condition);
165: } else {
166: $detail['store_id'] = $object->getStoreId();
167: $detail['customer_id']= $object->getCustomerId();
168: $detail['review_id'] = $object->getId();
169: $adapter->insert($this->_reviewDetailTable, $detail);
170: }
171:
172:
173: 174: 175:
176: $stores = $object->getStores();
177: if (!empty($stores)) {
178: $condition = array('review_id = ?' => $object->getId());
179: $adapter->delete($this->_reviewStoreTable, $condition);
180:
181: $insertedStoreIds = array();
182: foreach ($stores as $storeId) {
183: if (in_array($storeId, $insertedStoreIds)) {
184: continue;
185: }
186:
187: $insertedStoreIds[] = $storeId;
188: $storeInsert = array(
189: 'store_id' => $storeId,
190: 'review_id'=> $object->getId()
191: );
192: $adapter->insert($this->_reviewStoreTable, $storeInsert);
193: }
194: }
195:
196:
197: $this->_aggregateRatings(
198: $this->_loadVotedRatingIds($object->getId()),
199: $object->getEntityPkValue()
200: );
201:
202: return $this;
203: }
204:
205: 206: 207: 208: 209: 210:
211: protected function _afterLoad(Mage_Core_Model_Abstract $object)
212: {
213: $adapter = $this->_getReadAdapter();
214: $select = $adapter->select()
215: ->from($this->_reviewStoreTable, array('store_id'))
216: ->where('review_id = :review_id');
217: $stores = $adapter->fetchCol($select, array(':review_id' => $object->getId()));
218: if (empty($stores) && Mage::app()->isSingleStoreMode()) {
219: $object->setStores(array(Mage::app()->getStore(true)->getId()));
220: } else {
221: $object->setStores($stores);
222: }
223: return $this;
224: }
225:
226: 227: 228: 229: 230: 231:
232: protected function _beforeDelete(Mage_Core_Model_Abstract $object)
233: {
234:
235: $this->_deleteCache = array(
236: 'ratingIds' => $this->_loadVotedRatingIds($object->getId()),
237: 'entityPkValue' => $object->getEntityPkValue()
238: );
239: return $this;
240: }
241:
242: 243: 244: 245: 246: 247:
248: public function afterDeleteCommit(Mage_Core_Model_Abstract $object)
249: {
250: $this->aggregate($object);
251:
252:
253: $this->_aggregateRatings(
254: $this->_deleteCache['ratingIds'],
255: $this->_deleteCache['entityPkValue']
256: );
257: $this->_deleteCache = array();
258:
259: return $this;
260: }
261:
262: 263: 264: 265: 266: 267: 268: 269:
270: public function getTotalReviews($entityPkValue, $approvedOnly = false, $storeId = 0)
271: {
272: $adapter = $this->_getReadAdapter();
273: $select = $adapter->select()
274: ->from($this->_reviewTable,
275: array(
276: 'review_count' => new Zend_Db_Expr('COUNT(*)')
277: ))
278: ->where("{$this->_reviewTable}.entity_pk_value = :pk_value");
279: $bind = array(':pk_value' => $entityPkValue);
280: if ($storeId > 0) {
281: $select->join(array('store'=>$this->_reviewStoreTable),
282: $this->_reviewTable.'.review_id=store.review_id AND store.store_id = :store_id',
283: array());
284: $bind[':store_id'] = (int)$storeId;
285: }
286: if ($approvedOnly) {
287: $select->where("{$this->_reviewTable}.status_id = :status_id");
288: $bind[':status_id'] = 1;
289: }
290: return $adapter->fetchOne($select, $bind);
291: }
292:
293: 294: 295: 296: 297:
298: public function aggregate($object)
299: {
300: $readAdapter = $this->_getReadAdapter();
301: $writeAdapter = $this->_getWriteAdapter();
302: if (!$object->getEntityPkValue() && $object->getId()) {
303: $object->load($object->getReviewId());
304: }
305:
306: $ratingModel = Mage::getModel('rating/rating');
307: $ratingSummaries= $ratingModel->getEntitySummary($object->getEntityPkValue(), false);
308:
309: foreach ($ratingSummaries as $ratingSummaryObject) {
310: if ($ratingSummaryObject->getCount()) {
311: $ratingSummary = round($ratingSummaryObject->getSum() / $ratingSummaryObject->getCount());
312: } else {
313: $ratingSummary = $ratingSummaryObject->getSum();
314: }
315:
316: $reviewsCount = $this->getTotalReviews(
317: $object->getEntityPkValue(),
318: true,
319: $ratingSummaryObject->getStoreId()
320: );
321: $select = $readAdapter->select()
322: ->from($this->_aggregateTable)
323: ->where('entity_pk_value = :pk_value')
324: ->where('entity_type = :entity_type')
325: ->where('store_id = :store_id');
326: $bind = array(
327: ':pk_value' => $object->getEntityPkValue(),
328: ':entity_type' => $object->getEntityId(),
329: ':store_id' =>$ratingSummaryObject->getStoreId()
330: );
331: $oldData = $readAdapter->fetchRow($select, $bind);
332:
333: $data = new Varien_Object();
334:
335: $data->setReviewsCount($reviewsCount)
336: ->setEntityPkValue($object->getEntityPkValue())
337: ->setEntityType($object->getEntityId())
338: ->setRatingSummary(($ratingSummary > 0) ? $ratingSummary : 0)
339: ->setStoreId($ratingSummaryObject->getStoreId());
340:
341: $writeAdapter->beginTransaction();
342: try {
343: if ($oldData['primary_id'] > 0) {
344: $condition = array("{$this->_aggregateTable}.primary_id = ?" => $oldData['primary_id']);
345: $writeAdapter->update($this->_aggregateTable, $data->getData(), $condition);
346: } else {
347: $writeAdapter->insert($this->_aggregateTable, $data->getData());
348: }
349: $writeAdapter->commit();
350: } catch (Exception $e) {
351: $writeAdapter->rollBack();
352: }
353: }
354: }
355:
356: 357: 358: 359: 360: 361:
362: protected function _loadVotedRatingIds($reviewId)
363: {
364: $adapter = $this->_getReadAdapter();
365: if (empty($reviewId)) {
366: return array();
367: }
368: $select = $adapter->select()
369: ->from(array('v' => $this->getTable('rating/rating_option_vote')), 'r.rating_id')
370: ->joinInner(array('r' => $this->getTable('rating/rating')), 'v.rating_id=r.rating_id')
371: ->where('v.review_id = :revire_id');
372: return $adapter->fetchCol($select, array(':revire_id' => $reviewId));
373: }
374:
375: 376: 377: 378: 379: 380: 381: 382:
383: protected function _aggregateRatings($ratingIds, $entityPkValue)
384: {
385: if ($ratingIds && !is_array($ratingIds)) {
386: $ratingIds = array((int)$ratingIds);
387: }
388: if ($ratingIds && $entityPkValue
389: && ($resource = Mage::getResourceSingleton('rating/rating_option'))
390: ) {
391: foreach ($ratingIds as $ratingId) {
392: $resource->aggregateEntityByRatingId(
393: $ratingId, $entityPkValue
394: );
395: }
396: }
397: return $this;
398: }
399:
400: 401: 402: 403: 404: 405:
406: public function reAggregateReview($reviewId, $entityPkValue)
407: {
408: $this->_aggregateRatings($this->_loadVotedRatingIds($reviewId), $entityPkValue);
409: }
410:
411: 412: 413: 414: 415: 416:
417: public function getEntityIdByCode($entityCode)
418: {
419: $adapter = $this->_getReadAdapter();
420: $select = $adapter->select()
421: ->from($this->_reviewEntityTable, array('entity_id'))
422: ->where('entity_code = :entity_code');
423: return $adapter->fetchOne($select, array(':entity_code' => $entityCode));
424: }
425:
426: 427: 428: 429: 430: 431: 432:
433: public function deleteReviewsByProductId($productId)
434: {
435: $this->_getWriteAdapter()->delete($this->_reviewTable, array(
436: 'entity_pk_value=?' => $productId,
437: 'entity_id=?' => $this->getEntityIdByCode(Mage_Review_Model_Review::ENTITY_PRODUCT_CODE)
438: ));
439: $this->_getWriteAdapter()->delete($this->getTable('review/review_aggregate'), array(
440: 'entity_pk_value=?' => $productId,
441: 'entity_type=?' => $this->getEntityIdByCode(Mage_Review_Model_Review::ENTITY_PRODUCT_CODE)
442: ));
443: return $this;
444: }
445: }
446: