Sialan, saya suka saya beberapa filwinkle, tapi saya harus tidak setuju dengan kompleksitas / kerapuhan mengangkut parameter tugas dan area ( adminhtml | crontab | frontend | global | install ) ke antrian, terutama jika antrian itu akan mengeksekusi konteks Magento. Jika ada konteks campuran yang perlu penanganan maka solusi antrian adalah implementasi ulang dari "masalah" saat ini!
Saya pikir pendekatan antrian rapuh. Argumen saya adalah bahwa memuat area acara secara prematur bukan masalah sama sekali. Untuk menjelaskan ini, mari kita kembali dan melihat masalahnya:
Apa bahayanya memuat area acara secara prematur dalam lingkup eksekusi?
Untuk memahami ini kita harus memeriksa area acara dalam konteks eksekusi. Matthias, saya membayangkan Anda sudah mengetahui hal ini, tetapi untuk peneguhan orang lain:
Skrip pengaturan data dieksekusi Mage_Core_Model_App::run()
sebelum mengirim permintaan ke 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;
}
Pada saat skrip pengaturan data mengeksekusi area acara global dimuat. Area acara perutean-kontekstual ( frontend atau adminhtml ) dimuat di kemudian hari Mage_Core_Controller_Varien_Action::preDispatch()
sebagai hasil dari pencocokan router dengan tindakan pengontrol ( area
namanya diatur melalui pewarisan):
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
Jadi biasanya selama inisialisasi aplikasi hanya pengamat yang dikonfigurasi di bawah area acara global yang akan dieksekusi. Jika skrip pengaturan melakukan sesuatu seperti
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
maka hanya ada dua bahaya:
- Seorang pengamat telah salah konfigurasi di bawah adminhtml untuk mengamati peristiwa tanpa konteks seperti
controller_front_init_before
ataucontroller_front_init_routers
- Permintaan adalah permintaan frontend .
# 1 seharusnya mudah dipahami. # 2 adalah masalah nyata, dan saya pikir Refleksi dapat menyelesaikan masalah (perhatikan bahwa saya tidak berpengalaman menggunakan refleksi):
<?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()
Saya belum menguji ini, tetapi itu menghapus indeks peristiwa adminhtml dan Mage_Core_Model_App_Area
objek yang sesuai .