Подтвердить что ты не робот

Запрос Magento - Frontend или Backend?

Как узнать, является ли текущий запрос для бэкэнд-страницы или интерфейса? Эта проверка будет выполнена внутри наблюдателя, поэтому у меня есть доступ к объекту запроса, если это помогает.

Я считал проверку Mage::getSingleton('admin/session')->getUser(), но я не считаю это очень надежным методом. Я надеюсь на лучшее решение.

4b9b3361

Ответ 1

Это одна из тех областей, где нет хорошего ответа. Сама Magento не предоставляет явный метод /API для этой информации, поэтому при любом решении вам нужно будет изучить среду и сделать выводы.

Я использовал

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

но, оказывается, есть определенные страницы администрирования (менеджер пакетов Magento Connect), где это неверно. По какой-то причине эта страница явно устанавливает идентификатор хранилища равным 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
}

Таким образом, когда/если вы обнаружите дыры в логике проверки администратора, вы можете исправить все в одном централизованном месте.

Ответ 2

Если вы можете использовать наблюдателя, вы можете ограничить его в области событий "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>

Ответ 3

Посмотрите методы внутри Mage/Core/Model/Store.php, которые вы хотите использовать:

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

В сочетании с

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

Сделать резервную копию, когда идентификатор магазина не установлен так, как вы ожидаете (Magento connect и т.д.)

Ответ 4

Мне нравится ответ на звуковой сигнал - это имеет смысл в контексте наблюдателей. Мне также нравится, что Алан указывает, что нет никакого способа узнать состояние администратора во всех контекстах, что является функцией "admin", являющейся состоянием, которое вводится после инициализации приложения и переднего контроллера.

Состояние администратора Magento эффективно создается из диспетчеризации управления в контроллер действия администратора; см. Mage_Adminhtml_Controller_Action::preDispatch(). Это метод, который запускает событие adminhtml_controller_action_predispatch_start, которое расходуется на Mage_Adminhtml_Model_Observer::bindStore(), где администраторский магазин изначально "установлен". Фактически, области конфигурации наблюдателя (adminhtml vs 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: использовать наблюдателя, даже использовать одну и ту же модель наблюдателя, но передавать в контексте, указав другой метод вызова.

НТН.

edit: добавлен примерный код с использованием битовой логической конфигурации в качестве отправной точки

Ответ 5

Я ошибаюсь или нет (но я его протестировал), некоторые события (например, controller_front_init_before) могут быть перезаписаны только внутри глобального node. В результате это переопределение будет влиять как на внешний интерфейс, так и на бэкэнд.

Затем запустите решение Alan и benmark для спасения, чтобы указать, хотите ли вы применять наблюдателя только к интерфейсу или только к серверу.