Magento Request - Frontend or Backend?

后端 未结 5 1935
臣服心动
臣服心动 2020-12-29 05:31

How can I tell if the current request is for a backend or frontend page? This check will be done inside an observer, so I do have access to the request object if that helps

相关标签:
5条回答
  • 2020-12-29 05:33

    If you're able to use an observer, you can limit it to the 'adminhtml' event area.

    <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>
    
    0 讨论(0)
  • 2020-12-29 05:40

    This is one of those areas where there's no good answer. Magento itself doesn't provide an explicit method/API for this information, so with any solution you'll need to examine the environment and infer things.

    I was using

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

    for a while, but it turns out there are certain admin pages (the Magento Connect Package manager) where this isn't true. For some reason this page explicitly sets the store id to be 1, which makes isAdmin return as 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');
    }
    

    There may be other pages with this behavior,

    Another good bet is to check the "area" property of the design package.

    This seems less likely to be overridden for a page that's in the admin, since the area impacts the path to the admin areas design templates and layout XML files.

    Regardless of what you choose to infer from the environment, create new Magento module, and add a helper class to it

    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;
        }
    }
    

    and then whenever you need to check if you're in the admin, use this helper

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

    This way, when/if you discover holes in your admin checking logic, you can correct everything in one centralized place.

    0 讨论(0)
  • 2020-12-29 05:46

    Have a look at the methods inside Mage/Core/Model/Store.php you'll want to use:

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

    In conjunction with

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

    To act as a fallback where the store ID isn't set as you expect (Magento connect etc.)

    0 讨论(0)
  • 2020-12-29 05:49

    I like beep logic's answer - it makes sense in the context of observers. I also like Alan's point that there is no way to know the admin state in all contexts, which is a function of "the admin" being a state which is entered after the app and front controller are initialized.

    Magento's admin state is effectively created from the control dispatching to an admin action controller; see Mage_Adminhtml_Controller_Action::preDispatch(). This is the method which fires the adminhtml_controller_action_predispatch_start event, which is consumed by Mage_Adminhtml_Model_Observer::bindStore(), which is where the admin store is initially "set". In fact, the observer configuration areas (adminhtml vs frontend) "works" because of the main action controller class - see Mage_Core_Controller_Varien_Action::preDispatch(), specifically Mage::app()->loadArea($this->getLayout()->getArea()); - just note that the layout object has its area information set in the adminhtml predispatch.

    No matter how you slice it, the admin behavior on which we rely in so many contexts - even something as high-level as the event observer system - relies on the command control structure.

    <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>
    

    In your observer definition:

    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: Use an observer, even use the same observer model, but pass in the context by specifying a different calling method.

    HTH.

    edit: added example code using beep logic's config as a starting point

    0 讨论(0)
  • 2020-12-29 05:49

    Whether I'm wrong or not (but I've tested it), some events (like controller_front_init_before) can only be overwritten inside global node. As a result, this override will affect both frontend and backend.

    Then come Alan's and benmark's solution to the rescue to specify if you want to apply the observer on frontend only or backend only.

    0 讨论(0)
提交回复
热议问题