Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Option.php
Go to the documentation of this file.
1 <?php
7 
15 {
21  protected $_reviewTable;
22 
29 
35  protected $_ratingVoteTable;
36 
42  protected $_aggregateTable;
43 
49  protected $_reviewStoreTable;
50 
56  protected $_ratingStoreTable;
57 
63  protected $_optionData;
64 
70  protected $_optionId;
71 
75  protected $_customerSession;
76 
81 
89  public function __construct(
90  \Magento\Framework\Model\ResourceModel\Db\Context $context,
91  \Magento\Customer\Model\Session $customerSession,
92  \Magento\Review\Model\Rating\Option\VoteFactory $ratingOptionVoteF,
93  \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
94  $connectionName = null
95  ) {
96  $this->_customerSession = $customerSession;
97  $this->_ratingOptionVoteF = $ratingOptionVoteF;
98  $this->_remoteAddress = $remoteAddress;
99  parent::__construct($context, $connectionName);
100  }
101 
107  protected function _construct()
108  {
109  $this->_init('rating_option', 'option_id');
110 
111  $this->_reviewTable = $this->getTable('review');
112  $this->_ratingOptionTable = $this->getTable('rating_option');
113  $this->_ratingVoteTable = $this->getTable('rating_option_vote');
114  $this->_aggregateTable = $this->getTable('rating_option_vote_aggregated');
115  $this->_reviewStoreTable = $this->getTable('review_store');
116  $this->_ratingStoreTable = $this->getTable('rating_store');
117  }
118 
125  public function addVote($option)
126  {
127  $connection = $this->getConnection();
128  $optionData = $this->loadDataById($option->getId());
129  $data = [
130  'option_id' => $option->getId(),
131  'review_id' => $option->getReviewId(),
132  'percent' => $optionData['value'] / 5 * 100,
133  'value' => $optionData['value'],
134  ];
135 
136  if (!$option->getDoUpdate()) {
137  $data['remote_ip'] = $this->_remoteAddress->getRemoteAddress();
138  $data['remote_ip_long'] = $this->_remoteAddress->getRemoteAddress(true);
139  $data['customer_id'] = $this->_customerSession->getCustomerId();
140  $data['entity_pk_value'] = $option->getEntityPkValue();
141  $data['rating_id'] = $option->getRatingId();
142  }
143 
144  $connection->beginTransaction();
145  try {
146  if ($option->getDoUpdate()) {
147  $condition = ['vote_id = ?' => $option->getVoteId(), 'review_id = ?' => $option->getReviewId()];
148  $connection->update($this->_ratingVoteTable, $data, $condition);
149  $this->aggregate($option);
150  } else {
151  $connection->insert($this->_ratingVoteTable, $data);
152  $option->setVoteId($connection->lastInsertId($this->_ratingVoteTable));
153  $this->aggregate($option);
154  }
155  $connection->commit();
156  } catch (\Exception $e) {
157  $connection->rollBack();
158  throw new \Exception($e->getMessage());
159  }
160  return $this;
161  }
162 
169  public function aggregate($option)
170  {
171  $vote = $this->_ratingOptionVoteF->create()->load($option->getVoteId());
172  $this->aggregateEntityByRatingId($vote->getRatingId(), $vote->getEntityPkValue());
173  }
174 
182  public function aggregateEntityByRatingId($ratingId, $entityPkValue)
183  {
184  $connection = $this->getConnection();
185 
186  $select = $connection->select()->from(
187  $this->_aggregateTable,
188  ['store_id', 'primary_id']
189  )->where(
190  'rating_id = :rating_id'
191  )->where(
192  'entity_pk_value = :pk_value'
193  );
194  $bind = [':rating_id' => $ratingId, ':pk_value' => $entityPkValue];
195  $oldData = $connection->fetchPairs($select, $bind);
196 
197  $appVoteCountCond = $connection->getCheckSql('review.status_id=1', 'vote.vote_id', 'NULL');
198  $appVoteValueSumCond = $connection->getCheckSql('review.status_id=1', 'vote.value', '0');
199 
200  $select = $connection->select()->from(
201  ['vote' => $this->_ratingVoteTable],
202  [
203  'vote_count' => new \Zend_Db_Expr('COUNT(vote.vote_id)'),
204  'vote_value_sum' => new \Zend_Db_Expr('SUM(vote.value)'),
205  'app_vote_count' => new \Zend_Db_Expr("COUNT({$appVoteCountCond})"),
206  'app_vote_value_sum' => new \Zend_Db_Expr("SUM({$appVoteValueSumCond})")
207  ]
208  )->join(
209  ['review' => $this->_reviewTable],
210  'vote.review_id=review.review_id',
211  []
212  )->joinLeft(
213  ['store' => $this->_reviewStoreTable],
214  'vote.review_id=store.review_id',
215  'store_id'
216  )->join(
217  ['rstore' => $this->_ratingStoreTable],
218  'vote.rating_id=rstore.rating_id AND rstore.store_id=store.store_id',
219  []
220  )->where(
221  'vote.rating_id = :rating_id'
222  )->where(
223  'vote.entity_pk_value = :pk_value'
224  )->group(
225  ['vote.rating_id', 'vote.entity_pk_value', 'store.store_id']
226  );
227 
228  $perStoreInfo = $connection->fetchAll($select, $bind);
229 
230  $usedStores = [];
231  foreach ($perStoreInfo as $row) {
232  $saveData = [
233  'rating_id' => $ratingId,
234  'entity_pk_value' => $entityPkValue,
235  'vote_count' => $row['vote_count'],
236  'vote_value_sum' => $row['vote_value_sum'],
237  'percent' => $row['vote_value_sum'] / $row['vote_count'] / 5 * 100,
238  'percent_approved' => $row['app_vote_count'] ? $row['app_vote_value_sum'] /
239  $row['app_vote_count'] /
240  5 *
241  100 : 0,
242  'store_id' => $row['store_id'],
243  ];
244 
245  if (isset($oldData[$row['store_id']])) {
246  $condition = ['primary_id = ?' => $oldData[$row['store_id']]];
247  $connection->update($this->_aggregateTable, $saveData, $condition);
248  } else {
249  $connection->insert($this->_aggregateTable, $saveData);
250  }
251 
252  $usedStores[] = $row['store_id'];
253  }
254 
255  $toDelete = array_diff(array_keys($oldData), $usedStores);
256 
257  foreach ($toDelete as $storeId) {
258  $condition = ['primary_id = ?' => $oldData[$storeId]];
259  $connection->delete($this->_aggregateTable, $condition);
260  }
261  }
262 
270  public function loadDataById($optionId)
271  {
272  if (!$this->_optionData || $this->_optionId != $optionId) {
273  $connection = $this->getConnection();
274  $select = $connection->select();
275  $select->from($this->_ratingOptionTable)->where('option_id = :option_id');
276 
277  $data = $connection->fetchRow($select, [':option_id' => $optionId]);
278 
279  $this->_optionData = $data;
280  $this->_optionId = $optionId;
281  return $data;
282  }
283 
284  return $this->_optionData;
285  }
286 }
$optionData
aggregateEntityByRatingId($ratingId, $entityPkValue)
Definition: Option.php:182
__construct(\Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Customer\Model\Session $customerSession, \Magento\Review\Model\Rating\Option\VoteFactory $ratingOptionVoteF, \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress, $connectionName=null)
Definition: Option.php:89
$connection
Definition: bulk.php:13