PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/CatalogRule/Model/Observer.php

https://bitbucket.org/acidel/buykoala
PHP | 382 lines | 234 code | 41 blank | 107 comment | 38 complexity | 029c83a08f5206fb734766c26f1be325 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_CatalogRule
  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. * Catalog Price rules observer model
  28. */
  29. class Mage_CatalogRule_Model_Observer
  30. {
  31. protected $_rulePrices = array();
  32. /**
  33. * Apply all catalog price rules for specific product
  34. *
  35. * @param Varien_Event_Observer $observer
  36. * @return Mage_CatalogRule_Model_Observer
  37. */
  38. public function applyAllRulesOnProduct($observer)
  39. {
  40. $product = $observer->getEvent()->getProduct();
  41. if ($product->getIsMassupdate()) {
  42. return;
  43. }
  44. $productWebsiteIds = $product->getWebsiteIds();
  45. $rules = Mage::getModel('catalogrule/rule')->getCollection()
  46. ->addFieldToFilter('is_active', 1);
  47. foreach ($rules as $rule) {
  48. if (!is_array($rule->getWebsiteIds())) {
  49. $ruleWebsiteIds = (array)explode(',', $rule->getWebsiteIds());
  50. } else {
  51. $ruleWebsiteIds = $rule->getWebsiteIds();
  52. }
  53. $websiteIds = array_intersect($productWebsiteIds, $ruleWebsiteIds);
  54. $rule->applyToProduct($product, $websiteIds);
  55. }
  56. return $this;
  57. }
  58. /**
  59. * Apply all price rules for current date.
  60. * Handle cataolg_product_import_after event
  61. *
  62. * @param Varien_Event_Observer $observer
  63. * @return Mage_CatalogRule_Model_Observer
  64. */
  65. public function applyAllRules($observer)
  66. {
  67. $resource = Mage::getResourceSingleton('catalogrule/rule');
  68. $resource->applyAllRulesForDateRange($resource->formatDate(mktime(0,0,0)));
  69. Mage::app()->removeCache('catalog_rules_dirty');
  70. return $this;
  71. }
  72. /**
  73. * Apply catalog price rules to product on frontend
  74. *
  75. * @return Mage_CatalogRule_Model_Observer
  76. */
  77. public function processFrontFinalPrice($observer)
  78. {
  79. $product = $observer->getEvent()->getProduct();
  80. $pId = $product->getId();
  81. $storeId = $product->getStoreId();
  82. if ($observer->hasDate()) {
  83. $date = $observer->getEvent()->getDate();
  84. } else {
  85. $date = Mage::app()->getLocale()->storeTimeStamp($storeId);
  86. }
  87. if ($observer->hasWebsiteId()) {
  88. $wId = $observer->getEvent()->getWebsiteId();
  89. } else {
  90. $wId = Mage::app()->getStore($storeId)->getWebsiteId();
  91. }
  92. if ($observer->hasCustomerGroupId()) {
  93. $gId = $observer->getEvent()->getCustomerGroupId();
  94. } elseif ($product->hasCustomerGroupId()) {
  95. $gId = $product->getCustomerGroupId();
  96. } else {
  97. $gId = Mage::getSingleton('customer/session')->getCustomerGroupId();
  98. }
  99. $key = "$date|$wId|$gId|$pId";
  100. if (!isset($this->_rulePrices[$key])) {
  101. $rulePrice = Mage::getResourceModel('catalogrule/rule')
  102. ->getRulePrice($date, $wId, $gId, $pId);
  103. $this->_rulePrices[$key] = $rulePrice;
  104. }
  105. if ($this->_rulePrices[$key]!==false) {
  106. $finalPrice = min($product->getData('final_price'), $this->_rulePrices[$key]);
  107. $product->setFinalPrice($finalPrice);
  108. }
  109. return $this;
  110. }
  111. /**
  112. * Apply catalog price rules to product in admin
  113. *
  114. * @return Mage_CatalogRule_Model_Observer
  115. */
  116. public function processAdminFinalPrice($observer)
  117. {
  118. $product = $observer->getEvent()->getProduct();
  119. $storeId = $product->getStoreId();
  120. $date = Mage::app()->getLocale()->storeDate($storeId);
  121. $key = false;
  122. if ($ruleData = Mage::registry('rule_data')) {
  123. $wId = $ruleData->getWebsiteId();
  124. $gId = $ruleData->getCustomerGroupId();
  125. $pId = $product->getId();
  126. $key = "$date|$wId|$gId|$pId";
  127. }
  128. elseif ($product->getWebsiteId() != null && $product->getCustomerGroupId() != null) {
  129. $wId = $product->getWebsiteId();
  130. $gId = $product->getCustomerGroupId();
  131. $pId = $product->getId();
  132. $key = "$date|$wId|$gId|$pId";
  133. }
  134. if ($key) {
  135. if (!isset($this->_rulePrices[$key])) {
  136. $rulePrice = Mage::getResourceModel('catalogrule/rule')
  137. ->getRulePrice($date, $wId, $gId, $pId);
  138. $this->_rulePrices[$key] = $rulePrice;
  139. }
  140. if ($this->_rulePrices[$key]!==false) {
  141. $finalPrice = min($product->getData('final_price'), $this->_rulePrices[$key]);
  142. $product->setFinalPrice($finalPrice);
  143. }
  144. }
  145. return $this;
  146. }
  147. /**
  148. * Calculate price using catalog price rules of configurable product
  149. *
  150. * @param Varien_Event_Observer $observer
  151. * @return Mage_CatalogRule_Model_Observer
  152. */
  153. public function catalogProductTypeConfigurablePrice(Varien_Event_Observer $observer)
  154. {
  155. $product = $observer->getEvent()->getProduct();
  156. if ($product instanceof Mage_Catalog_Model_Product
  157. && $product->getConfigurablePrice() !== null
  158. ) {
  159. $configurablePrice = $product->getConfigurablePrice();
  160. $productPriceRule = Mage::getModel('catalogrule/rule')->calcProductPriceRule($product, $configurablePrice);
  161. if ($productPriceRule !== null) {
  162. $product->setConfigurablePrice($productPriceRule);
  163. }
  164. }
  165. return $this;
  166. }
  167. /**
  168. * Daily update catalog price rule by cron
  169. * Update include interval 3 days - current day - 1 days before + 1 days after
  170. * This method is called from cron process, cron is working in UTC time and
  171. * we should generate data for interval -1 day ... +1 day
  172. *
  173. * @param Varien_Event_Observer $observer
  174. * @return Mage_CatalogRule_Model_Observer
  175. */
  176. public function dailyCatalogUpdate($observer)
  177. {
  178. Mage::getResourceSingleton('catalogrule/rule')->applyAllRulesForDateRange();
  179. return $this;
  180. }
  181. public function flushPriceCache()
  182. {
  183. $this->_rulePrices = array();
  184. }
  185. /**
  186. * Calculate minimal final price with catalog rule price
  187. *
  188. * @param Varien_Event_Observer $observer
  189. * @return Mage_CatalogRule_Model_Observer
  190. */
  191. public function prepareCatalogProductPriceIndexTable(Varien_Event_Observer $observer)
  192. {
  193. $select = $observer->getEvent()->getSelect();
  194. $indexTable = $observer->getEvent()->getIndexTable();
  195. $entityId = $observer->getEvent()->getEntityId();
  196. $customerGroupId = $observer->getEvent()->getCustomerGroupId();
  197. $websiteId = $observer->getEvent()->getWebsiteId();
  198. $websiteDate = $observer->getEvent()->getWebsiteDate();
  199. $updateFields = $observer->getEvent()->getUpdateFields();
  200. Mage::getSingleton('catalogrule/rule_product_price')
  201. ->applyPriceRuleToIndexTable($select, $indexTable, $entityId, $customerGroupId, $websiteId,
  202. $updateFields, $websiteDate);
  203. return $this;
  204. }
  205. /**
  206. * Check rules that contains affected attribute
  207. * If rules were found they will be set to inactive and notice will be add to admin session
  208. *
  209. * @param string $attributeCode
  210. * @return Mage_CatalogRule_Model_Observer
  211. */
  212. protected function _checkCatalogRulesAvailability($attributeCode)
  213. {
  214. /* @var $collection Mage_CatalogRule_Model_Mysql4_Rule_Collection */
  215. $collection = Mage::getResourceModel('catalogrule/rule_collection')
  216. ->addAttributeInConditionFilter($attributeCode);
  217. $disabledRulesCount = 0;
  218. foreach ($collection as $rule) {
  219. /* @var $rule Mage_CatalogRule_Model_Rule */
  220. $rule->setIsActive(0);
  221. /* @var $rule->getConditions() Mage_CatalogRule_Model_Rule_Condition_Combine */
  222. $this->_removeAttributeFromConditions($rule->getConditions(), $attributeCode);
  223. $rule->save();
  224. $disabledRulesCount++;
  225. }
  226. if ($disabledRulesCount) {
  227. Mage::getModel('catalogrule/rule')->applyAll();
  228. Mage::getSingleton('adminhtml/session')->addWarning(
  229. Mage::helper('catalogrule')->__('%d Catalog Price Rules based on "%s" attribute have been disabled.', $disabledRulesCount, $attributeCode));
  230. }
  231. return $this;
  232. }
  233. /**
  234. * Remove catalog attribute condition by attribute code from rule conditions
  235. *
  236. * @param Mage_CatalogRule_Model_Rule_Condition_Combine $combine
  237. * @param string $attributeCode
  238. */
  239. protected function _removeAttributeFromConditions($combine, $attributeCode)
  240. {
  241. $conditions = $combine->getConditions();
  242. foreach ($conditions as $conditionId => $condition) {
  243. if ($condition instanceof Mage_CatalogRule_Model_Rule_Condition_Combine) {
  244. $this->_removeAttributeFromConditions($condition, $attributeCode);
  245. }
  246. if ($condition instanceof Mage_CatalogRule_Model_Rule_Condition_Product) {
  247. if ($condition->getAttribute() == $attributeCode) {
  248. unset($conditions[$conditionId]);
  249. }
  250. }
  251. }
  252. $combine->setConditions($conditions);
  253. }
  254. /**
  255. * After save attribute if it is not used for promo rules already check rules for containing this attribute
  256. *
  257. * @param Varien_Event_Observer $observer
  258. * @return Mage_CatalogRule_Model_Observer
  259. */
  260. public function catalogAttributeSaveAfter(Varien_Event_Observer $observer)
  261. {
  262. $attribute = $observer->getEvent()->getAttribute();
  263. if ($attribute->dataHasChangedFor('is_used_for_promo_rules') && !$attribute->getIsUsedForPromoRules()) {
  264. $this->_checkCatalogRulesAvailability($attribute->getAttributeCode());
  265. }
  266. return $this;
  267. }
  268. /**
  269. * After delete attribute check rules that contains deleted attribute
  270. *
  271. * @param Varien_Event_Observer $observer
  272. * @return Mage_CatalogRule_Model_Observer
  273. */
  274. public function catalogAttributeDeleteAfter(Varien_Event_Observer $observer)
  275. {
  276. $attribute = $observer->getEvent()->getAttribute();
  277. if ($attribute->getIsUsedForPromoRules()) {
  278. $this->_checkCatalogRulesAvailability($attribute->getAttributeCode());
  279. }
  280. return $this;
  281. }
  282. public function prepareCatalogProductCollectionPrices(Varien_Event_Observer $observer)
  283. {
  284. /* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
  285. $collection = $observer->getEvent()->getCollection();
  286. $store = Mage::app()->getStore($observer->getEvent()->getStoreId());
  287. $websiteId = $store->getWebsiteId();
  288. if ($observer->getEvent()->hasCustomerGroupId()) {
  289. $groupId = $observer->getEvent()->getCustomerGroupId();
  290. } else {
  291. /* @var $session Mage_Customer_Model_Session */
  292. $session = Mage::getSingleton('customer/session');
  293. if ($session->isLoggedIn()) {
  294. $groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
  295. } else {
  296. $groupId = Mage_Customer_Model_Group::NOT_LOGGED_IN_ID;
  297. }
  298. }
  299. if ($observer->getEvent()->hasDate()) {
  300. $date = $observer->getEvent()->getDate();
  301. } else {
  302. $date = Mage::app()->getLocale()->storeTimeStamp($store);
  303. }
  304. $productIds = array();
  305. /* @var $product Mage_Core_Model_Product */
  306. foreach ($collection as $product) {
  307. $key = implode('|', array($date, $websiteId, $groupId, $product->getId()));
  308. if (!isset($this->_rulePrices[$key])) {
  309. $productIds[] = $product->getId();
  310. }
  311. }
  312. if ($productIds) {
  313. $rulePrices = Mage::getResourceModel('catalogrule/rule')
  314. ->getRulePrices($date, $websiteId, $groupId, $productIds);
  315. foreach ($productIds as $productId) {
  316. $key = implode('|', array($date, $websiteId, $groupId, $productId));
  317. $this->_rulePrices[$key] = isset($rulePrices[$productId]) ? $rulePrices[$productId] : false;
  318. }
  319. }
  320. return $this;
  321. }
  322. /**
  323. * Create catalog rule relations for imported products
  324. *
  325. * @param Varien_Event_Observer $observer
  326. */
  327. public function createCatalogRulesRelations(Varien_Event_Observer $observer)
  328. {
  329. $adapter = $observer->getEvent()->getAdapter();
  330. $affectedEntityIds = $adapter->getAffectedEntityIds();
  331. if (empty($affectedEntityIds)) {
  332. return;
  333. }
  334. $rules = Mage::getModel('catalogrule/rule')->getCollection()
  335. ->addFieldToFilter('is_active', 1);
  336. foreach ($rules as $rule) {
  337. $rule->setProductsFilter($affectedEntityIds);
  338. Mage::getResourceSingleton('catalogrule/rule')->updateRuleProductData($rule);
  339. }
  340. }
  341. }