События и наблюдатели в 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.

Author: Abinaya, 2014-05-15

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.

 2
Author: David Manners, 2014-05-15 09:07:06