2

If I change multiple attributes of many products via mass action, the updated_at date of the products is not changed.

Why does it not change and how would you implement it? Observer?

4

Good question. I didn't notice this before.
The updated_at date does not change because the updated_at attribute has a backend model that updates the value Mage_Eav_Model_Entity_Attribute_Backend_Time_Updated. The value gets updated only when you call save on the product, because that's the only time the backend models for the attributes come into play.

There are some events dispatched in the mass update process. I think you have to observe all of them:
This one should be the easiest: catalog_product_attribute_update_before.
It is dispatched in Mage_Catalog_Model_Product_Action::updateAttributes. That method is called when updating the attributes.

The idea is to add the update_at in the attributes update list.
Your observer method could looks like this:

public function beforeUpdateAttributes($observer) 
{
    //the attributes data array is passed by reference
    $attributesData = $observer->getEvent()->getAttributesData();
    //add updated at
    $attributesData['updated_at'] = Varien_Date::now();
}

But now a problem.
If you only change a website or the stock data for the products this event never gets dispatched because Mage_Catalog_Model_Product_Action::updateAttributes does not get called.
Instead you can use these events:
catalog_product_stock_item_mass_change - for stock change.
catalog_product_to_website_change - for website change.
honestly I don't know if you should even update updated_at attribute the product if you change only the stock or a website, because technically you are not changing the product entity. You are just changing some related entities.
But in case you want to change updated_at in this case also, your observer for both of these events could look like this:

public function updateUpdatedAt($observer) 
{
    $productIds = $observer->getEvent()->getProducts();
    Mage::getSingleton('catalog/product_action')->updateAttributes(
        $productIds,
        array('updated_at' => Varien_Date::now()),
        0
    );
}

my code is not perfect. It has an issue. If you change some attributes in mass action AND the stock, the event catalog_product_attribute_update_before would be triggered twice. Once by the Mage_Catalog_Model_Product_Action::updateAttributes method and once by your observer for catalog_product_stock_item_mass_change.
To avoid this you should make your observer as a singleton and remember the product ids you already updated to avoid duplicate sql queries that have the same result.
The code would work even if you update a product twice, but it might be a bit slower.

  • It seems updateAttributes saves all data for products, except sku and updated_at all values in catalog_product_entity ... I was testing the above with (before) working code .... but I am unable to save SKU and UPDATED_AT column data. Sorry for the paste, this is the error Uncaught TypeError: Argument 1 passed to Varien_Db_Adapter_Pdo_Mysql::prepareColumnValue() must be of the type array, null given, called in /Mage/Eav/Model/Entity/Abstract.php on line 1509 Varien_Db_Adapter_Pdo_Mysql->prepareColumnValue(NULL, '2017-07-03 18:0...') – snh_nl Jul 3 '17 at 18:07
1

We implemented like answered before. But there is a bug or whatever. It does not work to update via updateAttributes().

That's why we do it with a collection:

$collection = Mage::getModel('catalog/product')->getCollection();
    $collection->addStoreFilter($storeId)
               ->addFieldToFilter('entity_id', array('in' => $productIds));

and

foreach($collection as $item) {
        $item->setUpdatedAt(Varien_Date::now());
        $item->save();
  • I have the same: cannot set either sku or updated_at via updateAttributes – snh_nl Jul 3 '17 at 18:08
1

I was unable to find catalog_product_stock_item_mass_change event and catalog_product_website_update_before does not send array by reference so you cannot update it.

I tried updating in post dispatch and also in looked at observer code, above solution will not work because updateAttribute Expects to work on Eav Attributes

You can quickly verify it by adding this line at the start of function

public function updateAttributes($productIds, $attrData, $storeId)
{

$attrData = array('updated_at' => Varien_Date::now());
//..keep rest of the code same
}

It will fail because it expects eav.

I fixed it by adding something like this in post dispatch

        $iRowsEffected = Mage::getSingleton('core/resource')->getConnection('core_write')
->update('catalog_product_entity',
            array('updated_at' => Varien_Date::now()),
            array(
                'entity_id IN (?)' => 
$Mage::helper('adminhtml/catalog_product_edit_action_attribute')->getProductIds(),
            )
        );
1

I want to add something to Marius's solution. In using catalog_product_attribute_update_before Observer and changing attributesData array, we should call setAttributesData at the end of the function:

public function beforeUpdateAttributes($observer) 
{
    //the attributes data array is passed by reference
    $attributesData = $observer->getEvent()->getAttributesData();
    //add updated at
    $attributesData['updated_at'] = Varien_Date::now();
    //set attributes data array
    $observer->getEvent()->setAttributesData($attributesData);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.