【发布时间】:2011-11-18 11:55:26
【问题描述】:
情况是:
管理员登录系统,他以某种方式更改产品。
例如:
将数量设置为 10 添加 2 张图片 更改说明
有没有办法跟踪这些变化?好吧,我的意思是准确跟踪管理员更改的内容和方式?
我使用 Magento CE 1.6
【问题讨论】:
标签: magento
情况是:
管理员登录系统,他以某种方式更改产品。
例如:
将数量设置为 10 添加 2 张图片 更改说明
有没有办法跟踪这些变化?好吧,我的意思是准确跟踪管理员更改的内容和方式?
我使用 Magento CE 1.6
【问题讨论】:
标签: magento
您可以通过对象的getOrigData() 方法找到未更改的数据。获取对象的好时机是通过它的 save_before 事件,因此 create an observer 用于 catalog_product_save_before 事件。观察者可能包含以下内容:
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());
}
}
请注意,$newValues 将包括所有 $added 和已更改其值的现有属性。 $oldValues 和 $unset 同上。
【讨论】:
array_diff 会奏效。
是的,您可以通过 getOrigData() 找到未更改的数据,正如clockworkgeek 指出的那样,但 Magento 有一个内置函数来比较和检查数据是否已更改。该方法称为 dataHasChangedFor() ,您必须传递要检查的属性。 它看起来像这样。
$isChanged = $productData->dataHasChangedFor('description');
if ($isChanged) {
// do somthing
}
这里的 dataHasChanged() 方法将根据数据是否被更改返回布尔值。
【讨论】:
以防万一还有人提出这个问题: @clockworkgeek 的回答是不正确的,一旦你打开开发者模式并显示错误(php>=5.4)你就会得到异常和警告:
Array to string conversion in...
作为递归比较的解决方案:
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;
}
希望有所帮助 就我个人而言,我建议将该函数放入一个辅助类并使其公开:)
更新: 根据数值问题是浮点数和小数,更好的解决方案是:
/**
* 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;
}
【讨论】: