Massactionのcatalog_product_save_afterイベント


7

イベントcatalog_product_save_afterを使用して、製品が変更/保存された後に何らかのアクションをトリガーしています。これはsave()を呼び出さずに行われるため、製品を変更するためにmassactionが使用される場合、このイベントは機能しません。

  • 製品の変更を監視するために使用できる別のイベントはありますか?
  • すべての製品の変更を取得するための推奨される方法はありますか?

回答:


5

このジョブは、標準のイベント/オブザーバーを介して実行できます。

<global>
     <events>
        <catalog_product_save_before>
            <observers>
                <some_module_detect_product_changes>
                    <type>singleton</type>
                    <class>some_module/observer</class>
                    <method>detectProductChanges</method>
                </some_module_detect_product_changes>
            </observers>
        </catalog_product_save_before>
        <catalog_product_attribute_update_before>
            <observers>
                <some_module_detect_product_attribute_changes>
                    <type>singleton</type>
                    <class>some_module/observer</class>
                    <method>detectProductAttributeChanges</method>
                </some_module_detect_product_attribute_changes>
            </observers>
        </catalog_product_attribute_update_before>
</global>

そしてObserver.php:

class Some_Module_Model_Observer{
    public function detectProductAttributeChanges($observer)
    {
        $attributesData = $observer->getEvent()->getAttributesData();
        $productIds     = $observer->getEvent()->getProductIds();

        $user  = Mage::getSingleton('admin/session')->getUser();
        foreach ($productIds as $id) {
            $change             = Mage::getModel('some_module/changes');
            $change->product_id = $id;
            $change->new_values = print_r($attributesData, true);
            $change->user_id    = ($user) ? $user->getId() : NULL;
            $change->created    = now();
            $change->save();
        }
        return $this;
    }

    public function detectProductChanges($observer)
    {
        /**
         * @var $product Mage_Catalog_Model_Product
         * @var $user    Mage_Admin_Model_User
         */
        $product = $observer->getEvent()->getProduct();
        if ($product->hasDataChanges()) {

            try {
                $user       = Mage::getSingleton('admin/session')->getUser();
                $attributes = $this->getAttributes();
                $new        = array();
                $org        = array();
                $changes    = array();
                foreach ($attributes as $attribute) {
                    if (!is_array($product->getData($attribute))) {
                        $new[$attribute] = ($product->getData($attribute)) ? $product->getData($attribute) : null;
                        if (!is_array($product->getOrigData($attribute))) {
                            $org[$attribute] = ($product->getOrigData($attribute)) ? $product->getOrigData($attribute) : null;
                            if (($new[$attribute] != $org[$attribute])) {
                                $changes[$attribute] = array('new'=> $new[$attribute],
                                                             'old'=> $org[$attribute]);
                            }
                        }
                    }
                }

                $stokAttributes = array(
                    'qty',
                    'manage_stock',
                    'is_in_stock',
                    'min_qty',
                    'min_sale_qty',
                    'max_sale_qty',
                );
                if ($product->getStockItem()) {
                    foreach ($stokAttributes as $attribute=> $value) {
                        $new[$attribute] = ($product->getStockItem()->getData($attribute)) ? $product->getStockItem()->getData($attribute) : null;
                        $org[$attribute] = ($product->getStockItem()->getOrigData($attribute)) ? $product->getStockItem()->getOrigData($attribute) : null;
                        if ($new[$attribute] != $org[$attribute]) {
                            $changes[$attribute] = array('new'=> $new[$attribute],
                                                         'old'=> $org[$attribute]);
                        }
                    }
                }


                $newValues = array_intersect_key($new, $changes);
                if (count($newValues)) {
                    $oldValues = array_intersect_key($org, $changes);

                    $change             = Mage::getModel('some_module/changes');
                    $change->product_id = $product->entity_id;
                    $change->sku        = $product->sku;
                    $change->name       = $product->name;
                    $change->new_values = print_r($newValues, true);
                    $change->old_values = print_r($oldValues, true);
                    $change->user_id    = ($user) ? $user->getId() : NULL;
                    $change->created    = now();
                    $change->save();
                }
            } catch (Exception $e) {
                Mage::log($e->getTraceAsString(), null, 'product_changes_fault.log');
            }
        }
        return $this;
    }

}

