我如何知道Magento请求是针对前端还是后端页面?

4sup72z8  于 2022-11-12  发布在  其他
关注(0)|答案(5)|浏览(97)

如何判断当前请求是针对后端页面还是前端页面?这个检查将在观察器中完成,因此如果有帮助的话,我可以访问请求对象。
我考虑过检查Mage::getSingleton('admin/session')->getUser(),但我不认为这是一个非常可靠的方法。我希望有一个更好的解决方案。

tcomlyy6

tcomlyy61#

Magento本身并没有为这些信息提供一个显式的方法/API,所以对于任何解决方案,您都需要检查环境并进行推断。
我用的是

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

有一段时间,但事实证明,有一些管理页面(Magento Connect软件包管理器)并不是这样的。由于某种原因,该页面明确地将存储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
}

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

wi3ka0sx

wi3ka0sx2#

如果您可以使用观察者,则可以将其限制在“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>
8i9zcol2

8i9zcol23#

看一下Mage/Core/Model/Store.php中您要使用的方法:

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

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

在商店ID未按预期设置(Magento连接等)时作为备用

lymgl2op

lymgl2op4#

我喜欢哔哔声逻辑的答案--它在观察者的环境中是有意义的。我也喜欢Alan的观点,即没有办法在所有环境中知道管理状态,这是“管理”的一个功能,是在应用程序和前端控制器初始化后进入的状态。
Magento的管理状态是有效地创建从控制调度到管理动作控制器;请参阅Mage_Adminhtml_Controller_Action::preDispatch()。这是触发adminhtml_controller_action_predispatch_start事件的方法,该事件由Mage_Adminhtml_Model_Observer::bindStore()使用,Mage_Adminhtml_Model_Observer::bindStore()是最初“设置”管理存储的位置。实际上,观察器配置区域(adminhtml对frontend)“工作”是因为主动作控制器类-参见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:使用观察器,甚至使用相同的观察器模型,但通过指定不同的调用方法传入上下文。

我还包含了一些示例代码,使用beeplogic的答案中的config作为起点。

njthzxwz

njthzxwz5#

不管我是不是错了(但是我已经测试过了),有些事件(比如controller_front_init_before)只能在全局节点内部被覆盖。因此,这个覆盖会同时影响前端和后端。
然后是Alan和benmark的解决方案来解决这个问题,指定是只在前端应用观察器还是只在后端应用观察器。

相关问题