Как я могу узнать, является ли текущий запрос для бэкэнд-сервера или внешней страницы? Эта проверка будет выполнена внутри наблюдателя, поэтому я имею доступ к объекту запроса, если это помогает.
Я считал проверку Mage::getSingleton('admin/session')->getUser()
но я не думаю, что это очень надежный метод. Я надеюсь на лучшее решение.
Это одна из тех областей, где нет хорошего ответа. Сама Magento не предоставляет явный метод / API для этой информации, поэтому с любым решением вам нужно будет изучить среду и сделать выводы.
Я использовал
Mage::app()->getStore()->isAdmin()
какое-то время, но, оказывается, есть определенные страницы администрирования (менеджер пакетов Magento Connect), где это неверно. По какой-то причине эта страница явно устанавливает идентификатор магазина как 1, что делает isAdmin
return 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 }
Таким образом, когда / если вы обнаружите дыры в логике проверки администратора, вы можете исправить все в одном централизованном месте.
Если вы можете использовать наблюдателя, вы можете ограничить его в области событий «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 и т. Д.),
Мне нравится ответ звуковой логики – это имеет смысл в контексте наблюдателей. Мне также нравится мнение Алана о том, что во всех контекстах невозможно знать состояние администратора, что является функцией «admin», являющейся состоянием, которое вводится после инициализации приложения и переднего контроллера.
Административное состояние Magento эффективно создается из диспетчерской диспетчеризации в контроллер действия администратора; см. Mage_Adminhtml_Controller_Action::preDispatch()
. Это метод, который запускает событие adminhtml_controller_action_predispatch_start
, которое потребляется Mage_Adminhtml_Model_Observer::bindStore()
, в котором хранилище admin сначала «установлено». Фактически, области конфигурации наблюдателя (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 } } }
во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 : добавлен примерный код, используя конфигурацию beep-логики в качестве отправной точки
Я ошибаюсь или нет (но я его протестировал), некоторые события (например, controller_front_init_before) могут быть перезаписаны только внутри глобального узла. В результате это переопределение будет влиять как на внешний интерфейс, так и на бэкэнд.
Затем запустите решение Alan's и benmark для спасения, чтобы указать, хотите ли вы применять наблюдателя только для интерфейса или только для бэкэнд.