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: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.