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
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.
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;
}
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
.