Запрос Magento — интерфейс или бэкенд?
-
13-12-2019 - |
Вопрос
Как узнать, относится ли текущий запрос к внутренней или внешней странице?Эта проверка будет выполняться внутри наблюдателя, поэтому у меня будет доступ к объекту запроса, если это поможет.
Я подумал проверить Mage::getSingleton('admin/session')->getUser()
но я не думаю, что это очень надежный метод.Я надеюсь на лучшее решение.
Решение
Это одна из тех областей, где нет хорошего ответа.Сам Magento не предоставляет явного метода/API для этой информации, поэтому в любом решении вам придется изучить среду и сделать выводы.
я использовал
Mage::app()->getStore()->isAdmin()
какое-то время, но оказывается, что на некоторых страницах администрирования (менеджер пакетов Magento Connect) это не так.По какой-то причине эта страница явно устанавливает идентификатор магазина равным 1, что делает isAdmin
вернуть как ложь.
#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');
}
Могут быть и другие страницы с таким поведением,
Еще один хороший вариант — проверить свойство «площадь» пакета проектирования.
Кажется, что это вряд ли будет переопределено для страницы, находящейся в администраторе, поскольку эта область влияет на путь к шаблонам дизайна областей администрирования и 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
}
Таким образом, когда/если вы обнаружите дыры в логике проверки администратором, вы сможете исправить все в одном централизованном месте.
Другие советы
Если вы можете использовать наблюдатель, вы можете ограничить его на область события «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>
. Посмотрите на методы внутри Mage/Core/Model/Store.php
, вы захотите использовать:
Mage::app()->getStore()->isAdmin()
.
в сочетании с
Mage::getDesign()->getArea() == 'adminhtml'
.
Чтобы действовать в качестве загрязнения, где идентификатор магазина не установлен, как вы ожидаете (Magento Connect ETC.)
Мне нравится ответ Beep Logic - это имеет смысл в контексте наблюдателей. Мне также нравится пункт Алана, что нет способа узнать состояние администратора во всех контекстах, что является функцией «администратора», являющегося состоянием, которое введено после инициализации приложения и переднего контроллера.
государство администратора Magento эффективно создано из диспетчера управления в контроллер действий администратора; Смотрите Mage_Adminhtml_Controller_Action::preDispatch()
. Это метод, который запускает событие adminhtml_controller_action_predispatch_start
, который потребляется Mage_Adminhtml_Model_Observer::bindStore()
, который находится в том случае, если Admin Store является первоначально «настроен». На самом деле, зоны конфигурации наблюдателя (AdminHTML VS Frontend) «работает» из-за главного класса контроллера действий - см. Mage_Core_Controller_Varien_Action::preDispatch()
, в частности, Renacodicetacodcode - просто обратите внимание, что объект Layout имеет информацию о своей области в Predispatch в 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 : используйте наблюдатель, даже используйте тот же модель наблюдателя, но пропускайте в контексте, указав другой метод вызова.
hth.
Я прав или нет (но я тестировал его), некоторые события (например, Controller_Front_init_before) могут быть перезаписаны только внутри глобального узла.В результате это переопределение повлияет на оба интерфейса и бэкэнда.
Затем приходите на решение Alan и Benmark на Rescue, чтобы указать, если вы хотите применить наблюдателя только на Frontend или Backend.