Magento Event Observer – Observer Event Not Triggering on Index

event-observerindexprice

I have built an observer event that fires on catalog_product_save_before to parse the price of associated products and set another attribute to yes/no based on the result:

public function catalog_product_save_before($observer)
{ 
    $onsale = false;
    $product = $observer->getProduct();     
    if ($product->getTypeId() == 'grouped'){
        $associatedProducts = $product->getTypeInstance(true)->getAssociatedProducts($product);
    }  else if ($product->getTypeId() == 'configurable') {
        $associatedProducts = $product->getTypeInstance(true)->getUsedProducts($product);
    };
    if (isset($associatedProducts)) {
        foreach ($associatedProducts as $simple) {
            if ($simple->getPrice() > $simple->getSpecialPrice()) {
                $onsale = true;
                //no point wasting time if we find something, break the loop and return a true
                break;
            }
        }
        //set attribute to true or false depending on above. 
        $product->setchildren_on_sale($onsale);
    }
}

My config xml:

<?xml version="1.0"?>
<config>
  <global>
    <helpers>
      <name_module>
        <class>name_module_Helper</class>
      </name_module>
    </helpers>
    <events>                
        <catalog_product_save_before>
            <observers>
                <module>
                    <type>singleton</type>
                    <class>name_module_model_observer</class>
                    <method>catalog_product_save_before</method>
                </module>
            </observers>
        </catalog_product_save_before>  
    </events>
  </global>
</config> 

The above works fine when i save the product in the backend as normal.

However, I need this attribute to be calculated for all products, and then whenever they change / the price changes.

The event is not fired for all products during a complete reindex, even when I change the attributes of all products using the mass modification tool on the product grid.

Is there something else I need to do to ensure this event will fire whenever the product changed?

Best Answer

The event you're observing, catalog_product_save_before is not all-encompassing. For example, you mentioned that it doesn't trigger on mass-action changes to products. If you look at the code around this activity, you'll see that no product models are actually saved.

See Mage_Adminhtml_Catalog_ProductController::massStatusAction and notice:

Mage::getSingleton('catalog/product_action')
            ->updateAttributes($productIds, array('status' => $status), $storeId);

If you follow that method to its class, Mage_Catalog_Model_Product_Action::updateAttributes, you would see that no product models are loaded/saved here. Instead, a less intensive route is taken.

But the good news is that there you would also see other events triggered: catalog_product_attribute_update_[before|after].

In the same way, the indexing processes do not interact with product models as you might expect. See Mage_Index_Model_Indexer::processEntityAction for example, and you can find that you might be able to observe the [start|end]_process_event_catalog_product_[mass_action|save|delete|reindex] events.

I think it comes down to observing more events, or else re-thinking how you want to manage product changes.

Related Topic