くそー、私は私にいくつかのツルニチニチソウが大好きですが、タスクのパラメーターと領域の輸送の複雑さ/脆弱性に同意する必要があります( adminhtml | crontab | frontend | global | install)をキュー、特にそのキューが実行されること必要がありますMagentoコンテキスト。処理が必要な混合コンテキストがある場合、キューソリューションは現在の「問題」の再実装です。
キューのアプローチは脆弱だと思います。私の主張は、イベントエリアを時期尚早にロードすることは本当に問題ではないということです。これを説明するために、バックアップして問題を見てみましょう。
実行スコープでイベント領域を時期尚早にロードする危険性は何ですか?
これを理解するには、実行コンテキストのイベント領域を調べる必要があります。マティアス、あなたはすでにこれを知っていると思いますが、他の人の啓発のために:
データ設定スクリプトはで実行されます Mage_Core_Model_App::run()
、リクエストをフロントコントローラーにディスパッチする前にます。
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;
}
データセットアップスクリプトが実行されるまでに、グローバルイベントエリアがロードされます。ルーティングコンテキストイベントエリア(frontendまたはadminhtml)は後でロードされますMage_Core_Controller_Varien_Action::preDispatch()
、コントローラーアクションと一致するルーターの結果としてます(area
名前は継承によって設定されます)。
public function preDispatch()
{
//...
Mage::app()->loadArea($this->getLayout()->getArea());
//...
}
だから普通はアプリの初期化中に、グローバルイベントエリアで設定されたオブザーバーのみが実行されます。セットアップスクリプトが次のようなことを行う場合
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);
次に、2つの危険のみがあります。
- オブザーバーが下で誤って設定されています adminhtmlの、
controller_front_init_before
またはcontroller_front_init_routers
- リクエストは フロントエンド要求です。
#1は簡単にgrepできるはずです。#2が真の関心事であり、Reflectionは問題を解決できると思います(私はリフレクションの使用に非常に不慣れであることに注意してください):
<?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()
これはテストしていませんが、adminhtmlイベントインデックスと対応するMage_Core_Model_App_Area
オブジェクトは削除されます。