Maldita sea, me encanta un poco de philwinkle, pero tengo que estar en desacuerdo con la complejidad / fragilidad de transportar los parámetros de la tarea y el área ( adminhtml | crontab | frontend | global | install ) a una cola, especialmente si esa cola se va a ejecutar Un contexto de Magento. Si hay contextos mixtos que necesitan ser manejados, entonces la solución de la cola es una reimplementación del "problema" actual.
Creo que el enfoque de la cola es frágil. Mi argumento es que cargar áreas de eventos prematuramente no es realmente un problema en absoluto. Para explicar esto, retrocedamos y veamos el problema:
¿Cuál es el peligro de cargar un área de evento prematuramente en un ámbito de ejecución?
Para comprender esto, debemos examinar las áreas de eventos en el contexto de ejecución. Matthias, imagino que ya lo sabes, pero para la edificación de otros:
Los scripts de configuración de datos se ejecutan Mage_Core_Model_App::run()
antes de enviar la solicitud al controlador 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;
}
Para cuando se ejecutan los scripts de configuración de datos , se carga el área de evento global . Las áreas de eventos contextuales de enrutamiento ( frontend o adminhtml ) se cargan más adelante Mage_Core_Controller_Varien_Action::preDispatch()
como resultado de que el enrutador coincida con una acción del controlador (el area
nombre se establece por herencia):
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
Por lo tanto, normalmente durante la inicialización de la aplicación, solo se ejecutarán los observadores configurados en el área de evento global . Si el script de configuración hace algo como
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
entonces solo hay dos peligros:
- Un observador se configuró incorrectamente en adminhtml para observar un evento sin contexto como
controller_front_init_before
ocontroller_front_init_routers
- La solicitud es una solicitud de interfaz .
# 1 debería ser fácil de conseguir. # 2 es la verdadera preocupación, y creo que Reflection puede resolver el problema (tenga en cuenta que lamentablemente no tengo experiencia con el uso de la reflexión):
<?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()
No he probado esto, pero elimina el índice de eventos adminhtml y el Mage_Core_Model_App_Area
objeto correspondiente .