我正试图在事件后挂接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。因此,系统陷入了一系列的发射和监听同一事件。
我的问题:
- 如何避免这种情况
- 是否有任何方法可以出于临时目的禁用Magento事件调度功能(而无需重写Mage_Cor_Model_App的dispatchEvent方法(如果可能))
- 如果观察者激发了实例化观察者的同一事件,如何防止无限循环。就像上面的例子一样
如果必须使用新值,并且必须使用这些值更新另一个产品,则可以在事件之前观察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"应该是特定的,而且可能也是特定于这个产品的,这样,如果你保存多个产品,它就不会影响它们。