Magento – how to get shopping cart price rule items in catalog page

catalog-price-rulesdiscountpromotionsshopping-cart-price-rules

I have configured the shopping cart price rule in Magento. Is it possible to fetch category IDs, product Ids that I configure in shopping cart price rule on product catalog page ?

If the product is eligible for some shopping cart price rule, I would like to get the shopping cart price rule name in product page ?

Awaiting for your valuable reply.

Best Answer

Very possible to do, and is really not limited to the type of Shopping Cart Rule Conditions.

The basic idea is to create a copy of the current quote object, inject your currently viewed product into 'said copy of quote', and then validate that copied quote object against your rule(s)

This way (most) rule conditions would be able to be used, and still get back a valid response.

Please note the following: I use this exact same idea to display a Gifting Icon, in my Gifting Promotions Extension, if a currently viewed item validates for gifting (if added to cart).

The code example below is thus using my gifting modules promo rule models, but you should be able to simply change that to the core Shopping Cart Rule models. The way my Gifting extension functionality works, is heavily based on the core way of doing the rules, so should be interchangeable. Even if not, the idea is here now :)

The code exists as a helper function, as I use it from product view and category list pages - I have added some comments in the code, but please ask if you need any clarifications.

Note that if you have a LOT of rules, this CAN, and WILL slow down your page load / display, unless cached. The routine below shows a way to use cache to help improve performance. Since the cache keys are known, you can easily add some hooks to product save, and rule saving to clear out the relevant cache blocks, so display is correct. of course a FPC will solve this as well)

So, now you have the idea, and enough babbling from me - show me the code!

The routine is simply called as such:

$result = Mage::helper('giftpromo/gifticon')
                    ->testItemHasValidGifting($this->getProduct());

and itself is:

    /**
                 * Determine if product would validate for a gift, if added to cart
                 *
                 * @param Mage_Catalog_Model_Product $product
                 *
                 *
                 * @return array List of validated rules. Empty if none
                 */
                public function testItemHasValidGifting(
                    Mage_Catalog_Model_Product $product
                ) {
                    $cacheKeys = array();
        $useCache = Mage::app()->useCache('giftpromo_product_valid');
$quote = Mage::getSingleton('checkout/cart')->getQuote();
                if ($useCache) {
                    $cacheID = ($quote->getId()) ? $quote->getId() : rand(0,1000000);
                    $cacheName = 'giftpromo_product_valid_cache_'
                        . $product->getId()
                        . '_' . $quote->getUpdatedAt()
                        . '_' . $cacheID;
                    $cachedData = Mage::app()->getCache()
                        ->load($cacheName);
                    if (is_string($cachedData)) {
                        try {
                            $result = unserialize($cachedData);
                            mage::helper('giftpromo')->debug("loaded from cache {$cacheName}", 5);

                            return $result;
                        } catch (Exception $e) {
                            mage::logException($e);
                        }
                    }
                }

                    $validRules = array();

                    try {
                        $rules = Mage::getSingleton('giftpromo/promo_rule')
                            ->getCollection()
                            ->addFieldToSelect('*');
                        // create a copy of the current quote object
                        // add this product to the copy quote
                        // validate rule against the copy quote
                        $copyQuote = new Varien_Object;
                        $copyQuote->setData($quote->getData());
                        // inject this product as an item here!
                        $allItems = array();
                        $product->setQty(1); // we want to test a fixed qty of 1, but this can be made more dynamic
                        // ensure product is fully loaded to allow for proper rule validation.
                        $product = $product->load($product->getId());
                        $product->setProductId(
                            $product->getId()
                        ); // workaround since rule expects cart items containing products, not products directly
                        $product->setProduct(
                            $product
                        ); // workaround since rule expects cart items containing products, not products directly
                        $allItems[] = $product;
                        //adjust the cart subtotal to reflect the additional item price, thus making rule valid for totals
                        $copyQuote->setAllItems($allItems);
                        $copyQuote->setAllVisibleItems($allItems);
                        $copyQuote->setSubtotal(
                            $copyQuote->getSubtotal() + $product->getPrice()
                        );
                        foreach ($rules as $rule) {
                            // test if the rule can be processed
                            if ($rule->validate($copyQuote)) {
                                    $cacheKeys[] = 'GIFTPROMO_RULE_VALID_'.$rule->getId(); // allow for selective cache clean on rule save 
                                    $validRules[] = $rule;
                            }
                        }
                    } catch (Exception $e) {
                        Mage::logException($e);
                    }

    // cache this
            if ($useCache) {
                try {
                    $cacheID = ($quote->getId()) ? $quote->getId() : 0;
                    $cacheName = 'giftpromo_product_valid_cache_'
                        . $product->getId()
                        . '_' . $quote->getUpdatedAt()
                        . '_' . $cacheID;
                    $cacheModel = Mage::app()->getCache();
                    if ($product->getId()) {
                        // clear out any old cache for this.
                        mage::helper('giftpromo')->debug(
                            "Clearing old cache for GIFTPROMO_PRODUCT_VALID_{$product->getId()}_{$cacheID}", 5
                        );
                        $cacheModel->clean(
                            Zend_Cache::CLEANING_MODE_MATCHING_TAG,
                            array('GIFTPROMO_PRODUCT_VALID_' . $product->getId() . '_' . $cacheID)
                        );
                    }
                    $cacheModel
                        ->save(
                            serialize($validRules),
                            $cacheName,
                            array_merge(array('GIFTPROMO_PRODUCT_VALID',
                                  'GIFTPROMO_PRODUCT_VALID_' . $cacheID,
                                  'GIFTPROMO_PRODUCT_VALID_' . $product->getId(),
                                  'GIFTPROMO_PRODUCT_VALID_' . $product->getId() . '_' . $cacheID
                            ), $cacheKeys), 600
                        );
                    mage::helper('giftpromo')->debug("Generating cache for {$cacheName}", 5);

                } catch
                (Exception $e) {
                    mage::logException($e);
                }
            }
                    return $validRules;
                }

Good luck :)

Related Topic