アップグレードスクリプトを実行する場合、現在のストアは1です


15

Mage::app()->getStore()アップグレードスクリプトを実行しているストアビューから独立したアップグレードスクリプト内で(管理者でも)ID 1のストアビューを返す理由は何ですか?
つまり、これを行うコードがどこにあるかを知っています。これMage_Core_Model_App::getStore()には:

    if (!Mage::isInstalled() || $this->getUpdateMode()) {
        return $this->_getDefaultStore();
    }

そして_getDefaultStore次のようになります。

   if (empty($this->_store)) {
        $this->_store = Mage::getModel('core/store')
            ->setId(self::DISTRO_STORE_ID)
            ->setCode(self::DISTRO_STORE_CODE);
    }
    return $this->_store;

$this->_store 上記のメソッドに到達すると、常に空になります。

アップグレードスクリプトの先頭にこれを追加しても、同じ結果が得られます。

Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));

この「機能」を持つビジネスロジックに興味があります。


アップグレードスクリプトは常にフロントエンドスコープで実行されていると思いました。多くの場合、次の行に管理ストアを使用するように明示的にアップグレードスクリプトに指示します。
bukart

@bukart。アップグレードスクリプトに明示的に管理ストアビューを実行するように指示しようとしましたが、同じ結果が得られます。質問の最後の3行を参照してください。
マリウス

以下の質問に答えようとしました
bukart 14

回答:


5

注:ディスパッチが行われ、コントローラーの拡張がMage_Adminhtml_Controller_Action実行されるまで、管理ストアのスコープが設定されないことを忘れないでください(adminhtml_controller_action_predispatch_startイベントと関連するオブザーバーを参照してくださいMage_Adminhtml_Controller_Action::preDispatch())。

この「機能」を持つビジネスロジックに興味があります。

あなただけではありません。とはいえ、MosheまたはDimaが議論を望まない限り、私たちは決して知らないかもしれません。

セットアップスクリプトは、アプリケーションの初期化の初期段階で実行されます。これはおそらく、スタックの残りの部分が実行されるまでに必要な移行やその他の作業が「完了」するように設計されているためです。つまり、モジュールをインストールしてもシステムはすぐに使用できます。またはアップグレードされました。元建築士が最初にこれまで以上に初期化されたシステムの必要性があるだろうと思った場合、私は思ったんだけど。 コードの多くは使用可能なストアインスタンスがあることを前提としているのに対し、_getDefaultStore()ロジックはストアインスタンスがあることを保証すると推測します。

全範囲の設定は、データのセットアップスクリプトを経由して1.4.0.0及びアップでご利用いただけます。


3

OK、アップグレードスクリプトで管理ストアを使用するには、

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

あなたのアプローチMage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); は成功できません。管理者用の既存のロード可能なストアビューが存在しないためです。

多くの場合、次のようなパターンを使用します。

// remembering old current store
$currentStore = Mage::app()->getCurrentStore();

// switching to admin store
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

// switching back to old current store
Mage::app()->setCurrentStore($currentStore->getStoreId());

そうしないと、アップグレードスクリプトの実行後に、訪問者がフロントエンドではなく管理ページにリダイレクトされることがあります。


更新:

以下の質問を誤って解釈したので、ここで新しい説明を試みます^^

アップグレードスクリプトは、コアのより深いメソッドから呼び出されます(Mage_Core_Model_Resource_Setup::_modifyResourceDb(...)

ここでスタックをリストしようとしました

  • Mage_Core_Model_App::run($params)

  • Mage_Core_Model_App::_initModules()

  • Mage_Core_Model_Resource_Setup::applyAllUpdates()

  • Mage_Core_Model_Resource_Setup::applyUpdates()

  • Mage_Core_Model_Resource_Setup::_upgradeResourceDb($oldVersion, $newVersion)

  • Mage_Core_Model_Resource_Setup::_modifyResourceDb($actionType, $fromVersion, $toVersion)

そして今、見てみましょうMage_Core_model_App::run($params)

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();
        $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();
            Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
        }

        $this->getFrontController()->dispatch();
    }
    return $this;
}

