PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/rgranadino/magento-mirror
PHP | 432 lines | 266 code | 38 blank | 128 comment | 23 complexity | 3e2db83900a65bc23c3e41ac1626ec57 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) 2011 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. * Tag resourse model
  28. *
  29. * @category Mage
  30. * @package Mage_Tag
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Tag_Model_Resource_Tag extends Mage_Core_Model_Resource_Db_Abstract
  34. {
  35. /**
  36. * Define main table and primary index
  37. *
  38. */
  39. protected function _construct()
  40. {
  41. $this->_init('tag/tag', 'tag_id');
  42. }
  43. /**
  44. * Initialize unique fields
  45. *
  46. * @return Mage_Tag_Model_Resource_Tag
  47. */
  48. protected function _initUniqueFields()
  49. {
  50. $this->_uniqueFields = array(array(
  51. 'field' => 'name',
  52. 'title' => Mage::helper('tag')->__('Tag')
  53. ));
  54. return $this;
  55. }
  56. /**
  57. * Loading tag by name
  58. *
  59. * @param Mage_Tag_Model_Tag $model
  60. * @param string $name
  61. * @return array|false
  62. */
  63. public function loadByName($model, $name)
  64. {
  65. if ( $name ) {
  66. $read = $this->_getReadAdapter();
  67. $select = $read->select();
  68. if (Mage::helper('core/string')->strlen($name) > 255) {
  69. $name = Mage::helper('core/string')->substr($name, 0, 255);
  70. }
  71. $select->from($this->getMainTable())
  72. ->where('name = :name');
  73. $data = $read->fetchRow($select, array('name' => $name));
  74. $model->setData(( is_array($data) ) ? $data : array());
  75. } else {
  76. return false;
  77. }
  78. }
  79. /**
  80. * Before saving actions
  81. *
  82. * @param Mage_Core_Model_Abstract $object
  83. * @return Mage_Tag_Model_Resource_Tag
  84. */
  85. protected function _beforeSave(Mage_Core_Model_Abstract $object)
  86. {
  87. if (!$object->getId() && $object->getStatus() == $object->getApprovedStatus()) {
  88. $searchTag = new Varien_Object();
  89. $this->loadByName($searchTag, $object->getName());
  90. if ($searchTag->getData($this->getIdFieldName())
  91. && $searchTag->getStatus() == $object->getPendingStatus()) {
  92. $object->setId($searchTag->getData($this->getIdFieldName()));
  93. }
  94. }
  95. if (Mage::helper('core/string')->strlen($object->getName()) > 255) {
  96. $object->setName(Mage::helper('core/string')->substr($object->getName(), 0, 255));
  97. }
  98. return parent::_beforeSave($object);
  99. }
  100. /**
  101. * Saving tag's base popularity
  102. *
  103. * @param Mage_Core_Model_Abstract $object
  104. * @return Mage_Core_Model_Resource_Db_Abstract
  105. */
  106. protected function _afterSave(Mage_Core_Model_Abstract $object)
  107. {
  108. if (!$object->getStore() || !Mage::app()->getStore()->isAdmin()) {
  109. return parent::_afterSave($object);
  110. }
  111. $tagId = ($object->isObjectNew()) ? $object->getTagId() : $object->getId();
  112. $writeAdapter = $this->_getWriteAdapter();
  113. $writeAdapter->insertOnDuplicate($this->getTable('tag/properties'), array(
  114. 'tag_id' => $tagId,
  115. 'store_id' => $object->getStore(),
  116. 'base_popularity' => (!$object->getBasePopularity()) ? 0 : $object->getBasePopularity()
  117. ));
  118. return parent::_afterSave($object);
  119. }
  120. /**
  121. * Getting base popularity per store view for specified tag
  122. *
  123. * @deprecated after 1.4.0.0
  124. *
  125. * @param int $tagId
  126. * @return array
  127. */
  128. protected function _getExistingBasePopularity($tagId)
  129. {
  130. $read = $this->_getReadAdapter();
  131. $selectSummary = $read->select()
  132. ->from(
  133. array('main' => $this->getTable('tag/summary')),
  134. array('store_id', 'base_popularity')
  135. )
  136. ->where('main.tag_id = :tag_id')
  137. ->where('main.store_id != 0');
  138. return $read->fetchAssoc($selectSummary, array('tag_id' => $tagId));
  139. }
  140. /**
  141. * Get aggregation data per store view
  142. *
  143. * @deprecated after 1.4.0.0
  144. *
  145. * @param int $tagId
  146. * @return array
  147. */
  148. protected function _getAggregationPerStoreView($tagId)
  149. {
  150. $readAdapter = $this->_getReadAdapter();
  151. $selectLocal = $readAdapter->select()
  152. ->from(
  153. array('main' => $this->getTable('tag/relation')),
  154. array(
  155. 'customers' => 'COUNT(DISTINCT main.customer_id)',
  156. 'products' => 'COUNT(DISTINCT main.product_id)',
  157. 'store_id',
  158. 'uses' => 'COUNT(main.tag_relation_id)'
  159. )
  160. )
  161. ->join(array('store' => $this->getTable('core/store')),
  162. 'store.store_id = main.store_id AND store.store_id > 0',
  163. array()
  164. )
  165. ->join(array('product_website' => $this->getTable('catalog/product_website')),
  166. 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
  167. array()
  168. )
  169. ->where('main.tag_id = :tag_id')
  170. ->where('main.active = 1')
  171. ->group('main.store_id');
  172. $selectLocalResult = $readAdapter->fetchAll($selectLocal, array('tag_id' => $tagId));
  173. $selectHistorical = $readAdapter->select()
  174. ->from(
  175. array('main' => $this->getTable('tag/relation')),
  176. array('historical_uses' => 'COUNT(main.tag_relation_id)',
  177. 'store_id')
  178. )
  179. ->join(array('store' => $this->getTable('core/store')),
  180. 'store.store_id = main.store_id AND store.store_id > 0',
  181. array()
  182. )
  183. ->join(array('product_website' => $this->getTable('catalog/product_website')),
  184. 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
  185. array()
  186. )
  187. ->group('main.store_id')
  188. ->where('main.tag_id = :tag_id');
  189. $selectHistoricalResult = $readAdapter->fetchAll($selectHistorical, array('tag_id' => $tagId));
  190. foreach ($selectHistoricalResult as $historical) {
  191. foreach ($selectLocalResult as $key => $local) {
  192. if ($local['store_id'] == $historical['store_id']) {
  193. $selectLocalResult[$key]['historical_uses'] = $historical['historical_uses'];
  194. break;
  195. }
  196. }
  197. }
  198. return $selectLocalResult;
  199. }
  200. /**
  201. * Get global aggregation data for row with store_id = 0
  202. *
  203. * @deprecated after 1.4.0.0
  204. *
  205. * @param int $tagId
  206. * @return array
  207. */
  208. protected function _getGlobalAggregation($tagId)
  209. {
  210. $readAdapter = $this->_getReadAdapter();
  211. // customers and products stats
  212. $selectGlobal = $readAdapter->select()
  213. ->from(
  214. array('main' => $this->getTable('tag/relation')),
  215. array(
  216. 'customers' => 'COUNT(DISTINCT main.customer_id)',
  217. 'products' => 'COUNT(DISTINCT main.product_id)',
  218. 'store_id' => new Zend_Db_Expr(0),
  219. 'uses' => 'COUNT(main.tag_relation_id)'
  220. )
  221. )
  222. ->join(array('store' => $this->getTable('core/store')),
  223. 'store.store_id=main.store_id AND store.store_id>0',
  224. array()
  225. )
  226. ->join(array('product_website' => $this->getTable('catalog/product_website')),
  227. 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
  228. array()
  229. )
  230. ->where('main.tag_id = :tag_id')
  231. ->where('main.active = 1');
  232. $result = $readAdapter->fetchRow($selectGlobal, array('tag_id' => $tagId));
  233. if (!$result) {
  234. return array();
  235. }
  236. // historical uses stats
  237. $selectHistoricalGlobal = $readAdapter->select()
  238. ->from(
  239. array('main' => $this->getTable('tag/relation')),
  240. array('historical_uses' => 'COUNT(main.tag_relation_id)')
  241. )
  242. ->join(array('store' => $this->getTable('core/store')),
  243. 'store.store_id = main.store_id AND store.store_id > 0',
  244. array()
  245. )
  246. ->join(array('product_website' => $this->getTable('catalog/product_website')),
  247. 'product_website.website_id = store.website_id AND product_website.product_id = main.product_id',
  248. array()
  249. )
  250. ->where('main.tag_id = :tag_id');
  251. $result['historical_uses'] = (int) $readAdapter->fetchOne($selectHistoricalGlobal, array('tag_id' => $tagId));
  252. return $result;
  253. }
  254. /**
  255. * Getting statistics data into buffer.
  256. * Replacing our buffer array with new statistics and incoming data.
  257. *
  258. * @deprecated after 1.4.0.0
  259. *
  260. * @param Mage_Tag_Model_Tag $object
  261. * @return Mage_Tag_Model_Tag
  262. */
  263. public function aggregate($object)
  264. {
  265. $tagId = (int)$object->getId();
  266. $storeId = (int)$object->getStore();
  267. // create final summary from existing data and add specified base popularity
  268. $finalSummary = $this->_getExistingBasePopularity($tagId);
  269. if ($object->hasBasePopularity() && $storeId) {
  270. $finalSummary[$storeId]['store_id'] = $storeId;
  271. $finalSummary[$storeId]['base_popularity'] = $object->getBasePopularity();
  272. }
  273. // calculate aggregation data
  274. $summaries = $this->_getAggregationPerStoreView($tagId);
  275. $summariesGlobal = $this->_getGlobalAggregation($tagId);
  276. if ($summariesGlobal) {
  277. $summaries[] = $summariesGlobal;
  278. }
  279. // override final summary with aggregated data
  280. foreach ($summaries as $row) {
  281. $storeId = (int)$row['store_id'];
  282. foreach ($row as $key => $value) {
  283. $finalSummary[$storeId][$key] = $value;
  284. }
  285. }
  286. // prepare static parameters to final summary for insertion
  287. foreach ($finalSummary as $key => $row) {
  288. $finalSummary[$key]['tag_id'] = $tagId;
  289. foreach (array('base_popularity', 'popularity', 'historical_uses', 'uses', 'products', 'customers') as $k) {
  290. if (!isset($row[$k])) {
  291. $finalSummary[$key][$k] = 0;
  292. }
  293. }
  294. $finalSummary[$key]['popularity'] = $finalSummary[$key]['historical_uses'];
  295. }
  296. // remove old and insert new data
  297. $write = $this->_getWriteAdapter();
  298. $write->delete(
  299. $this->getTable('tag/summary'), array('tag_id = ?' => $tagId)
  300. );
  301. $write->insertMultiple($this->getTable('tag/summary'), $finalSummary);
  302. return $object;
  303. }
  304. /**
  305. * Decrementing tag products quantity as action for product delete
  306. *
  307. * @param array $tagsId
  308. * @return int The number of affected rows
  309. */
  310. public function decrementProducts(array $tagsId)
  311. {
  312. $writeAdapter = $this->_getWriteAdapter();
  313. if (empty($tagsId)) {
  314. return 0;
  315. }
  316. return $writeAdapter->update(
  317. $this->getTable('tag/summary'),
  318. array('products' => new Zend_Db_Expr('products - 1')),
  319. array('tag_id IN (?)' => $tagsId)
  320. );
  321. }
  322. /**
  323. * Add summary data to specified object
  324. *
  325. * @deprecated after 1.4.0.0
  326. *
  327. * @param Mage_Tag_Model_Tag $object
  328. * @return Mage_Tag_Model_Tag
  329. */
  330. public function addSummary($object)
  331. {
  332. $read = $this->_getReadAdapter();
  333. $select = $read->select()
  334. ->from(array('relation' => $this->getTable('tag/relation')), array())
  335. ->joinLeft(
  336. array('summary' => $this->getTable('tag/summary')),
  337. 'relation.tag_id = summary.tag_id AND relation.store_id = summary.store_id',
  338. array(
  339. 'customers',
  340. 'products',
  341. 'popularity'
  342. )
  343. )
  344. ->where('relation.tag_id = :tag_id')
  345. ->where('relation.store_id = :store_id')
  346. ->limit(1);
  347. $bind = array(
  348. 'tag_id' => (int)$object->getId(),
  349. 'store_id' => (int)$object->getStoreId()
  350. );
  351. $row = $read->fetchRow($select, $bind);
  352. if ($row) {
  353. $object->addData($row);
  354. }
  355. return $object;
  356. }
  357. /**
  358. * Retrieve select object for load object data
  359. * Redeclare parent method just for adding tag's base popularity if flag exists
  360. *
  361. * @param string $field
  362. * @param mixed $value
  363. * @param Mage_Core_Model_Abstract $object
  364. * @return Zend_Db_Select
  365. */
  366. protected function _getLoadSelect($field, $value, $object)
  367. {
  368. $select = parent::_getLoadSelect($field, $value, $object);
  369. if ($object->getAddBasePopularity() && $object->hasStoreId()) {
  370. $select->joinLeft(
  371. array('properties' => $this->getTable('tag/properties')),
  372. "properties.tag_id = {$this->getMainTable()}.tag_id AND properties.store_id = {$object->getStoreId()}",
  373. 'base_popularity'
  374. );
  375. }
  376. return $select;
  377. }
  378. /**
  379. * Fetch store ids in which tag visible
  380. *
  381. * @param Mage_Tag_Model_Resource_Tag $object
  382. * @return Mage_Tag_Model_Resource_Tag
  383. */
  384. protected function _afterLoad(Mage_Core_Model_Abstract $object)
  385. {
  386. $read = $this->_getReadAdapter();
  387. $select = $read->select()
  388. ->from($this->getTable('tag/summary'), array('store_id'))
  389. ->where('tag_id = :tag_id');
  390. $storeIds = $read->fetchCol($select, array('tag_id' => $object->getId()));
  391. $object->setVisibleInStoreIds($storeIds);
  392. return $this;
  393. }
  394. }