简体   繁体   English

Magento请求 - 前端还是后端?

[英]Magento Request - Frontend or Backend?

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. 此检查将在观察者内部完成,因此如果有帮助,我可以访问请求对象。

I considered checking Mage::getSingleton('admin/session')->getUser() but I don't think that's a very reliable method. 我考虑过检查Mage::getSingleton('admin/session')->getUser()但我认为这不是一个非常可靠的方法。 I'm hoping for a better solution. 我希望有更好的解决方案。

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. Magento本身不为此信息提供显式方法/ API,因此对于任何解决方案,您都需要检查环境并推断事物。

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. 有一段时间了,但事实证明,某些管理页面(Magento Connect Package Manager)并非如此。 For some reason this page explicitly sets the store id to be 1, which makes isAdmin return as false. 由于某种原因,此页面显式将商店标识设置为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');
}

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. 对于管理员中的页面,这似乎不太可能被覆盖,因为该区域会影响管理区域设计模板和布局XML文件的路径。

Regardless of what you choose to infer from the environment, create new Magento module, and add a helper class to it 无论您选择从环境中推断出什么,都可以创建新的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;
    }
}

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. 这样,当您在管理检查逻辑中发现漏洞时,您可以在一个集中位置更正所有内容。

If you're able to use an observer, you can limit it to the 'adminhtml' event area. 如果您能够使用观察者,则可以将其限制为“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>

Have a look at the methods inside Mage/Core/Model/Store.php you'll want to use: 看看你想要使用的Mage/Core/Model/Store.php中的方法:

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.) 充当后备,其中商店ID未按预期设置(Magento连接等)

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. 我也很喜欢Alan的观点,即无法知道所有上下文中的管理状态,这是“管理员”的一个功能,它是在应用程序和前端控制器初始化后输入的状态。

Magento's admin state is effectively created from the control dispatching to an admin action controller; Magento的管理状态是从控制调度到管理动作控制器有效创建的; see Mage_Adminhtml_Controller_Action::preDispatch() . 请参阅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". 这是触发adminhtml_controller_action_predispatch_start事件的方法,该事件由Mage_Adminhtml_Model_Observer::bindStore() ,这是管理存储最初“设置”的位置。 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()); 实际上,观察者配置区域(adminhtml vs frontend)“工作”因为主要的动作控制器类 - 请参阅Mage_Core_Controller_Varien_Action::preDispatch() ,特别是Mage::app()->loadArea($this->getLayout()->getArea()); - just note that the layout object has its area information set in the adminhtml predispatch. - 请注意,布局对象的区域信息在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. tl; dr :使用观察者,甚至使用相同的观察者模型,但通过指定不同的调用方法来传递上下文。

HTH. HTH。

edit : added example code using beep logic's config as a starting point 编辑 :使用beep logic的config作为起​​点添加了示例代码

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. 无论我是否错误(但我已经测试过),一些事件(如controller_front_init_before)只能在全局节点内覆盖。 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. 然后来看看Alan和Benmark的救援解决方案,以指定是否只在前端或后端应用观察者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM