Magento EDA系统如何避免事件循环


Magento EDA system how to avoid event loop?

我正试图在事件后挂接catalog_product_save_after。这是config.xml

<events>
   <catalog_product_save_after>
     <observers>
       <observer_name_here>
         <class>My_Class_Model_Observer</class>
         <method>methodToCall</method>
         <type>singleton</type>
       </observer_name_here>
     </observers>
   </catalog_product_save_after>
</events>

下面是运行在methodToCall()中的代码:

$product = Mage::getModel('catalog/product')->load(1);
$product->setName('TESTING 123');
$product->save();


问题是
当事件catalog_product_save_after被激发时。用methodToCall()编写的代码再次触发catalog_product_save_after。并且根据Magento EDA系统再次调用methodToCall(),再次触发catalog_product_save_after。因此,系统陷入了一系列的发射和监听同一事件。

我的问题:

  1. 如何避免这种情况
  2. 是否有任何方法可以出于临时目的禁用Magento事件调度功能(而无需重写Mage_Cor_Model_AppdispatchEvent方法(如果可能))
  3. 如果观察者激发了实例化观察者的同一事件,如何防止无限循环。就像上面的例子一样

如果必须使用新值,并且必须使用这些值更新另一个产品,则可以在事件之前观察catalog_product_save_b。您的配置看起来不错,下面是methodToCall函数的示例:

public function methodToCall(Varien_Event_Observer $observer)
{
    $event    = $observer->getEvent();
    $product  = $event->getProduct();
    if($product->hasDataChanges()) { //somethings changed
        $newName = $product->getName();
        $oldName = $product->getOrigData('name');
        //do stuff here
        //don't call $product->save() It WILL be saved. If you call save() you will create a loop
    }
}

我认为,从根本上讲,这可能是您用例的错误方法,我认为您可能应该考虑save_before。然而,我在过去看到人们使用Mage::注册表来实现这一点。

if(!Mage::Registry("somekey")) {
    Mage::Register("somekey", true);
    //LOGIC
}

现在,在这个例子中,"somekey"应该是特定的,而且可能也是特定于这个产品的,这样,如果你保存多个产品,它就不会影响它们。