Collection.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Review\Model\ResourceModel\Rating;
  7. /**
  8. * Rating collection resource model
  9. *
  10. * @api
  11. *
  12. * @author Magento Core Team <core@magentocommerce.com>
  13. * @since 100.0.2
  14. */
  15. class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  16. {
  17. /**
  18. * @var \Magento\Store\Model\StoreManagerInterface
  19. */
  20. protected $_storeManager;
  21. /**
  22. * @var \Magento\Review\Model\ResourceModel\Rating\Option\CollectionFactory
  23. */
  24. protected $_ratingCollectionF;
  25. /**
  26. * Add store data flag
  27. * @var bool
  28. */
  29. protected $_addStoreDataFlag = false;
  30. /**
  31. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
  32. * @param \Psr\Log\LoggerInterface $logger
  33. * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
  34. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  35. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  36. * @param \Magento\Review\Model\ResourceModel\Rating\Option\CollectionFactory $ratingCollectionF
  37. * @param mixed $connection
  38. * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
  39. */
  40. public function __construct(
  41. \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
  42. \Psr\Log\LoggerInterface $logger,
  43. \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
  44. \Magento\Framework\Event\ManagerInterface $eventManager,
  45. \Magento\Store\Model\StoreManagerInterface $storeManager,
  46. \Magento\Review\Model\ResourceModel\Rating\Option\CollectionFactory $ratingCollectionF,
  47. \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
  48. \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
  49. ) {
  50. $this->_storeManager = $storeManager;
  51. $this->_ratingCollectionF = $ratingCollectionF;
  52. parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
  53. }
  54. /**
  55. * @var bool
  56. */
  57. protected $_isStoreJoined = false;
  58. /**
  59. * Resource initialization
  60. *
  61. * @return void
  62. */
  63. protected function _construct()
  64. {
  65. $this->_init(\Magento\Review\Model\Rating::class, \Magento\Review\Model\ResourceModel\Rating::class);
  66. }
  67. /**
  68. * Add entity filter
  69. *
  70. * @param int|string $entity
  71. * @return $this
  72. */
  73. public function addEntityFilter($entity)
  74. {
  75. $connection = $this->getConnection();
  76. $this->getSelect()->join(
  77. $this->getTable('rating_entity'),
  78. 'main_table.entity_id=' . $this->getTable('rating_entity') . '.entity_id',
  79. ['entity_code']
  80. );
  81. if (is_numeric($entity)) {
  82. $this->addFilter(
  83. 'entity',
  84. $connection->quoteInto($this->getTable('rating_entity') . '.entity_id=?', $entity),
  85. 'string'
  86. );
  87. } elseif (is_string($entity)) {
  88. $this->addFilter(
  89. 'entity',
  90. $connection->quoteInto($this->getTable('rating_entity') . '.entity_code=?', $entity),
  91. 'string'
  92. );
  93. }
  94. return $this;
  95. }
  96. /**
  97. * Set order by position field
  98. *
  99. * @param string $dir
  100. * @return $this
  101. */
  102. public function setPositionOrder($dir = 'ASC')
  103. {
  104. $this->setOrder('main_table.position', $dir);
  105. return $this;
  106. }
  107. /**
  108. * Set store filter
  109. *
  110. * @param int $storeId
  111. * @return $this
  112. */
  113. public function setStoreFilter($storeId)
  114. {
  115. if ($this->_storeManager->isSingleStoreMode()) {
  116. return $this;
  117. }
  118. $connection = $this->getConnection();
  119. if (!is_array($storeId)) {
  120. $storeId = [$storeId === null ? -1 : $storeId];
  121. }
  122. if (empty($storeId)) {
  123. return $this;
  124. }
  125. if (!$this->_isStoreJoined) {
  126. $this->getSelect()->distinct(
  127. true
  128. )->join(
  129. ['store' => $this->getTable('rating_store')],
  130. 'main_table.rating_id = store.rating_id',
  131. []
  132. );
  133. $this->_isStoreJoined = true;
  134. }
  135. $inCondition = $connection->prepareSqlCondition('store.store_id', ['in' => $storeId]);
  136. $this->getSelect()->where($inCondition);
  137. $this->setPositionOrder();
  138. return $this;
  139. }
  140. /**
  141. * Add options to ratings in collection
  142. *
  143. * @return $this
  144. */
  145. public function addOptionToItems()
  146. {
  147. $arrRatingId = $this->getColumnValues('rating_id');
  148. if (!empty($arrRatingId)) {
  149. /** @var \Magento\Review\Model\ResourceModel\Rating\Option\Collection $collection */
  150. $collection = $this->_ratingCollectionF->create()->addRatingFilter(
  151. $arrRatingId
  152. )->setPositionOrder()->load();
  153. foreach ($this as $rating) {
  154. $rating->setOptions($collection->getItemsByColumnValue('rating_id', $rating->getId()));
  155. }
  156. }
  157. return $this;
  158. }
  159. /**
  160. * Add entity summary to item
  161. *
  162. * @param int $entityPkValue
  163. * @param int $storeId
  164. * @return $this
  165. */
  166. public function addEntitySummaryToItem($entityPkValue, $storeId)
  167. {
  168. $arrRatingId = $this->getColumnValues('rating_id');
  169. if (count($arrRatingId) == 0) {
  170. return $this;
  171. }
  172. $connection = $this->getConnection();
  173. $inCond = $connection->prepareSqlCondition('rating_option_vote.rating_id', ['in' => $arrRatingId]);
  174. $sumCond = new \Zend_Db_Expr("SUM(rating_option_vote.{$connection->quoteIdentifier('percent')})");
  175. $countCond = new \Zend_Db_Expr('COUNT(*)');
  176. $select = $connection->select()->from(
  177. ['rating_option_vote' => $this->getTable('rating_option_vote')],
  178. ['rating_id' => 'rating_option_vote.rating_id', 'sum' => $sumCond, 'count' => $countCond]
  179. )->join(
  180. ['review_store' => $this->getTable('review_store')],
  181. 'rating_option_vote.review_id=review_store.review_id AND review_store.store_id = :store_id',
  182. []
  183. );
  184. if (!$this->_storeManager->isSingleStoreMode()) {
  185. $select->join(
  186. ['rst' => $this->getTable('rating_store')],
  187. 'rst.rating_id = rating_option_vote.rating_id AND rst.store_id = :rst_store_id',
  188. []
  189. );
  190. }
  191. $select->join(
  192. ['review' => $this->getTable('review')],
  193. 'review_store.review_id=review.review_id AND review.status_id=1',
  194. []
  195. )->where(
  196. $inCond
  197. )->where(
  198. 'rating_option_vote.entity_pk_value=:pk_value'
  199. )->group(
  200. 'rating_option_vote.rating_id'
  201. );
  202. $bind = [':store_id' => (int)$storeId, ':pk_value' => $entityPkValue];
  203. if (!$this->_storeManager->isSingleStoreMode()) {
  204. $bind[':rst_store_id'] = (int)$storeId;
  205. }
  206. $data = $this->getConnection()->fetchAll($select, $bind);
  207. foreach ($data as $item) {
  208. $rating = $this->getItemById($item['rating_id']);
  209. if ($rating && $item['count'] > 0) {
  210. $rating->setSummary($item['sum'] / $item['count']);
  211. }
  212. }
  213. return $this;
  214. }
  215. /**
  216. * Add rating store name
  217. *
  218. * @param int $storeId
  219. * @return $this
  220. */
  221. public function addRatingPerStoreName($storeId)
  222. {
  223. $connection = $this->getConnection();
  224. $ratingCodeCond = $connection->getIfNullSql('title.value', 'main_table.rating_code');
  225. $this->getSelect()->joinLeft(
  226. ['title' => $this->getTable('rating_title')],
  227. $connection->quoteInto('main_table.rating_id=title.rating_id AND title.store_id = ?', (int)$storeId),
  228. ['rating_code' => $ratingCodeCond]
  229. );
  230. return $this;
  231. }
  232. /**
  233. * Add stores data to collection
  234. *
  235. * @return $this
  236. */
  237. public function addStoreData()
  238. {
  239. if (!$this->_storeManager->isSingleStoreMode()) {
  240. if (!$this->_isCollectionLoaded) {
  241. $this->_addStoreDataFlag = true;
  242. } elseif (!$this->_addStoreDataFlag) {
  243. $this->_addStoreData();
  244. }
  245. }
  246. return $this;
  247. }
  248. /**
  249. * Load data
  250. *
  251. * @param bool $printQuery
  252. * @param bool $logQuery
  253. * @return $this
  254. */
  255. public function load($printQuery = false, $logQuery = false)
  256. {
  257. if ($this->isLoaded()) {
  258. return $this;
  259. }
  260. $this->_eventManager->dispatch('rating_rating_collection_load_before', ['collection' => $this]);
  261. parent::load($printQuery, $logQuery);
  262. if ($this->_addStoreDataFlag) {
  263. $this->_addStoreData();
  264. }
  265. return $this;
  266. }
  267. /**
  268. * Add store data
  269. *
  270. * @return $this
  271. */
  272. protected function _addStoreData()
  273. {
  274. $ratingIds = [];
  275. foreach ($this as $item) {
  276. $ratingIds[] = $item->getId();
  277. $item->setStores([]);
  278. }
  279. if (!$ratingIds) {
  280. return $this;
  281. }
  282. $connection = $this->getConnection();
  283. $inCondition = $connection->prepareSqlCondition('rating_id', ['in' => $ratingIds]);
  284. $this->_select = $connection->select()->from($this->getTable('rating_store'))->where($inCondition);
  285. $data = $connection->fetchAll($this->_select);
  286. if (is_array($data) && count($data) > 0) {
  287. foreach ($data as $row) {
  288. $item = $this->getItemById($row['rating_id']);
  289. $item->setStores(array_merge($item->getStores(), [$row['store_id']]));
  290. }
  291. }
  292. return $this;
  293. }
  294. /**
  295. * Set Active Filter
  296. *
  297. * @param bool $isActive
  298. * @return $this
  299. */
  300. public function setActiveFilter($isActive = true)
  301. {
  302. $this->getSelect()->where('main_table.is_active=?', $isActive);
  303. return $this;
  304. }
  305. }