Magento: добавление обсервера «на лету»

magentoКак то раз, при разработке кастомного функционала для Magento, я столкнулся с необходимостью расширения дефолтного грида (добавление новой колонки). Задача в целом тривиальная, но загвоздка была в том, что грид подгружался по требованию аяксом. Делать оверрайд класса грида мне не хотелось, и я начал копать как это лучше сделать с помощью обсервера, чтобы не вызывать его каждый раз, когда файрится ивент adminhtml_block_html_before. Оказалось, для решения такой задачи есть небольшая хитрость, а именно — добавление обсервера «на лету». Для этого нам нужно создать вот такой метод:

/**
* Add observer to specific event
*
* @param string $area
* @param string $eventName
* @param string $observerName
* @param string $observerClass
* @param string $observerMethod
* @param boolean $top
* @return Vendor_Module_Helper_Observer
*/
public function addObserver($area, $eventName, $observerName, $observerClass, $observerMethod, $top = false)
{
$eventConfig = Mage::getConfig()->getEventConfig($area, $eventName);
if (!$eventConfig) {
    $eventConfig = Mage::getConfig()->getNode($area)->events->addChild($eventName);
}

if (isset($eventConfig->observers)) {
    $eventObservers = $eventConfig->observers;
} else {
    $eventObservers = $eventConfig->addChild('observers');
}

$currentObserversCount = count($eventObservers->children());
$observer = $eventObservers->addChild($observerName);

if ($top && $currentObserversCount) {
    $targetDom = dom_import_simplexml($eventObservers);
    $domObserver = $targetDom->ownerDocument->importNode(dom_import_simplexml($observer), true);
    $targetDom->insertBefore($domObserver, $targetDom->firstChild);
}

$observer->addChild('class', $observerClass);
$observer->addChild('method', $observerMethod);

return $this;
}

Создать его можно где нибудь в хелпере, как удобно. Затем нам нужно создать обсервер для контроллера, который дергается аяксом. В идеале — на предиспатче. Затем, в этом обсервере мы вызываем наш новый метод, и создаем динамический обсервер на событие adminhtml_block_html_before. Таким образом, наш обсервер будет отрабатывать только при вызове конкретного контроллера.

Есть важный нюанс — добавлять динамический обсервер нужно ДО того как ивент вызывается первый раз, потому что обсерверы после этого кэшируются.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s