Magento – Using catalog_product_save_after Event for Massaction

event-observermassactionproduct

I'm using the event catalog_product_save_after to trigger some action after a product has altered/saved. This event does not work when a massaction is used to change the product as this is done without calling save().

  • Is there another event that can be used to monitor product changes?
  • Is there a recommended way to get all product changes?

Best Answer

You can do this job via standard event/observers:

<global>
     <events>
        <catalog_product_save_before>
            <observers>
                <some_module_detect_product_changes>
                    <type>singleton</type>
                    <class>some_module/observer</class>
                    <method>detectProductChanges</method>
                </some_module_detect_product_changes>
            </observers>
        </catalog_product_save_before>
        <catalog_product_attribute_update_before>
            <observers>
                <some_module_detect_product_attribute_changes>
                    <type>singleton</type>
                    <class>some_module/observer</class>
                    <method>detectProductAttributeChanges</method>
                </some_module_detect_product_attribute_changes>
            </observers>
        </catalog_product_attribute_update_before>
</global>

And Observer.php:

class Some_Module_Model_Observer{
    public function detectProductAttributeChanges($observer)
    {
        $attributesData = $observer->getEvent()->getAttributesData();
        $productIds     = $observer->getEvent()->getProductIds();

        $user  = Mage::getSingleton('admin/session')->getUser();
        foreach ($productIds as $id) {
            $change             = Mage::getModel('some_module/changes');
            $change->product_id = $id;
            $change->new_values = print_r($attributesData, true);
            $change->user_id    = ($user) ? $user->getId() : NULL;
            $change->created    = now();
            $change->save();
        }
        return $this;
    }

    public function detectProductChanges($observer)
    {
        /**
         * @var $product Mage_Catalog_Model_Product
         * @var $user    Mage_Admin_Model_User
         */
        $product = $observer->getEvent()->getProduct();
        if ($product->hasDataChanges()) {

            try {
                $user       = Mage::getSingleton('admin/session')->getUser();
                $attributes = $this->getAttributes();
                $new        = array();
                $org        = array();
                $changes    = array();
                foreach ($attributes as $attribute) {
                    if (!is_array($product->getData($attribute))) {
                        $new[$attribute] = ($product->getData($attribute)) ? $product->getData($attribute) : null;
                        if (!is_array($product->getOrigData($attribute))) {
                            $org[$attribute] = ($product->getOrigData($attribute)) ? $product->getOrigData($attribute) : null;
                            if (($new[$attribute] != $org[$attribute])) {
                                $changes[$attribute] = array('new'=> $new[$attribute],
                                                             'old'=> $org[$attribute]);
                            }
                        }
                    }
                }

                $stokAttributes = array(
                    'qty',
                    'manage_stock',
                    'is_in_stock',
                    'min_qty',
                    'min_sale_qty',
                    'max_sale_qty',
                );
                if ($product->getStockItem()) {
                    foreach ($stokAttributes as $attribute=> $value) {
                        $new[$attribute] = ($product->getStockItem()->getData($attribute)) ? $product->getStockItem()->getData($attribute) : null;
                        $org[$attribute] = ($product->getStockItem()->getOrigData($attribute)) ? $product->getStockItem()->getOrigData($attribute) : null;
                        if ($new[$attribute] != $org[$attribute]) {
                            $changes[$attribute] = array('new'=> $new[$attribute],
                                                         'old'=> $org[$attribute]);
                        }
                    }
                }


                $newValues = array_intersect_key($new, $changes);
                if (count($newValues)) {
                    $oldValues = array_intersect_key($org, $changes);

                    $change             = Mage::getModel('some_module/changes');
                    $change->product_id = $product->entity_id;
                    $change->sku        = $product->sku;
                    $change->name       = $product->name;
                    $change->new_values = print_r($newValues, true);
                    $change->old_values = print_r($oldValues, true);
                    $change->user_id    = ($user) ? $user->getId() : NULL;
                    $change->created    = now();
                    $change->save();
                }
            } catch (Exception $e) {
                Mage::log($e->getTraceAsString(), null, 'product_changes_fault.log');
            }
        }
        return $this;
    }

}

Here is I used Changes model to save every changes to DB. And you may create admin grid to view tracked changes on dashboard.

Related Topic