Получить изменения продукта - PullRequest
10 голосов
/ 18 ноября 2011

Ситуация такова:

Администратор входит в систему и как-то меняет продукт.

Например:

Устанавливает количество в 10 Добавляет 2 изображения Описание изменений

Есть ли способ отследить эти изменения?Ну, я имею в виду именно трек, ЧТО и КАК изменил админ?

Я использую Magento CE 1.6

Ответы [ 3 ]

22 голосов
/ 18 ноября 2011

Вы можете найти неизмененные данные с помощью метода getOrigData() объекта. Хорошее время для получения объекта - это событие save_before, поэтому создайте наблюдатель для события 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.

4 голосов
/ 24 марта 2016

Да, вы можете найти неизмененные данные с помощью getOrigData (), как указано в clockworkgeek, но Magento имеет встроенную функцию для сравнения и проверки изменения данных.Метод называется dataHasChangedFor (), и вам нужно передать свойство, которое вы хотите проверить.Это выглядело бы примерно так.

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

здесь метод dataHasChanged () будет возвращать логическое значение в зависимости от того, были ли данные изменены.

1 голос
/ 22 сентября 2015

на всякий случай, если некоторые люди все еще подходят к этому: ответ @ 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...