Overview

Packages

  • currencysymbol
  • MAbout
  • Mage
    • Admin
    • Adminhtml
    • AdminNotification
    • Api
    • Api2
    • Authorizenet
    • Backup
    • Bundle
    • Captcha
    • Catalog
    • CatalogIndex
    • CatalogInventory
    • CatalogRule
    • CatalogSearch
    • Centinel
    • Checkout
    • Cms
    • Compiler
    • Connect
    • Contacts
    • Core
    • Cron
    • CurrencySymbol
    • Customer
    • Dataflow
    • Directory
    • DirtectPost
    • Downloadable
    • Eav
    • GiftMessage
    • GoogleAnalytics
    • GoogleBase
    • GoogleCheckout
    • ImportExport
    • Index
    • Install
    • Log
    • Media
    • Newsletter
    • Oauth
    • Page
    • PageCache
    • Paygate
    • Payment
    • Paypal
    • PaypalUk
    • Persistent
    • Poll
    • ProductAlert
    • Rating
    • Reports
    • Review
    • Rss
    • Rule
    • Sales
    • SalesRule
    • Sedfriend
    • Sendfriend
    • Shipping
    • Sitemap
    • Tag
    • Tax
    • Usa
    • Weee
    • Widget
    • Wishlist
    • XmlConnect
  • None
  • Phoenix
    • Moneybookers
  • PHP
  • Zend
    • Date
    • Mime
    • XmlRpc