ここでは、変更モデルを使用してすべての変更をDBに保存しています。また、管理グリッドを作成して、追跡された変更をダッシュ​​ボードに表示できます。


これは本当に良い答えですが、小さな問題があります。保存した後に製品を入手する必要があります。記録された変更は、cronジョブで製品をロードするために使用できますが、cronジョブは数分ごとにのみ実行されます。変更は、controller_front_send_response_after(dbに保存しなくても)でも処理できますが、これは醜い解決策になると思います。
Wienczny 2013年

私はあなたが本当に何を望んでいるのか想像できません。cronジョブを介して製品の変更を追跡する場合もこれを行うことができますが、古い値と新しい値を保存するための追加のテーブルも必要です。いくつかの属性のみを追跡する場合は、特定の期間ごとにスナップショットを取得できます。 1つのスナップショットを新しいスナップショットと比較します。これにより、変更を検出できます。ただし、属性全体を追跡したい場合、変更を保存するのはより複雑で費用がかかります。
mageUz 2013年

また、簡単な方法は、追跡する属性に基づいて製品のハッシュコードを計算することです。例:$ hash = md5($ product-> getName()。$ product-> getPrice()。$ product-> getSomeValueYouWantToTrack()); if($ product-> getHashCode()!= $ hash){// productに変更がある場合は、ロジックを実行します}; $ product-> setHashCode($ hash)-> save()
mageUz 2013年

製品の変更を追跡するのではなく、変更された製品を追跡します。変更された製品は、外部サービスと同期する必要があります。
Wienczny 2013年

上記の新しい最後の回答を参照してください
mageUz 2013年

4

観察することによってcatalog_product_attribute_update_before mageUzに育てを、あなたはproduct_idsなどのイベントが参照し、影響を受けたentity_idsを保存することができます。

Zend_Debug :: dumping $ observer-> getEvent()-> getData()で、私が取得する前catalog_product_attribute_update_を処理しました。

array(4){
  ["attributes_data"] =>&array(1){
    ["ステータス"] => int(1)
  }
  ["product_ids"] =>&array(2){
    [0] => string(6) "159340"
    [1] => string(6) "159339"
  }
  ["store_id"] =>&int(0)
  ["name"] => string(39) "catalog_product_attribute_update_before"
}

たとえば、これらのentity_idをMagentoセッションシングルトンに格納できます。

次に、Magentoの動的に構築されたイベントの1つであるend_process_event_catalog_product_mass_actionを確認します。製品の変更が完了したことを通知する処理により、更新された製品の状態を取得できます。それ自体にはデータが含まれていないため、保存したentity_idが必要になります。


0

私はすでにあなたの状況に適切なロジックをコメントしました。しかし、あなたを理解するために、私はさらにコードを与えます:

class Some_Module_Model_Sync{
public function catalogSynchronizeChangedProducts()
{
    /**
     * suppose you have hash_code attribute for catalog products which is store
     * hash code of synchronizeable attribute values.
     */
    $collection = Mage::getResourceModel('catalog/product_collection');
    foreach ($collection as $product) {
        $hash = md5($product->getName() . $product->getPrice() . $product->getSomeValueYouWantToSyncronize());
        if ($product->getHashCode() != $hash) {
            //if you understand this stuff, product has some changes, because of
            //new hash code not equal to hash code when last synchronized time;
            //you should synchronize this product

            /*after synchronization */
            $product->setHashCode($hash)->save();
        }
    }
}
}

そして、cronはこのロジックを使用して製品を同期します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.