Bon sang, je m'aime un peu, mais je dois être en désaccord avec la complexité / fragilité du transport des paramètres de la tâche et de la zone ( adminhtml | crontab | frontend | global | install ) vers une file d'attente, surtout si cette file d'attente doit être en cours d'exécution un contexte Magento. S'il existe des contextes mixtes qui doivent être traités, la solution de file d'attente est une réimplémentation du "problème" actuel!
Je pense que l'approche de la file d'attente est fragile. Mon argument est que le chargement prématuré des zones d'événements n'est pas vraiment un problème. Pour expliquer cela, revenons en arrière et examinons le problème:
Quel est le danger de charger prématurément une zone d'événements dans une étendue d'exécution?
Pour comprendre cela, nous devons examiner les zones d'événements dans le contexte d'exécution. Matthias, j'imagine que vous le savez déjà, mais pour l'édification des autres:
Les scripts de configuration des données sont exécutés Mage_Core_Model_App::run()
avant d'envoyer la demande au contrôleur frontal:
public function run($params)
{
$options = isset($params['options']) ? $params['options'] : array();
$this->baseInit($options);
Mage::register('application_params', $params);
if ($this->_cache->processRequest()) {
$this->getResponse()->sendResponse();
} else {
$this->_initModules();
//Global event area is loaded here
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
if ($this->_config->isLocalConfigLoaded()) {
$scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
$scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
$this->_initCurrentStore($scopeCode, $scopeType);
$this->_initRequest();
//Data setup scripts are executed here:
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
$this->getFrontController()->dispatch();
}
return $this;
}
Au moment où les scripts de configuration des données s'exécutent, la zone d'événements globale est chargée. Les zones d'événements contextuelles de routage ( frontend ou adminhtml ) sont chargées plus tard à Mage_Core_Controller_Varien_Action::preDispatch()
la suite de la correspondance du routeur avec une action du contrôleur (le area
nom est défini via l'héritage):
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
Ainsi, normalement lors de l'initialisation de l'application, seuls les observateurs configurés sous la zone d'événement global seront exécutés. Si le script de configuration fait quelque chose comme
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
alors il n'y a que deux dangers:
- Un observateur a été mal configuré sous adminhtml pour observer un événement sans contexte tel que
controller_front_init_before
oucontroller_front_init_routers
- La demande est une demande frontale .
# 1 devrait être facile à comprendre. # 2 est la vraie préoccupation, et je pense que la réflexion peut résoudre le problème (notez que je suis terriblement inexpérimenté avec la réflexion):
<?php
//Start setup script as normal
$installer = $this;
$installer->startSetup()
//Load adminhtml event area
Mage::app()->loadAreaPart(
Mage_Core_Model_App_Area::AREA_ADMINHTML,
Mage_Core_Model_App_Area::PART_EVENTS
);
// your setup script logic here
//I hope this isn't a bad idea.
$reflectedApp = new ReflectionClass('Mage_Core_Model_App');
$_areas = $reflectedApp->getProperty('_areas');
$_areas->setAccessible(true);
$areas = $_areas->getValue(Mage::app());
unset($areas['adminhtml']);
$_areas->setValue(Mage::app(),$areas); //reset areas
//End setup script as normal
$installer->endSetup()
Je n'ai pas testé cela, mais cela supprime l'index des événements adminhtml et l' Mage_Core_Model_App_Area
objet correspondant .