Droga, eu amo algumas coisas, mas tenho que discordar da complexidade / fragilidade de transportar os parâmetros da tarefa e a área ( adminhtml | crontab | frontend | global | install ) para uma fila, especialmente se essa fila estiver em execução um contexto Magento. Se houver contextos mistos que precisam ser manipulados, a solução da fila é uma reimplementação do "problema" atual!
Eu acho que a abordagem da fila é quebradiça. Meu argumento é que carregar áreas de eventos prematuramente não é realmente um problema. Para explicar isso, vamos voltar e analisar o problema:
Qual é o perigo de carregar uma área de eventos prematuramente em um escopo de execução?
Para entender isso, devemos examinar as áreas de eventos no contexto de execução. Matthias, imagino que você já saiba disso, mas para a edificação de outras pessoas:
Os scripts de configuração de dados são executados Mage_Core_Model_App::run()
antes do envio da solicitação ao Front Controller:
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;
}
No momento em que os scripts de configuração de dados estão sendo executados, a área de eventos globais é carregada. As áreas de eventos contextuais de roteamento ( frontend ou adminhtml ) são carregadas posteriormente Mage_Core_Controller_Varien_Action::preDispatch()
como resultado do roteador correspondente a uma ação do controlador (o area
nome é definido por herança):
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
Portanto, normalmente durante a inicialização do aplicativo, apenas os observadores configurados na área de eventos globais serão executados. Se o script de instalação fizer algo como
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
então existem apenas dois perigos:
- Um observador foi configurado incorretamente em adminhtml para observar um evento sem contexto, como
controller_front_init_before
oucontroller_front_init_routers
- A solicitação é uma solicitação de front - end .
O número 1 deve ser fácil de saudar. O número 2 é a verdadeira preocupação, e acho que o Reflection pode resolver o problema (note que sou extremamente inexperiente em usar o reflexo):
<?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()
Eu não testei isso, mas ele remove o índice de eventos adminhtml e o Mage_Core_Model_App_Area
objeto correspondente .