PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Tag/Model/Resource/Product/Collection.php

https://github.com/cosmocommerce/magento-mirror
PHP | 490 lines | 255 code | 57 blank | 178 comment | 18 complexity | 3695ec6f3fb1103687713c858bcc219c MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Tag
  23. * @copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Tagged Product(s) Collection
  28. *
  29. * @category Mage
  30. * @package Mage_Tag
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Tag_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
  34. {
  35. /**
  36. * Customer Id Filter
  37. *
  38. * @var int
  39. */
  40. protected $_customerFilterId;
  41. /**
  42. * Tag Id Filter
  43. *
  44. * @var int
  45. */
  46. protected $_tagIdFilter;
  47. /**
  48. * Join Flags
  49. *
  50. * @var array
  51. */
  52. protected $_joinFlags = array();
  53. /**
  54. * Initialize collection select
  55. *
  56. * @return Mage_Tag_Model_Resource_Product_Collection
  57. */
  58. protected function _initSelect()
  59. {
  60. parent::_initSelect();
  61. $this->_joinFields();
  62. $this->getSelect()->group('e.entity_id');
  63. /*
  64. * Allow analytic function usage
  65. */
  66. $this->_useAnalyticFunction = true;
  67. return $this;
  68. }
  69. /**
  70. * Set flag about joined table.
  71. * setFlag method must be used in future.
  72. *
  73. * @deprecated after 1.3.2.3
  74. *
  75. * @param string $table
  76. * @return Mage_Tag_Model_Resource_Product_Collection
  77. */
  78. public function setJoinFlag($table)
  79. {
  80. $this->setFlag($table, true);
  81. return $this;
  82. }
  83. /**
  84. * Get flag's status about joined table.
  85. * getFlag method must be used in future.
  86. *
  87. * @deprecated after 1.3.2.3
  88. *
  89. * @param string $table
  90. * @return bool
  91. */
  92. public function getJoinFlag($table)
  93. {
  94. return $this->getFlag($table);
  95. }
  96. /**
  97. * Unset value of join flag.
  98. * Set false (bool) value to flag instead in future.
  99. *
  100. * @deprecated after 1.3.2.3
  101. *
  102. * @param string $table
  103. * @return Mage_Tag_Model_Resource_Product_Collection
  104. */
  105. public function unsetJoinFlag($table = null)
  106. {
  107. $this->setFlag($table, false);
  108. return $this;
  109. }
  110. /**
  111. * Add tag visibility on stores
  112. *
  113. * @return Mage_Tag_Model_Resource_Product_Collection
  114. */
  115. public function addStoresVisibility()
  116. {
  117. $this->setFlag('add_stores_after', true);
  118. return $this;
  119. }
  120. /**
  121. * Add tag visibility on stores process
  122. *
  123. * @return Mage_Tag_Model_Resource_Product_Collection
  124. */
  125. protected function _addStoresVisibility()
  126. {
  127. $tagIds = array();
  128. foreach ($this as $item) {
  129. $tagIds[] = $item->getTagId();
  130. }
  131. $tagsStores = array();
  132. if (sizeof($tagIds) > 0) {
  133. $select = $this->getConnection()->select()
  134. ->from($this->getTable('tag/relation'), array('store_id', 'tag_id'))
  135. ->where('tag_id IN(?)', $tagIds);
  136. $tagsRaw = $this->getConnection()->fetchAll($select);
  137. foreach ($tagsRaw as $tag) {
  138. if (!isset($tagsStores[$tag['tag_id']])) {
  139. $tagsStores[$tag['tag_id']] = array();
  140. }
  141. $tagsStores[$tag['tag_id']][] = $tag['store_id'];
  142. }
  143. }
  144. foreach ($this as $item) {
  145. if (isset($tagsStores[$item->getTagId()])) {
  146. $item->setStores($tagsStores[$item->getTagId()]);
  147. } else {
  148. $item->setStores(array());
  149. }
  150. }
  151. return $this;
  152. }
  153. /**
  154. * Add group by tag
  155. *
  156. * @return Mage_Tag_Model_Resource_Product_Collection
  157. */
  158. public function addGroupByTag()
  159. {
  160. $this->getSelect()->group('relation.tag_relation_id');
  161. return $this;
  162. }
  163. /**
  164. * Add Store ID filter
  165. *
  166. * @param int|array $store
  167. * @return Mage_Tag_Model_Resource_Product_Collection
  168. */
  169. public function addStoreFilter($store = null)
  170. {
  171. if (!is_null($store)) {
  172. $this->getSelect()->where('relation.store_id IN (?)', $store);
  173. }
  174. return $this;
  175. }
  176. /**
  177. * Set Customer filter
  178. * If incoming parameter is array and has element with key 'null'
  179. * then condition with IS NULL or IS NOT NULL will be added.
  180. * Otherwise condition with IN() will be added
  181. *
  182. * @param int|array $customerId
  183. * @return Mage_Tag_Model_Resource_Product_Collection
  184. */
  185. public function addCustomerFilter($customerId)
  186. {
  187. if (is_array($customerId) && isset($customerId['null'])) {
  188. $condition = ($customerId['null']) ? 'IS NULL' : 'IS NOT NULL';
  189. $this->getSelect()->where('relation.customer_id ' . $condition);
  190. return $this;
  191. }
  192. $this->getSelect()->where('relation.customer_id IN(?)', $customerId);
  193. $this->_customerFilterId = $customerId;
  194. return $this;
  195. }
  196. /**
  197. * Set tag filter
  198. *
  199. * @param int $tagId
  200. * @return Mage_Tag_Model_Resource_Product_Collection
  201. */
  202. public function addTagFilter($tagId)
  203. {
  204. $this->getSelect()->where('relation.tag_id = ?', $tagId);
  205. $this->setFlag('distinct', true);
  206. return $this;
  207. }
  208. /**
  209. * Add tag status filter
  210. *
  211. * @param int $status
  212. * @return Mage_Tag_Model_Resource_Product_Collection
  213. */
  214. public function addStatusFilter($status)
  215. {
  216. $this->getSelect()->where('t.status = ?', $status);
  217. return $this;
  218. }
  219. /**
  220. * Set DESC order to collection
  221. *
  222. * @param string $dir
  223. * @return Mage_Tag_Model_Resource_Product_Collection
  224. */
  225. public function setDescOrder($dir = 'DESC')
  226. {
  227. $this->setOrder('relation.tag_relation_id', $dir);
  228. return $this;
  229. }
  230. /**
  231. * Add Popularity
  232. *
  233. * @param int $tagId
  234. * @param int $storeId
  235. * @return Mage_Tag_Model_Resource_Product_Collection
  236. */
  237. public function addPopularity($tagId, $storeId = null)
  238. {
  239. $tagRelationTable = $this->getTable('tag/relation');
  240. $condition = array(
  241. 'prelation.product_id=e.entity_id'
  242. );
  243. if (!is_null($storeId)) {
  244. $condition[] = $this->getConnection()->quoteInto('prelation.store_id = ?', $storeId);
  245. }
  246. $condition = join(' AND ', $condition);
  247. $innerSelect = $this->getConnection()->select()
  248. ->from(
  249. array('relation' => $tagRelationTable),
  250. array('product_id', 'store_id', 'popularity' => 'COUNT(DISTINCT relation.tag_relation_id)')
  251. )
  252. ->where('relation.tag_id = ?', $tagId)
  253. ->group(array('product_id', 'store_id'));
  254. $this->getSelect()
  255. ->joinLeft(
  256. array('prelation' => $innerSelect),
  257. $condition,
  258. array('popularity' => 'prelation.popularity')
  259. );
  260. $this->_tagIdFilter = $tagId;
  261. $this->setFlag('prelation', true);
  262. return $this;
  263. }
  264. /**
  265. * Add Popularity Filter
  266. *
  267. * @param mixed $condition
  268. * @return Mage_Tag_Model_Resource_Product_Collection
  269. */
  270. public function addPopularityFilter($condition)
  271. {
  272. $tagRelationTable = Mage::getSingleton('core/resource')
  273. ->getTableName('tag/relation');
  274. $select = $this->getConnection()->select()
  275. ->from($tagRelationTable, array('product_id', 'popularity' => 'COUNT(DISTINCT tag_relation_id)'))
  276. ->where('tag_id = :tag_id')
  277. ->group('product_id')
  278. ->having($this->_getConditionSql('popularity', $condition));
  279. $prodIds = array();
  280. foreach ($this->getConnection()->fetchAll($select, array('tag_id' => $this->_tagIdFilter)) as $item) {
  281. $prodIds[] = $item['product_id'];
  282. }
  283. if (sizeof($prodIds) > 0) {
  284. $this->getSelect()->where('e.entity_id IN(?)', $prodIds);
  285. } else {
  286. $this->getSelect()->where('e.entity_id IN(0)');
  287. }
  288. return $this;
  289. }
  290. /**
  291. * Set tag active filter to collection
  292. *
  293. * @return Mage_Tag_Model_Resource_Product_Collection
  294. */
  295. public function setActiveFilter()
  296. {
  297. $active = Mage_Tag_Model_Tag_Relation::STATUS_ACTIVE;
  298. $this->getSelect()->where('relation.active = ?', $active);
  299. if ($this->getFlag('prelation')) {
  300. $this->getSelect()->where('prelation.active = ?', $active);
  301. }
  302. return $this;
  303. }
  304. /**
  305. * Add Product Tags
  306. *
  307. * @param int $storeId
  308. * @return Mage_Tag_Model_Resource_Product_Collection
  309. */
  310. public function addProductTags($storeId = null)
  311. {
  312. foreach ($this->getItems() as $item) {
  313. $tagsCollection = Mage::getModel('tag/tag')->getResourceCollection();
  314. if (!is_null($storeId)) {
  315. $tagsCollection->addStoreFilter($storeId);
  316. }
  317. $tagsCollection->addPopularity()
  318. ->addProductFilter($item->getEntityId())
  319. ->addCustomerFilter($this->_customerFilterId)
  320. ->setActiveFilter();
  321. $tagsCollection->load();
  322. $item->setProductTags($tagsCollection);
  323. }
  324. return $this;
  325. }
  326. /**
  327. * Join fields process
  328. *
  329. * @return Mage_Tag_Model_Resource_Product_Collection
  330. */
  331. protected function _joinFields()
  332. {
  333. $tagTable = $this->getTable('tag/tag');
  334. $tagRelationTable = $this->getTable('tag/relation');
  335. $this->addAttributeToSelect('name')
  336. ->addAttributeToSelect('price')
  337. ->addAttributeToSelect('small_image');
  338. $this->getSelect()
  339. ->join(array('relation' => $tagRelationTable), 'relation.product_id = e.entity_id', array(
  340. 'product_id' => 'product_id',
  341. 'item_store_id' => 'store_id',
  342. ))
  343. ->join(array('t' => $tagTable),
  344. 't.tag_id = relation.tag_id',
  345. array(
  346. 'tag_id',
  347. 'tag_status' => 'status',
  348. 'tag_name' => 'name',
  349. 'store_id' => $this->getConnection()->getCheckSql(
  350. 't.first_store_id = 0',
  351. 'relation.store_id',
  352. 't.first_store_id'
  353. )
  354. )
  355. );
  356. return $this;
  357. }
  358. /**
  359. * After load adding data
  360. *
  361. * @return Mage_Tag_Model_Resource_Product_Collection
  362. */
  363. protected function _afterLoad()
  364. {
  365. parent::_afterLoad();
  366. if ($this->getFlag('add_stores_after')) {
  367. $this->_addStoresVisibility();
  368. }
  369. if (count($this) > 0) {
  370. Mage::dispatchEvent('tag_tag_product_collection_load_after', array(
  371. 'collection' => $this
  372. ));
  373. }
  374. return $this;
  375. }
  376. /**
  377. * Render SQL for retrieve product count
  378. *
  379. * @return string
  380. */
  381. public function getSelectCountSql()
  382. {
  383. $countSelect = clone $this->getSelect();
  384. $countSelect->reset(Zend_Db_Select::COLUMNS);
  385. $countSelect->reset(Zend_Db_Select::ORDER);
  386. $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
  387. $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
  388. $countSelect->reset(Zend_Db_Select::GROUP);
  389. if ($this->getFlag('group_tag')) {
  390. $field = 'relation.tag_id';
  391. } else {
  392. $field = 'e.entity_id';
  393. }
  394. $expr = new Zend_Db_Expr('COUNT('
  395. . ($this->getFlag('distinct') ? 'DISTINCT ' : '')
  396. . $field . ')');
  397. $countSelect->columns($expr);
  398. return $countSelect;
  399. }
  400. /**
  401. * Treat "order by" items as attributes to sort
  402. *
  403. * @return Mage_Tag_Model_Resource_Product_Collection
  404. */
  405. protected function _renderOrders()
  406. {
  407. if (!$this->_isOrdersRendered) {
  408. parent::_renderOrders();
  409. $orders = $this->getSelect()
  410. ->getPart(Zend_Db_Select::ORDER);
  411. $appliedOrders = array();
  412. foreach ($orders as $order) {
  413. $appliedOrders[$order[0]] = true;
  414. }
  415. foreach ($this->_orders as $field => $direction) {
  416. if (empty($appliedOrders[$field])) {
  417. $this->_select->order(new Zend_Db_Expr($field . ' ' . $direction));
  418. }
  419. }
  420. }
  421. return $this;
  422. }
  423. /**
  424. * Set Id Fieldname as Tag Relation Id
  425. *
  426. * @return Mage_Tag_Model_Resource_Product_Collection
  427. */
  428. public function setRelationId()
  429. {
  430. $this->_setIdFieldName('tag_relation_id');
  431. return $this;
  432. }
  433. }