События и наблюдатели в Magento
В app/code/core/Mage/Customer/conrtrollers/AccountController.php существует
Mage::dispatchEvent('customer_register_success',
array('account_controller' => $this, 'customer' => $customer)
);
Как этот код события, т.е. customer_register_success, запускается в magento при вызове dispatchEvent.
1 answers
Если вы посмотрите на функцию dispatchEvent
в классе Mage_Core_Model_App
, вы увидите, что код работает следующим образом:
ПРИМЕЧАНИЕ: для этого примера я буду использовать событие controller_front_init_routers
просто потому, что это часто случается и с помощью него легче пройти через код
Во-первых, происходит то, что все наблюдатели, настроенные в конфигурации, загружаются в массив формата:
$observers['observer_name'] = array(
'type' => 'observer_type,
'model' => 'observer_model',
'method'=> 'method_to_call',
'args' => 'arguments_array',
);
Это соответствует способу определения наблюдателя с помощью xml следующим образом.
<events>
<event_name>
<observers>
<observer_name>
<type>observer_type</type>
<class>observer_model</class>
<method>method_to_call</method>
</observer_name>
</observers>
</event_name>
</events>
Для в нашем примере массив выглядит следующим образом.
array(1) {
["cms"]=>
array(4) {
["type"]=>
string(0) ""
["model"]=>
string(26) "Mage_Cms_Controller_Router"
["method"]=>
string(21) "initControllerRouters"
["args"]=>
array(0) {
}
}
}
Затем происходит то, что функция dispatchEvent проверяет, прослушивает ли событие, которое мы хотим отправить, что-то. Если это не так, то он не будет продолжаться дальше, но когда это произойдет, он продолжит создавать объект события и объект наблюдателя.
Затем он перебирает всю сохраненную информацию о событии, устанавливает аргументы данных и вызывает нужный метод для нужного объекта. Обратите внимание, что по умолчанию модель загружена как синглтон.
foreach ($events[$eventName]['observers'] as $obsName=>$obs) {
$observer->setData(array('event'=>$event));
Varien_Profiler::start('OBSERVER: '.$obsName);
switch ($obs['type']) {
case 'disabled':
break;
case 'object':
case 'model':
$method = $obs['method'];
$observer->addData($args);
$object = Mage::getModel($obs['model']);
$this->_callObserverMethod($object, $method, $observer);
break;
default:
$method = $obs['method'];
$observer->addData($args);
$object = Mage::getSingleton($obs['model']);
$this->_callObserverMethod($object, $method, $observer);
break;
}
Varien_Profiler::stop('OBSERVER: '.$obsName);
}
И последнее, что происходит, это то, что функция _callObserverMethod
проверяет, существует ли нужный метод, а когда его нет, она выдает исключение.
Итак, для нашего примера мы будем использовать модель Mage_Cms_Controller_Router
и метод initControllerRouters
.