この方法は、_initModules()前に呼び出され$scopeCode$scopeType判断されます。

現在、想定されるフォールバックがどこで定義されているのかわかりません。


ああ、でも管理者用のロード可能なストアビューがあります。で見てとるcore_storeテーブルを。idのレコードがあり0ます。また、これを試すとvar_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID))、管理ストアの有効なインスタンスが取得されます。試してみましたMage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);が、同じ結果が得られます。しかし、私の質問は、アップグレードスクリプトで管理ストアを設定する方法についてはなかったです。Mage::app()->getStore()アップグレードスクリプトでid 1のストアを返す理由を尋ねていました。
マリウス

ああ...そうです...確かに、データベースに管理ストアがあります。
ブカート14

1
うーん...私はスタックを知っていましたが、あなたの答えでそれを見たので、それは私に当たりました。更新は何らかの形で「ステートレス」に実行されるはずです。しかし、何かを実行するには、ストアが必要です。したがって、ストアのデフォルト値。意味をなさない唯一のものは次のとおりです。なぜこのデフォルトストアは0(admin)ではなく、管理UIから簡単に削除できるストアビューであるのですか?目を開けて+1。これに関して他の明確な答えが得られない場合、これを受け入れます。
マリウス

mhh ...良い質問...昼食の後、多分見てみよう...
興味深い

1.9.3.6の時点でMage::app()->getCurrentStore();は、定義されていないようで、呼び出されると致命的なエラーが発生します。代わりに、私が使用してIDを得ました$currentStoreId = Mage::app()->getStore()->getId();
エリックイーストランド

2

したがって、基本的な答えは、実際に3番目に入る場合です。

if (!isset($id) || ''===$id || $id === true) {
    $id = $this->_currentStore;
}

私にとっては、trueを返しMage::isInstalled()、falseを$this->getUpdateMode()間違って聞こえます。しかし、これはの最初のヒットでのみ発生しgetStoreます。

そのため、更新モードが設定される前にストアをセットアップし、セットアップスクリプトに戻ったときに、次のコードを使用するデフォルトのストアコールを使用しているように見えます。

$this->_store = Mage::getModel('core/store')
    ->setId(self::DISTRO_STORE_ID)
    ->setCode(self::DISTRO_STORE_CODE);

の値self::DISTRO_STORE_IDは1で、何かを必要とし、管理者ストアにセットアップされていなかったと思われます:(

そのため、実際にはID 1のストアを持たないシステムがあり、更新スクリプトはうまく機能しているように見えます。テーブル/属性を追加する場合は問題ありません。サイト固有のcmsブロックを追加する場合でもこれは機能しますが、すべてのストアIDを取得し、ストア固有のデータを保存するときに具体的に設定します。


同じことを掘り下げました。私が理解していないのは、「Magentoなぜアップグレードに管理ストアを使用しないのですか?」です。それはより合理的です。私は、ID 1とストアを削除した場合、何が起こるか考えることが怖い
マリウス

デフォルトのストアを削除するほどクレイジーな人はいません;)
デビッドマナー14

これを知った今、私は夢中になることはありませんが、それが可能であるという事実は...まあ...決してユーザーを信頼しないでください。
マリウス

私たちのPMの1人が、先週古い店を削除できるかどうかを尋ねました。私は、「何が起こる可能性が最悪だ」と答えたと思います....そして、さらに奇数当社の現在のプロジェクトの設定では、我々は、ID 1とは店舗を持っていない:(表でcore_storeスクリプトが動作しているが、セットアップ
デヴィッド・マナー

1
ストアスコープがMage_Core_Model_App :: DISTRO_STORE_CODEにロックされていないデータアップグレード(インストールではない)スクリプトでcmsブロックを追加する必要があります。より一般的には、インストールスクリプトを使用してデータ構造を変更し(ストアスコープをロック)、データアップグレードを使用してデータコンテンツを変更します(ストアスコープはスクリプト中に変更できます)
アレッサンドロロンチ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.