Classes

  • Mage_CatalogRule_Helper_Data
  • Mage_CatalogRule_Model_Flag
  • Mage_CatalogRule_Model_Mysql4_Rule
  • Mage_CatalogRule_Model_Mysql4_Rule_Collection
  • Mage_CatalogRule_Model_Mysql4_Rule_Product_Price
  • Mage_CatalogRule_Model_Mysql4_Rule_Product_Price_Collection
  • Mage_CatalogRule_Model_Observer
  • Mage_CatalogRule_Model_Resource_Rule
  • Mage_CatalogRule_Model_Resource_Rule_Collection
  • Mage_CatalogRule_Model_Resource_Rule_Product_Price
  • Mage_CatalogRule_Model_Resource_Rule_Product_Price_Collection
  • Mage_CatalogRule_Model_Rule
  • Mage_CatalogRule_Model_Rule_Action_Collection
  • Mage_CatalogRule_Model_Rule_Action_Product
  • Mage_CatalogRule_Model_Rule_Condition_Combine
  • Mage_CatalogRule_Model_Rule_Condition_Product
  • Mage_CatalogRule_Model_Rule_Product_Price
  • Overview
  • Package
  • Class
  • Tree
  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) 2012 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: 
 28: /**
 29:  * Catalog rules resource model
 30:  *
 31:  * @category    Mage
 32:  * @package     Mage_CatalogRule
 33:  * @author      Magento Core Team <core@magentocommerce.com>
 34:  */
 35: class Mage_CatalogRule_Model_Resource_Rule extends Mage_Rule_Model_Resource_Abstract
 36: {
 37:     /**
 38:      * Store number of seconds in a day
 39:      */
 40:     const SECONDS_IN_DAY = 86400;
 41: 
 42:     /**
 43:      * Store associated with rule entities information map
 44:      *
 45:      * @var array
 46:      */
 47:     protected $_associatedEntitiesMap = array(
 48:         'website' => array(
 49:             'associations_table' => 'catalogrule/website',
 50:             'rule_id_field'      => 'rule_id',
 51:             'entity_id_field'    => 'website_id'
 52:         ),
 53:         'customer_group' => array(
 54:             'associations_table' => 'catalogrule/customer_group',
 55:             'rule_id_field'      => 'rule_id',
 56:             'entity_id_field'    => 'customer_group_id'
 57:         )
 58:     );
 59: 
 60:     /**
 61:      * Initialize main table and table id field
 62:      */
 63:     protected function _construct()
 64:     {
 65:         $this->_init('catalogrule/rule', 'rule_id');
 66:     }
 67: 
 68:     /**
 69:      * Add customer group ids and website ids to rule data after load
 70:      *
 71:      * @param Mage_Core_Model_Abstract $object
 72:      *
 73:      * @return Mage_CatalogRule_Model_Resource_Rule
 74:      */
 75:     protected function _afterLoad(Mage_Core_Model_Abstract $object)
 76:     {
 77:         $object->setData('customer_group_ids', (array)$this->getCustomerGroupIds($object->getId()));
 78:         $object->setData('website_ids', (array)$this->getWebsiteIds($object->getId()));
 79: 
 80:         return parent::_afterLoad($object);
 81:     }
 82: 
 83:     /**
 84:      * Bind catalog rule to customer group(s) and website(s).
 85:      * Update products which are matched for rule.
 86:      *
 87:      * @param Mage_Core_Model_Abstract $object
 88:      *
 89:      * @return Mage_CatalogRule_Model_Resource_Rule
 90:      */
 91:     protected function _afterSave(Mage_Core_Model_Abstract $object)
 92:     {
 93:         if ($object->hasWebsiteIds()) {
 94:             $websiteIds = $object->getWebsiteIds();
 95:             if (!is_array($websiteIds)) {
 96:                 $websiteIds = explode(',', (string)$websiteIds);
 97:             }
 98:             $this->bindRuleToEntity($object->getId(), $websiteIds, 'website');
 99:         }
100: 
101:         if ($object->hasCustomerGroupIds()) {
102:             $customerGroupIds = $object->getCustomerGroupIds();
103:             if (!is_array($customerGroupIds)) {
104:                 $customerGroupIds = explode(',', (string)$customerGroupIds);
105:             }
106:             $this->bindRuleToEntity($object->getId(), $customerGroupIds, 'customer_group');
107:         }
108: 
109:         parent::_afterSave($object);
110:         return $this;
111:     }
112: 
113:     /**
114:      * Update products which are matched for rule
115:      *
116:      * @param Mage_CatalogRule_Model_Rule $rule
117:      *
118:      * @return Mage_CatalogRule_Model_Resource_Rule
119:      */
120:     public function updateRuleProductData(Mage_CatalogRule_Model_Rule $rule)
121:     {
122:         $ruleId = $rule->getId();
123:         $write  = $this->_getWriteAdapter();
124:         $write->beginTransaction();
125:         if ($rule->getProductsFilter()) {
126:             $write->delete(
127:                 $this->getTable('catalogrule/rule_product'),
128:                 array(
129:                     'rule_id=?' => $ruleId,
130:                     'product_id IN (?)' => $rule->getProductsFilter()
131:                 )
132:             );
133:         } else {
134:             $write->delete($this->getTable('catalogrule/rule_product'), $write->quoteInto('rule_id=?', $ruleId));
135:         }
136: 
137:         if (!$rule->getIsActive()) {
138:             $write->commit();
139:             return $this;
140:         }
141: 
142:         $websiteIds = $rule->getWebsiteIds();
143:         if (!is_array($websiteIds)) {
144:             $websiteIds = explode(',', $websiteIds);
145:         }
146:         if (empty($websiteIds)) {
147:             return $this;
148:         }
149: 
150:         Varien_Profiler::start('__MATCH_PRODUCTS__');
151:         $productIds = $rule->getMatchingProductIds();
152:         Varien_Profiler::stop('__MATCH_PRODUCTS__');
153: 
154:         $customerGroupIds = $rule->getCustomerGroupIds();
155:         $fromTime = strtotime($rule->getFromDate());
156:         $toTime = strtotime($rule->getToDate());
157:         $toTime = $toTime ? ($toTime + self::SECONDS_IN_DAY - 1) : 0;
158:         $sortOrder = (int)$rule->getSortOrder();
159:         $actionOperator = $rule->getSimpleAction();
160:         $actionAmount = $rule->getDiscountAmount();
161:         $subActionOperator = $rule->getSubIsEnable() ? $rule->getSubSimpleAction() : '';
162:         $subActionAmount = $rule->getSubDiscountAmount();
163:         $actionStop = $rule->getStopRulesProcessing();
164: 
165:         $rows = array();
166: 
167:         try {
168:             foreach ($productIds as $productId) {
169:                 foreach ($websiteIds as $websiteId) {
170:                     foreach ($customerGroupIds as $customerGroupId) {
171:                         $rows[] = array(
172:                             'rule_id' => $ruleId,
173:                             'from_time' => $fromTime,
174:                             'to_time' => $toTime,
175:                             'website_id' => $websiteId,
176:                             'customer_group_id' => $customerGroupId,
177:                             'product_id' => $productId,
178:                             'action_operator' => $actionOperator,
179:                             'action_amount' => $actionAmount,
180:                             'action_stop' => $actionStop,
181:                             'sort_order' => $sortOrder,
182:                             'sub_simple_action' => $subActionOperator,
183:                             'sub_discount_amount' => $subActionAmount,
184:                         );
185: 
186:                         if (count($rows) == 1000) {
187:                             $write->insertMultiple($this->getTable('catalogrule/rule_product'), $rows);
188:                             $rows = array();
189:                         }
190:                     }
191:                 }
192:             }
193:             if (!empty($rows)) {
194:                $write->insertMultiple($this->getTable('catalogrule/rule_product'), $rows);
195:             }
196: 
197:             $write->commit();
198:         } catch (Exception $e) {
199:             $write->rollback();
200:             throw $e;
201:         }
202: 
203: 
204:         return $this;
205:     }
206: 
207:     /**
208:      * Get all product ids matched for rule
209:      *
210:      * @param int $ruleId
211:      *
212:      * @return array
213:      */
214:     public function getRuleProductIds($ruleId)
215:     {
216:         $read = $this->_getReadAdapter();
217:         $select = $read->select()->from($this->getTable('catalogrule/rule_product'), 'product_id')
218:             ->where('rule_id=?', $ruleId);
219: 
220:         return $read->fetchCol($select);
221:     }
222: 
223:     /**
224:      * Remove catalog rules product prices for specified date range and product
225:      *
226:      * @param int|string $fromDate
227:      * @param int|string $toDate
228:      * @param int|null $productId
229:      *
230:      * @return Mage_CatalogRule_Model_Resource_Rule
231:      */
232:     public function removeCatalogPricesForDateRange($fromDate, $toDate, $productId = null)
233:     {
234:         $write = $this->_getWriteAdapter();
235:         $conds = array();
236:         $cond = $write->quoteInto('rule_date between ?', $this->formatDate($fromDate));
237:         $cond = $write->quoteInto($cond.' and ?', $this->formatDate($toDate));
238:         $conds[] = $cond;
239:         if (!is_null($productId)) {
240:             $conds[] = $write->quoteInto('product_id=?', $productId);
241:         }
242: 
243:         /**
244:          * Add information about affected products
245:          * It can be used in processes which related with product price (like catalog index)
246:          */
247:         $select = $this->_getWriteAdapter()->select()
248:             ->from($this->getTable('catalogrule/rule_product_price'), 'product_id')
249:             ->where(implode(' AND ', $conds))
250:             ->group('product_id');
251: 
252:         $replace = $write->insertFromSelect(
253:             $select,
254:             $this->getTable('catalogrule/affected_product'),
255:             array('product_id'),
256:             true
257:         );
258:         $write->query($replace);
259:         $write->delete($this->getTable('catalogrule/rule_product_price'), $conds);
260:         return $this;
261:     }
262: 
263:     /**
264:      * Delete old price rules data
265:      *
266:      * @param string $date
267:      * @param int|null $productId
268:      *
269:      * @return Mage_CatalogRule_Model_Resource_Rule
270:      */
271:     public function deleteOldData($date, $productId = null)
272:     {
273:         $write = $this->_getWriteAdapter();
274:         $conds = array();
275:         $conds[] = $write->quoteInto('rule_date<?', $this->formatDate($date));
276:         if (!is_null($productId)) {
277:             $conds[] = $write->quoteInto('product_id=?', $productId);
278:         }
279:         $write->delete($this->getTable('catalogrule/rule_product_price'), $conds);
280:         return $this;
281:     }
282: 
283:     /**
284:      * Get DB resource statement for processing query result
285:      *
286:      * @param int $fromDate
287:      * @param int $toDate
288:      * @param int|null $productId
289:      * @param int|null $websiteId
290:      *
291:      * @return Zend_Db_Statement_Interface
292:      */
293:     protected function _getRuleProductsStmt($fromDate, $toDate, $productId = null, $websiteId = null)
294:     {
295:         $read = $this->_getReadAdapter();
296:         /**
297:          * Sort order is important
298:          * It used for check stop price rule condition.
299:          * website_id   customer_group_id   product_id  sort_order
300:          *  1           1                   1           0
301:          *  1           1                   1           1
302:          *  1           1                   1           2
303:          * if row with sort order 1 will have stop flag we should exclude
304:          * all next rows for same product id from price calculation
305:          */
306:         $select = $read->select()
307:             ->from(array('rp' => $this->getTable('catalogrule/rule_product')))
308:             ->where($read->quoteInto('rp.from_time = 0 or rp.from_time <= ?', $toDate)
309:             . ' OR ' . $read->quoteInto('rp.to_time = 0 or rp.to_time >= ?', $fromDate))
310:             ->order(array('rp.website_id', 'rp.customer_group_id', 'rp.product_id', 'rp.sort_order', 'rp.rule_id'));
311: 
312:         if (!is_null($productId)) {
313:             $select->where('rp.product_id=?', $productId);
314:         }
315: 
316:         /**
317:          * Join default price and websites prices to result
318:          */
319:         $priceAttr  = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'price');
320:         $priceTable = $priceAttr->getBackend()->getTable();
321:         $attributeId= $priceAttr->getId();
322: 
323:         $joinCondition = '%1$s.entity_id=rp.product_id AND (%1$s.attribute_id=' . $attributeId
324:             . ') and %1$s.store_id=%2$s';
325: 
326:         $select->join(
327:             array('pp_default'=>$priceTable),
328:             sprintf($joinCondition, 'pp_default', Mage_Core_Model_App::ADMIN_STORE_ID),
329:             array('default_price'=>'pp_default.value')
330:         );
331: 
332:         if ($websiteId !== null) {
333:             $website  = Mage::app()->getWebsite($websiteId);
334:             $defaultGroup = $website->getDefaultGroup();
335:             if ($defaultGroup instanceof Mage_Core_Model_Store_Group) {
336:                 $storeId = $defaultGroup->getDefaultStoreId();
337:             } else {
338:                 $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
339:             }
340: 
341:             $select->joinInner(
342:                 array('product_website' => $this->getTable('catalog/product_website')),
343:                 'product_website.product_id=rp.product_id ' .
344:                 'AND rp.website_id=product_website.website_id ' .
345:                 'AND product_website.website_id='.$websiteId,
346:                 array()
347:             );
348: 
349:             $tableAlias = 'pp'.$websiteId;
350:             $fieldAlias = 'website_'.$websiteId.'_price';
351:             $select->joinLeft(
352:                 array($tableAlias=>$priceTable),
353:                 sprintf($joinCondition, $tableAlias, $storeId),
354:                 array($fieldAlias=>$tableAlias.'.value')
355:             );
356:         } else {
357:             foreach (Mage::app()->getWebsites() as $website) {
358:                 $websiteId  = $website->getId();
359:                 $defaultGroup = $website->getDefaultGroup();
360:                 if ($defaultGroup instanceof Mage_Core_Model_Store_Group) {
361:                     $storeId = $defaultGroup->getDefaultStoreId();
362:                 } else {
363:                     $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
364:                 }
365: 
366:                 $tableAlias = 'pp' . $websiteId;
367:                 $fieldAlias = 'website_' . $websiteId . '_price';
368:                 $select->joinLeft(
369:                     array($tableAlias => $priceTable),
370:                     sprintf($joinCondition, $tableAlias, $storeId),
371:                     array($fieldAlias => $tableAlias.'.value')
372:                 );
373:             }
374:         }
375: 
376:         return $read->query($select);
377:     }
378: 
379:     /**
380:      * Generate catalog price rules prices for specified date range
381:      * If from date is not defined - will be used previous day by UTC
382:      * If to date is not defined - will be used next day by UTC
383:      *
384:      * @param int|string|null $fromDate
385:      * @param int|string|null $toDate
386:      * @param int $productId
387:      *
388:      * @return Mage_CatalogRule_Model_Resource_Rule
389:      */
390:     public function applyAllRulesForDateRange($fromDate = null, $toDate = null, $productId = null)
391:     {
392:         $write = $this->_getWriteAdapter();
393:         $write->beginTransaction();
394: 
395:         Mage::dispatchEvent('catalogrule_before_apply', array('resource' => $this));
396: 
397:         $clearOldData = false;
398:         if ($fromDate === null) {
399:             $fromDate = mktime(0,0,0,date('m'),date('d')-1);
400:             /**
401:              * If fromDate not specified we can delete all data oldest than 1 day
402:              * We have run it for clear table in case when cron was not installed
403:              * and old data exist in table
404:              */
405:             $clearOldData = true;
406:         }
407:         if (is_string($fromDate)) {
408:             $fromDate = strtotime($fromDate);
409:         }
410:         if ($toDate === null) {
411:             $toDate = mktime(0,0,0,date('m'),date('d')+1);
412:         }
413:         if (is_string($toDate)) {
414:             $toDate = strtotime($toDate);
415:         }
416: 
417:         $product = null;
418:         if ($productId instanceof Mage_Catalog_Model_Product) {
419:             $product    = $productId;
420:             $productId  = $productId->getId();
421:         }
422: 
423:         $this->removeCatalogPricesForDateRange($fromDate, $toDate, $productId);
424:         if ($clearOldData) {
425:             $this->deleteOldData($fromDate, $productId);
426:         }
427: 
428:         $dayPrices  = array();
429: 
430:         try {
431:             /**
432:              * Update products rules prices per each website separately
433:              * because of max join limit in mysql
434:              */
435:             foreach (Mage::app()->getWebsites(false) as $website) {
436:                 $productsStmt = $this->_getRuleProductsStmt(
437:                    $fromDate,
438:                    $toDate,
439:                    $productId,
440:                    $website->getId()
441:                 );
442: 
443:                 $dayPrices  = array();
444:                 $stopFlags  = array();
445:                 $prevKey    = null;
446: 
447:                 while ($ruleData = $productsStmt->fetch()) {
448:                     $ruleProductId  = $ruleData['product_id'];
449:                     $productKey     = $ruleProductId . '_'
450:                        . $ruleData['website_id'] . '_'
451:                        . $ruleData['customer_group_id'];
452: 
453:                     if ($prevKey && ($prevKey != $productKey)) {
454:                         $stopFlags = array();
455:                     }
456: 
457:                     /**
458:                      * Build prices for each day
459:                      */
460:                     for ($time=$fromDate; $time<=$toDate; $time+=self::SECONDS_IN_DAY) {
461:                         if (($ruleData['from_time']==0 || $time >= $ruleData['from_time'])
462:                             && ($ruleData['to_time']==0 || $time <=$ruleData['to_time'])
463:                         ) {
464:                             $priceKey = $time . '_' . $productKey;
465: 
466:                             if (isset($stopFlags[$priceKey])) {
467:                                 continue;
468:                             }
469: 
470:                             if (!isset($dayPrices[$priceKey])) {
471:                                 $dayPrices[$priceKey] = array(
472:                                     'rule_date'         => $time,
473:                                     'website_id'        => $ruleData['website_id'],
474:                                     'customer_group_id' => $ruleData['customer_group_id'],
475:                                     'product_id'        => $ruleProductId,
476:                                     'rule_price'        => $this->_calcRuleProductPrice($ruleData),
477:                                     'latest_start_date' => $ruleData['from_time'],
478:                                     'earliest_end_date' => $ruleData['to_time'],
479:                                 );
480:                             } else {
481:                                 $dayPrices[$priceKey]['rule_price'] = $this->_calcRuleProductPrice(
482:                                     $ruleData,
483:                                     $dayPrices[$priceKey]
484:                                 );
485:                                 $dayPrices[$priceKey]['latest_start_date'] = max(
486:                                     $dayPrices[$priceKey]['latest_start_date'],
487:                                     $ruleData['from_time']
488:                                 );
489:                                 $dayPrices[$priceKey]['earliest_end_date'] = min(
490:                                     $dayPrices[$priceKey]['earliest_end_date'],
491:                                     $ruleData['to_time']
492:                                 );
493:                             }
494: 
495:                             if ($ruleData['action_stop']) {
496:                                 $stopFlags[$priceKey] = true;
497:                             }
498:                         }
499:                     }
500: 
501:                     $prevKey = $productKey;
502:                     if (count($dayPrices)>1000) {
503:                         $this->_saveRuleProductPrices($dayPrices);
504:                         $dayPrices = array();
505:                     }
506:                 }
507:                 $this->_saveRuleProductPrices($dayPrices);
508:             }
509:             $this->_saveRuleProductPrices($dayPrices);
510: 
511:             $write->delete($this->getTable('catalogrule/rule_group_website'), array());
512: 
513:             $timestamp = Mage::getModel('core/date')->gmtTimestamp();
514: 
515:             $select = $write->select()
516:                 ->distinct(true)
517:                 ->from(
518:                     $this->getTable('catalogrule/rule_product'),
519:                     array('rule_id', 'customer_group_id', 'website_id')
520:                 )->where("{$timestamp} >= from_time AND (({$timestamp} <= to_time AND to_time > 0) OR to_time = 0)");
521:             $query = $select->insertFromSelect($this->getTable('catalogrule/rule_group_website'));
522:             $write->query($query);
523: 
524:             $write->commit();
525:         } catch (Exception $e) {
526:             $write->rollback();
527:             throw $e;
528:         }
529: 
530:         $productCondition = Mage::getModel('catalog/product_condition')
531:             ->setTable($this->getTable('catalogrule/affected_product'))
532:             ->setPkFieldName('product_id');
533:         Mage::dispatchEvent('catalogrule_after_apply', array(
534:             'product' => $product,
535:             'product_condition' => $productCondition
536:         ));
537:         $write->delete($this->getTable('catalogrule/affected_product'));
538: 
539:         return $this;
540:     }
541: 
542:     /**
543:      * Calculate product price based on price rule data and previous information
544:      *
545:      * @param array $ruleData
546:      * @param null|array $productData
547:      *
548:      * @return float
549:      */
550:     protected function _calcRuleProductPrice($ruleData, $productData = null)
551:     {
552:         if ($productData !== null && isset($productData['rule_price'])) {
553:             $productPrice = $productData['rule_price'];
554:         } else {
555:             $websiteId = $ruleData['website_id'];
556:             if (isset($ruleData['website_'.$websiteId.'_price'])) {
557:                 $productPrice = $ruleData['website_'.$websiteId.'_price'];
558:             } else {
559:                 $productPrice = $ruleData['default_price'];
560:             }
561:         }
562: 
563:         $productPrice = Mage::helper('catalogrule')->calcPriceRule(
564:             $ruleData['action_operator'],
565:             $ruleData['action_amount'],
566:             $productPrice);
567: 
568:         return Mage::app()->getStore()->roundPrice($productPrice);
569:     }
570: 
571:     /**
572:      * Save rule prices for products to DB
573:      *
574:      * @param array $arrData
575:      *
576:      * @return Mage_CatalogRule_Model_Resource_Rule
577:      */
578:     protected function _saveRuleProductPrices($arrData)
579:     {
580:         if (empty($arrData)) {
581:             return $this;
582:         }
583: 
584:         $adapter    = $this->_getWriteAdapter();
585:         $productIds = array();
586: 
587:         $adapter->beginTransaction();
588:         try {
589:             foreach ($arrData as $key => $data) {
590:                 $productIds['product_id'] = $data['product_id'];
591:                 $arrData[$key]['rule_date'] = $this->formatDate($data['rule_date'], false);
592:                 $arrData[$key]['latest_start_date'] = $this->formatDate($data['latest_start_date'], false);
593:                 $arrData[$key]['earliest_end_date'] = $this->formatDate($data['earliest_end_date'], false);
594:             }
595:             $adapter->insertOnDuplicate($this->getTable('catalogrule/affected_product'), array_unique($productIds));
596:             $adapter->insertOnDuplicate($this->getTable('catalogrule/rule_product_price'), $arrData);
597: 
598:         } catch (Exception $e) {
599:             $adapter->rollback();
600:             throw $e;
601: 
602:         }
603:         $adapter->commit();
604: 
605:         return $this;
606:     }
607: 
608:     /**
609:      * Get catalog rules product price for specific date, website and
610:      * customer group
611:      *
612:      * @param int|string $date
613:      * @param int $wId
614:      * @param int $gId
615:      * @param int $pId
616:      *
617:      * @return float|bool
618:      */
619:     public function getRulePrice($date, $wId, $gId, $pId)
620:     {
621:         $data = $this->getRulePrices($date, $wId, $gId, array($pId));
622:         if (isset($data[$pId])) {
623:             return $data[$pId];
624:         }
625: 
626:         return false;
627:     }
628: 
629:     /**
630:      * Retrieve product prices by catalog rule for specific date, website and customer group
631:      * Collect data with  product Id => price pairs
632:      *
633:      * @param int|string $date
634:      * @param int $websiteId
635:      * @param int $customerGroupId
636:      * @param array $productIds
637:      *
638:      * @return array
639:      */
640:     public function getRulePrices($date, $websiteId, $customerGroupId, $productIds)
641:     {
642:         $adapter = $this->_getReadAdapter();
643:         $select  = $adapter->select()
644:             ->from($this->getTable('catalogrule/rule_product_price'), array('product_id', 'rule_price'))
645:             ->where('rule_date = ?', $this->formatDate($date, false))
646:             ->where('website_id = ?', $websiteId)
647:             ->where('customer_group_id = ?', $customerGroupId)
648:             ->where('product_id IN(?)', $productIds);
649:         return $adapter->fetchPairs($select);
650:     }
651: 
652:     /**
653:      * Get active rule data based on few filters
654:      *
655:      * @param int|string $date
656:      * @param int $websiteId
657:      * @param int $customerGroupId
658:      * @param int $productId
659:      * @return array
660:      */
661:     public function getRulesFromProduct($date, $websiteId, $customerGroupId, $productId)
662:     {
663:         $adapter = $this->_getReadAdapter();
664:         if (is_string($date)) {
665:             $date = strtotime($date);
666:         }
667:         $select = $adapter->select()
668:             ->from($this->getTable('catalogrule/rule_product'))
669:             ->where('website_id = ?', $websiteId)
670:             ->where('customer_group_id = ?', $customerGroupId)
671:             ->where('product_id = ?', $productId)
672:             ->where('from_time = 0 or from_time < ?', $date)
673:             ->where('to_time = 0 or to_time > ?', $date);
674: 
675:         return $adapter->fetchAll($select);
676:     }
677: 
678:     /**
679:      * Retrieve product price data for all customer groups
680:      *
681:      * @param int|string $date
682:      * @param int $wId
683:      * @param int $pId
684:      *
685:      * @return array
686:      */
687:     public function getRulesForProduct($date, $wId, $pId)
688:     {
689:         $read = $this->_getReadAdapter();
690:         $select = $read->select()
691:             ->from($this->getTable('catalogrule/rule_product_price'), '*')
692:             ->where('rule_date=?', $this->formatDate($date, false))
693:             ->where('website_id=?', $wId)
694:             ->where('product_id=?', $pId);
695: 
696:         return $read->fetchAll($select);
697:     }
698: 
699:     /**
700:      * Apply catalog rule to product
701:      *
702:      * @param Mage_CatalogRule_Model_Rule $rule
703:      * @param Mage_Catalog_Model_Product $product
704:      * @param array $websiteIds
705:      *
706:      * @return Mage_CatalogRule_Model_Resource_Rule
707:      */
708:     public function applyToProduct($rule, $product, $websiteIds)
709:     {
710:         if (!$rule->getIsActive()) {
711:             return $this;
712:         }
713: 
714:         $ruleId    = $rule->getId();
715:         $productId = $product->getId();
716: 
717:         $write = $this->_getWriteAdapter();
718:         $write->beginTransaction();
719: 
720:         $write->delete($this->getTable('catalogrule/rule_product'), array(
721:             $write->quoteInto('rule_id=?', $ruleId),
722:             $write->quoteInto('product_id=?', $productId),
723:         ));
724: 
725:         if (!$rule->getConditions()->validate($product)) {
726:             $write->delete($this->getTable('catalogrule/rule_product_price'), array(
727:                 $write->quoteInto('product_id=?', $productId),
728:             ));
729:             $write->commit();
730:             return $this;
731:         }
732: 
733:         $customerGroupIds = $rule->getCustomerGroupIds();
734:         $fromTime = strtotime($rule->getFromDate());
735:         $toTime = strtotime($rule->getToDate());
736:         $toTime = $toTime ? $toTime + self::SECONDS_IN_DAY - 1 : 0;
737:         $sortOrder = (int)$rule->getSortOrder();
738:         $actionOperator = $rule->getSimpleAction();
739:         $actionAmount = $rule->getDiscountAmount();
740:         $actionStop = $rule->getStopRulesProcessing();
741:         $subActionOperator = $rule->getSubIsEnable() ? $rule->getSubSimpleAction() : '';
742:         $subActionAmount = $rule->getSubDiscountAmount();
743: 
744:         $rows = array();
745:         try {
746:             foreach ($websiteIds as $websiteId) {
747:                 foreach ($customerGroupIds as $customerGroupId) {
748:                     $rows[] = array(
749:                         'rule_id' => $ruleId,
750:                         'from_time' => $fromTime,
751:                         'to_time' => $toTime,
752:                         'website_id' => $websiteId,
753:                         'customer_group_id' => $customerGroupId,
754:                         'product_id' => $productId,
755:                         'action_operator' => $actionOperator,
756:                         'action_amount' => $actionAmount,
757:                         'action_stop' => $actionStop,
758:                         'sort_order' => $sortOrder,
759:                         'sub_simple_action' => $subActionOperator,
760:                         'sub_discount_amount' => $subActionAmount,
761:                     );
762: 
763:                     if (count($rows) == 1000) {
764:                         $write->insertMultiple($this->getTable('catalogrule/rule_product'), $rows);
765:                         $rows = array();
766:                     }
767:                 }
768:             }
769: 
770:             if (!empty($rows)) {
771:                 $write->insertMultiple($this->getTable('catalogrule/rule_product'), $rows);
772:             }
773:         } catch (Exception $e) {
774:             $write->rollback();
775:             throw $e;
776:         }
777: 
778:         $this->applyAllRulesForDateRange(null, null, $product);
779: 
780:         $write->commit();
781: 
782:         return $this;
783:     }
784: }
785: 
Magento 1.7.0.2 API documentation generated by ApiGen 2.8.0