php Magento 请求 - 前端还是后端?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9693020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 07:26:19  来源:igfitidea点击:

Magento Request - Frontend or Backend?

phpmagentomagento-1.x

提问by Colin O'Dell

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. I'm hoping for a better solution.

我考虑过检查,Mage::getSingleton('admin/session')->getUser()但我认为这不是一个非常可靠的方法。我希望有更好的解决方案。

回答by Alan Storm

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. For some reason this page explicitly sets the store id to be 1, which makes isAdminreturn as false.

有一段时间,但事实证明,某些管理页面(Magento Connect 包管理器)并非如此。出于某种原因,此页面将商店 ID 显式设置为 1,这使得isAdminreturn 为 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.

这样,当/如果您在管理检查逻辑中发现漏洞时,您可以在一个集中的地方更正所有内容。

回答by beeplogic

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>

回答by Ben Lessani - Sonassi

Have a look at the methods inside Mage/Core/Model/Store.phpyou'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 连接等)

回答by benmarks

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; see Mage_Adminhtml_Controller_Action::preDispatch(). This is the method which fires the adminhtml_controller_action_predispatch_startevent, 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.

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 预调度中设置了其区域信息。

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.

哈。

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

编辑:使用蜂鸣逻辑的配置作为起点添加示例代码

回答by user1576748

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.

无论我错与否(但我已经测试过),某些事件(如 controller_front_init_before)只能在全局节点内被覆盖。因此,此覆盖将影响前端和后端。

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 的救援解决方案,以指定您是否只想在前端或后端应用观察者。