web-dev-qa-db-fra.com

Demande Magento - Frontend ou Backend?

Comment savoir si la requête actuelle concerne un backend ou une page frontend? Cette vérification sera effectuée à l'intérieur d'un observateur. J'ai donc accès à l'objet de requête si cela peut vous aider.

J'ai envisagé de vérifier Mage::getSingleton('admin/session')->getUser() mais je ne pense pas que ce soit une méthode très fiable. J'espère une meilleure solution.

21
Colin O'Dell

C'est l'un de ces domaines où il n'y a pas de bonne réponse. Magento lui-même ne fournit pas de méthode/API explicite pour ces informations. Par conséquent, quelle que soit la solution, vous devrez examiner l'environnement et en déduire des choses.

J'utilisais 

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

pendant un certain temps, mais il s'avère que certaines pages d'administration (le gestionnaire de packages de Magento Connect) ne sont pas vraies. Pour une raison quelconque, cette page définit explicitement l'ID de magasin sur 1, ce qui renvoie 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');
}

Il peut y avoir d'autres pages avec ce comportement, 

Un autre bon choix consiste à vérifier la propriété "area" du package de conception.

Cela semble moins susceptible d'être remplacé pour une page qui se trouve dans l'administrateur, car la zone a une incidence sur le chemin d'accès aux modèles de conception des zones d'administration et aux fichiers XML de présentation.

Indépendamment de ce que vous choisissez d'inférer de l'environnement, créez un nouveau module Magento et ajoutez-y une classe d'assistance.

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;
    }
}

et puis chaque fois que vous avez besoin de vérifier si vous êtes dans l'administrateur, utilisez cette aide

if( Mage::helper('modulename/isadmin')->isAdmin() )
{
    //do the thing about the admin thing
}

Ainsi, lorsque/si vous découvrez des failles dans la logique de vérification de votre administrateur, vous pouvez tout corriger en un seul endroit centralisé. 

58
Alan Storm

Si vous pouvez utiliser un observateur, vous pouvez le limiter à la zone d'événements '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>
14
beeplogic

Regardez les méthodes à l'intérieur de Mage/Core/Model/Store.php que vous voudrez utiliser:

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

En conjonction avec

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

Pour agir comme solution de secours lorsque l'ID de magasin n'est pas défini comme prévu (connexion Magento, etc.)

11

J'aime la réponse de la logique du bip - cela a du sens dans le contexte des observateurs. J'aime aussi le point de vue d'Alan selon lequel il n'y a aucun moyen de connaître l'état de l'administrateur dans tous les contextes, fonction de "l'administrateur" étant un état entré après l'initialisation de l'application et du contrôleur frontal.

L'état d'administration de Magento est effectivement créé à partir de l'envoi du contrôle à un contrôleur d'action d'administration; voir Mage_Adminhtml_Controller_Action::preDispatch(). C'est la méthode qui déclenche l'événement adminhtml_controller_action_predispatch_start, qui est consommé par Mage_Adminhtml_Model_Observer::bindStore(), qui est l'emplacement initial du magasin admin. En fait, les zones de configuration de l'observateur (adminhtml vs frontend) "fonctionnent" en raison de la classe de contrôleur d'action principale - voir Mage_Core_Controller_Varien_Action::preDispatch(), plus précisément Mage::app()->loadArea($this->getLayout()->getArea()); - il suffit de noter que les informations de zone de présentation sont définies dans le prédispatch adminhtml.

Quelle que soit la manière dont vous la découpez, le comportement de l'administrateur sur lequel nous nous appuyons dans de nombreux contextes - même à un niveau aussi élevé que celui du système d'observation des événements - repose sur la structure de contrôle des commandes.

<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>

Dans votre définition d'observateur:

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 : Utilisez un observateur, utilisez même le même modèle d'observateur, mais transmettez le contexte en spécifiant une méthode d'appel différente.

HTH.

edit : ajout d'un exemple de code utilisant la configuration de beep logic comme point de départ

5
benmarks

Que je me trompe ou non (mais je l'ai testé), certains événements (comme controller_front_init_before) ne peuvent être écrasés que dans le noeud global. En conséquence, cette substitution affectera à la fois le front-end et le back-end. 

Viennent ensuite la solution d'Alan et Benmark à la rescousse pour spécifier si vous souhaitez appliquer l'observateur uniquement sur le front-end ou le back-end.

0
user1576748