Unregister событие наблюдатель программно
-
16-10-2019 - |
Вопрос
Кто -нибудь знает, можно ли программно нерегистрировать событие программно? У меня есть наблюдатель на newsletter_subscribe_save_after
Это обновляет пользовательский атрибут в модели клиента, но когда запись клиента сохраняется, он выходит из customer_save_after
событие определено в Mage_All.xml
который затем повторно заставляет статус подписки на бюллетень, приводящий к бесконечному циклу, который затем запускает ошибку рекурсии PHP из-за 100 раз гнездования.
В идеале я хотел бы перерегистрировать customer_save_after
Событие только тогда, когда мой наблюдатель стреляет.
Решение
Вы можете попытаться отметить свое мероприятие как dispatched
И во второй попытке запустить это, просто ничего не сделает, если он уже отправлен. Например, давайте скажем updateCustomer()
.
public function updateCustomer($observer){
if (Mage::registry('my_event_was_dispatched') == 1){//do nothing if the event was dispatched
return $this;
}
//your code here
Mage::register('my_event_was_dispatched', 1);//mark the event as dispatched.
}
Имя ключа реестра не важно, просто убедитесь, что вы используете один и тот же в обоих случаях.
Другие советы
Вы можете перерегистрировать мероприятие наблюдатель На лету программно следующим образом:
$area = Mage::app()->getStore()->isAdmin() ? 'adminhtml' : 'frontend';
foreach (array($area, 'global') as $branch) {
$path = $branch . '/events/customer_save_after/observers/your_module/type';
Mage::app()->getConfig()->setNode($path, 'disabled');
}
Вы не можете перерегистрировать само событие. Чтобы полностью деактивировать мероприятие, вам придется зацикливаться на всех детях $branch . '/events/customer_save_after/observers'
и деактивировать каждого.
Если это просто один конкретный метод наблюдателя, который вы не хотите снова запускать, вы можете установить его тип singleton
А затем просто используйте логическое свойство в качестве флага, чтобы проверить, называется ли оно уже один раз следующим образом:
class Your_Module_Model_Observer
{
private $_processFlag = false;
public function customerSaveAfter($data)
{
if (! $this->_processFlag) {
$this->_processFlag = true;
// do your thing with $customer->save()
}
}
}
Вот метод помощника проверки концепции, который переключает существующий наблюдатель. Если вы хотите отключить событие по умолчанию, добавьте <type>disabled</type>
к определению вашего наблюдателя. xml.
public function toggleObserver($area, $event, $name, $enable)
{
$app = Mage::app();
// reflection on the property Mage_Core_Model_App::_events
$class = new ReflectionClass(get_class($app));
$property = $class->getProperty('_events');
$property->setAccessible(true);
// get the events
$events = $property->getValue($app);
// make sure the event config is loaded
if (!isset($events[$area][$event]))
{
// load observers from config
/** @see Mage_Core_Model_App::dispatchEvent() */
$config = $app->getConfig()->getEventConfig($area, $event);
if (!$config)
{
// event is not configured
return;
}
// create observers array
$observers = array();
foreach ($config->observers->children() as $name => $values)
{
$observers[$name] = array(
'type' => (string) $values->type,
'model' => $values->class ? (string) $values->class : $values->getClassName(),
'method'=> (string) $values->method,
'args' => (array) $values->args,
);
}
$events[$area][$event]['observers'] = $observers;
}
if ($events[$area][$event] && isset($events[$area][$event]['observers'][$name]))
{
// enable/disable the observer by changing its type
$events[$area][$event]['observers'][$name]['type'] = $enable ? '' : 'disabled';
// update the object
$property->setValue($app, $events);
}
}
Функция использует отражение для доступа к защищенным иным образом защищенным $_events
свойство Mage_Mage_Core_Model_App
. Анкет Тот же трюк может быть использован для введения ранее неопределенных наблюдателей.