catalog_product_save_after Sự kiện cho khối lượng


7

Tôi đang sử dụng danh mục sự kiện_product_save_after để kích hoạt một số hành động sau khi sản phẩm bị thay đổi / lưu. Sự kiện này không hoạt động khi khối lượng được sử dụng để thay đổi sản phẩm vì việc này được thực hiện mà không cần gọi save ().

  • Có sự kiện nào khác có thể được sử dụng để theo dõi sự thay đổi của sản phẩm không?
  • Có một cách được đề nghị để có được tất cả các thay đổi sản phẩm?

Câu trả lời:


5

Bạn có thể thực hiện công việc này thông qua các sự kiện / quan sát viên tiêu chuẩn:

<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>

Và 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;
    }

}

Ở đây tôi đã sử dụng mô hình Thay đổi để lưu mọi thay đổi vào DB. Và bạn có thể tạo lưới quản trị để xem các thay đổi được theo dõi trên bảng điều khiển.


Đây là một câu trả lời thực sự tốt nhưng có một vấn đề nhỏ: tôi cần lấy sản phẩm sau khi chúng đã được lưu. Các thay đổi được ghi lại có thể được sử dụng tải các sản phẩm trong công việc định kỳ nhưng công việc định kỳ chỉ chạy mỗi vài phút. Các thay đổi cũng có thể được xử lý trong control_front_send_response_after (ngay cả khi không lưu trữ chúng vào db) nhưng tôi nghĩ đây sẽ là một giải pháp xấu.
Wienczny

Tôi không thể tưởng tượng những gì bạn thực sự muốn. Nếu bạn muốn theo dõi các thay đổi sản phẩm thông qua công việc định kỳ, bạn cũng có thể thực hiện việc này, nhưng bạn cũng cần có bảng bổ sung để lưu trữ các giá trị cũ và giá trị mới, nếu bạn muốn theo dõi một vài thuộc tính, bạn chỉ có thể chụp nhanh mỗi giai đoạn cụ thể và so sánh một ảnh chụp nhanh với ảnh chụp nhanh mới, thông qua cách này bạn có thể phát hiện các thay đổi. Nhưng bạn muốn theo dõi toàn bộ thuộc tính, sẽ phức tạp hơn và tốn kém hơn để lưu trữ các thay đổi.
mageUz

Và cách đơn giản là tính mã băm của sản phẩm dựa trên các thuộc tính bạn muốn theo dõi. Ví dụ:. $ hash = md5 ($ sản phẩm-> getName (). $ sản phẩm-> getprice (). $ sản phẩm-> getSomeValueYouWantToTrack ()); if ($ sản phẩm-> getHashCode ()! = $ hash) {// sản phẩm có thay đổi, hãy thực hiện một số logic}; $ sản phẩm-> setHashCode ($ băm) -> save ()
mageUz

Tôi không muốn theo dõi thay đổi sản phẩm nhưng thay đổi sản phẩm. Các sản phẩm thay đổi cần được đồng bộ hóa với dịch vụ bên ngoài.
Wienczny

Xem câu trả lời cuối cùng mới của tôi được đưa ra ở trên
mageUz

4

Bằng cách quan sát catalog_product_attribution_update_b Before do mageUz đưa lên, bạn có thể lưu trữ các thực thể bị ảnh hưởng được tham chiếu bởi sự kiện dưới dạng Product_ids:

Bởi Zend_Debug :: kết xuất $ observer-> getEvent () -> getData () nơi tôi đã xử lý catalog_product_attribution_update_b Before tôi đã nhận được:

mảng (4) {
  ["Properties_data"] => & mảng (1) {
    ["trạng thái"] => int (1)
  }
  ["Product_ids"] => & mảng (2) {
    [0] => chuỗi (6) "159340"
    [1] => chuỗi (6) "159339"
  }
  ["store_id"] => & int (0)
  ["name"] => chuỗi (39) "catalog_product_attribution_update_b Before"
}

Ví dụ, bạn có thể lưu trữ những entity_ids đó trong singleton phiên Magento.

Sau đó, quan sát end_ process_event_catalog_product_mass_action , đây là một trong những sự kiện được xây dựng động của Magento. Xử lý sẽ cho bạn biết khi thay đổi sản phẩm hoàn tất cho phép bạn có được trạng thái sản phẩm được cập nhật. Vì nó không chứa dữ liệu nên bạn sẽ cần những thực thể mà bạn vừa lưu trữ.


0

Tôi đã nhận xét logic thích hợp cho tình huống của bạn. Nhưng để hiểu bạn, tôi cung cấp thêm mã:

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();
        }
    }
}
}

Và cron của bạn sử dụng logic này để đồng bộ hóa sản phẩm của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.