Get product changes

2020-06-12 04:40发布

Situation is:

Admin logs in to system and he changes product somehow.

For example:

Sets qty to 10 Adds 2 images Changes description

Is there any way to track these changes? Well I mean exactly track WHAT and HOW admin changed?

I use Magento CE 1.6

标签: magento
3条回答
闹够了就滚
2楼-- · 2020-06-12 04:57

just in case some people still coming up to this one: @clockworkgeek's answer is not correct, as soon as you turn on developer mode and displaying errors (php>=5.4) you will get exceptions and warnings:

Array to string conversion in...

as solution for recursive comparison:

public function onCatalogProductSaveBefore($observer)
{
  $product = $observer->getProduct();
  if ($product->hasDataChanges()) {
    $newValues = $this->_compareArrayAssocRecursive($product->getData(), $product->getOrigData());
    $oldValues = $this->_compareArrayAssocRecursive($product->getOrigData(), $product->getData());
  }
}

protected function _compareArrayAssocRecursive($array1, $array2) 
{
    $diff = array();
    foreach ($array1 as $key => $value) {
        if (is_array($value)) {
            if (!isset($array2[$key]) || !is_array($array2[$key])) {
                $diff[$key] = $value;
            } else {
                $newDiff = $this->_compareArrayAssocRecursive($value, $array2[$key]);
                if (!empty($newDiff)) {
                    $diff[$key] = $newDiff;
                }
            }
        } elseif (!array_key_exists($key,$array2) || $array2[$key] !== $value) {
            $diff[$key] = $value;
        }
    }
    return $diff;
}

Hope that helps Personally i would recommend to put that function into a helper class and make it public :)

UPDATE: according to problems with numeric values was float and decimal the better solution would be:

/**
 * return diff according to product changes 
 * 
 * @param Mage_Catalog_Model_Product $product
 * @return array
 */
protected function _compareArrayAssocRecursive($product)
{
    $diff = array();
    $attributes = $product->getTypeInstance(true)->getEditableAttributes($product);

    foreach ($attributes as $key => $value) {
        if ($product->dataHasChangedFor($key)) {
            $diff[$key] = $product->getData($key);
        }
    }
    return $diff;
}
查看更多
虎瘦雄心在
3楼-- · 2020-06-12 04:58

Yes you can find unaltered data through getOrigData() as pointed out by clockworkgeek but Magento has a build in function to compare and check if the data has been changed. The method is called dataHasChangedFor() and you have to pass the property that you want to check. It would look somthing like this.

$isChanged = $productData->dataHasChangedFor('description'); 
if ($isChanged) { 
// do somthing 
}

here the method dataHasChanged() will return boolean value based on whether the data was altered.

查看更多
不美不萌又怎样
4楼-- · 2020-06-12 05:16

You can find the unaltered data through an object's getOrigData() method. A good time to get the object is through it's save_before event, so create an observer for the catalog_product_save_before event. The observer might contain the following:

public function onCatalogProductSaveBefore($observer)
{
  $product = $observer->getProduct();
  if ($product->hasDataChanges()) {
    $newValues = array_diff_assoc($product->getData(), $product->getOrigData());
    $oldValues = array_diff_assoc($product->getOrigData(), $product->getData());
    $added     = array_diff_key($product->getData(), $product->getOrigData());
    $unset     = array_diff_key($product->getOrigData(), $product->getData());
  }
}

Note that $newValues will include all of $added and existing attributes that have had their value changed. Ditto for $oldValues and $unset.

查看更多
登录 后发表回答