web-dev-qa-db-ja.com

Magentoリクエスト-フロントエンドまたはバックエンド?

現在のリクエストがバックエンドページであるかフロントエンドページであるかを確認するにはどうすればよいですか?このチェックはオブザーバーの内部で行われるため、それが役立つ場合はリクエストオブジェクトにアクセスできます。

Mage::getSingleton('admin/session')->getUser()をチェックすることを検討しましたが、これは非常に信頼できる方法だとは思いません。より良い解決策を期待しています。

22
Colin O'Dell

これは良い答えが得られない分野の1つです。 Magento自体は、この情報のための明示的なメソッド/ APIを提供していません。そのため、ソリューションを使用する場合は、環境を調べて物事を推測する必要があります。

使っていた

Mage::app()->getStore()->isAdmin()

しばらくの間、そうではない特定の管理ページ(Magento Connect Package Manager)があることがわかりました。何らかの理由で、このページはストアIDを明示的に1に設定し、isAdminをfalseとして返します。

#File: app/code/core/Mage/Connect/controllers/Adminhtml/Extension/CustomController.php
public function indexAction()
{
    $this->_title($this->__('System'))
         ->_title($this->__('Magento Connect'))
         ->_title($this->__('Package Extensions'));

    Mage::app()->getStore()->setStoreId(1);
    $this->_forward('edit');
}

この動作をする他のページがあるかもしれません、

別の良い策は、デザインパッケージの "area"プロパティをチェックすることです。

エリアは管理エリアのデザインテンプレートとレイアウトXMLファイルへのパスに影響を与えるため、これは管理ページにあるページでオーバーライドされる可能性は低いようです。

環境から何を推測するかに関係なく、新しいMagentoモジュールを作成し、それにヘルパークラスを追加します。

class Namespace_Modulename_Helper_Isadmin extends Mage_Core_Helper_Abstract
{
    public function isAdmin()
    {
        if(Mage::app()->getStore()->isAdmin())
        {
            return true;
        }

        if(Mage::getDesign()->getArea() == 'adminhtml')
        {
            return true;
        }

        return false;
    }
}

そして、あなたが管理者であるかどうかを確認する必要があるときはいつでも、このヘルパーを使用してください

if( Mage::helper('modulename/isadmin')->isAdmin() )
{
    //do the thing about the admin thing
}

このようにして、管理者チェックロジックに穴が見つかった場合や、1つの場所ですべてを修正できます。

59
Alan Storm

オブザーバーを使用できる場合は、「adminhtml」イベント領域に制限できます。

<config>
...
  <adminhtml>
    <events>
      <core_block_abstract_prepare_layout_after>
        <observers>
          <mynamespace_mymodule_html_before>
            <type>singleton</type>
            <class>mynamespace_mymodule/observer</class>
            <method>adminPrepareLayoutBefore</method>
          </mynamespace_mymodule_html_before>
        </observers>
      </core_block_abstract_prepare_layout_after>
    </events>
  </adminhtml>
</config>
14
beeplogic

使用するMage/Core/Model/Store.php内のメソッドをご覧ください。

Mage::app()->getStore()->isAdmin()

とともに

Mage::getDesign()->getArea() == 'adminhtml'

ストアIDが期待どおりに設定されていないフォールバックとして機能する(Magento接続など)

11

ビープロジックの答えが好きです。オブザーバーのコンテキストでは理にかなっています。私はまた、すべてのコンテキストで管理状態を知る方法がないというAlanのポイントも気に入っています。これは、「管理者」の機能であり、アプリとフロントコントローラーが初期化された後に入る状態です。

Magentoの管理状態は、コントロールディスパッチから管理アクションコントローラーに効果的に作成されます。 Mage_Adminhtml_Controller_Action::preDispatch()を参照してください。これは、_adminhtml_controller_action_predispatch_start_イベントを発生させるメソッドで、Mage_Adminhtml_Model_Observer::bindStore()によって消費されます。これは、管理ストアが最初に「設定」されている場所です。実際、オブザーバー設定領域(adminhtmlとフロントエンド)は、メインアクションコントローラークラスのために「機能します」-Mage_Core_Controller_Varien_Action::preDispatch()、特にMage::app()->loadArea($this->getLayout()->getArea());を参照-レイアウトオブジェクトにその領域があることに注意してくださいadminhtml事前ディスパッチで設定された情報。

どのようにスライスするかに関係なく、非常に多くのコンテキストで依存している管理動作(イベントオブザーバーシステムと同じくらい高レベルのものでも)は、コマンド制御構造に依存しています。

_<config>
  <!-- ... -->
  <adminhtml>
    <events>
      <core_block_abstract_prepare_layout_after>
        <observers>
          <mynamespace_mymodule_html_after>
            <type>singleton</type>
            <class>mynamespace_mymodule/observer</class>
            <method>adminPrepareLayoutAfter</method>
          </mynamespace_mymodule_html_after>
        </observers>
      </core_block_abstract_prepare_layout_after>
    </events>
  </adminhtml>
  <frontend>
    <events>
      <core_block_abstract_prepare_layout_after>
        <observers>
          <mynamespace_mymodule_html_after>
            <type>singleton</type>
            <class>mynamespace_mymodule/observer</class>
            <method>frontendPrepareLayoutAfter</method>
          </mynamespace_mymodule_html_after>
        </observers>
      </core_block_abstract_prepare_layout_after>
    </events>
  </frontend>
</config>
_

あなたのオブザーバー定義では:

_class Mynamepace_Mymodule_Model_Observer
{
    public function adminPrepareLayoutAfter()
    {
        $this->_prepareLayoutAfter('admin');
    }

    public function frontendPrepareLayoutAfter()
    {
        $this->_prepareLayoutAfter('frontend');
    }

    protected function _prepareLayoutAfter($area)
    {
        switch($area){
           case 'admin':
               // do admin things
               break;

           case 'frontend':
               // do frontend things
               break;

           default:
               // i'm a moron
        }
    }
}
_

tl; dr:オブザーバーを使用します。同じオブザーバーモデルを使用しますが、別の呼び出しメソッドを指定してコンテキストで渡します。

HTH。

編集:ビープロジックの設定を開始点として使用するサンプルコードを追加

5
benmarks

私が間違っているかどうかにかかわらず(ただし、テストしました)、一部のイベント(controller_front_init_beforeなど)はグローバルノード内でのみ上書きできます。その結果、このオーバーライドはフロントエンドとバックエンドの両方に影響します。

次に、Alanとbenmarkの解決策を利用して、フロントエンドのみまたはバックエンドのみにオブザーバーを適用するかどうかを指定します。

0
user1576748