2012-03-13 18 views
20

Come posso sapere se la richiesta corrente riguarda un back-end o una pagina di frontend? Questo controllo sarà fatto all'interno di un osservatore, quindi ho accesso all'oggetto richiesta se questo aiuta.Richiesta Magento - Frontend o Backend?

Ho considerato il controllo di Mage::getSingleton('admin/session')->getUser() ma non penso che sia un metodo molto affidabile. Sto sperando in una soluzione migliore.

risposta

55

Questa è una di quelle aree in cui non c'è una buona risposta. Magento stesso non fornisce un metodo/API esplicito per queste informazioni, quindi con qualsiasi soluzione è necessario esaminare l'ambiente e dedurre le cose.

stavo usando

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

per un po ', ma si scopre ci sono alcune pagine di amministrazione (il direttore Magento Connect Package), dove questo non è vero. Per qualche ragione questa pagina imposta esplicitamente l'ID del negozio come 1, il che rende isAdmin restituito come falso.

#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'); 
} 

Ci possono essere altre pagine con questo comportamento,

Un'altra buona scommessa è quello di verificare la "area" di proprietà del pacchetto di progettazione.

Sembra meno probabile che venga sovrascritta una pagina nell'amministratore, poiché l'area influisce sul percorso dei modelli di progettazione delle aree di amministrazione e dei file XML di layout.

Indipendentemente da ciò che si sceglie di dedurre dal contesto, creare nuovo modulo Magento, e aggiungere una classe di supporto ad esso

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

e poi ogni volta che avete bisogno di controllare se siete in l'amministratore, l'uso questo helper

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

questo modo, quando/se si scopre buchi nel vostro amministratore logica controllo, è possibile correggere tutto in un unico luogo centralizzato.

+0

Grazie per le informazioni Alan! In realtà sto usando questo per personalizzare [la tua correzione IE9] (http://alanstorm.com/ie9_fix_for_magento), in quanto causava alcuni problemi sul frontend per i nostri progettisti. Funziona perfettamente nell'area dell'amministratore, quindi grazie anche per aver trovato questa soluzione :) –

+0

Piccolo mondo! Inoltre, la risposta logica di beep qui sotto è probabilmente la soluzione migliore ** se ** è valida per la soluzione. (Ad esempio, se vuoi licenziare il tuo evento solo dal lato amministrativo). Se hai un singolo osservatore che fa cose sia sul frontend che sul backend, allora quanto sopra è un buon inizio. –

+0

Beh, questo non controlla se uno script viene eseguito nel back-end, ma se c'è un amministratore registrato ... – feeela

10

Date un'occhiata ai metodi all'interno Mage/Core/Model/Store.php si vorrà utilizzare:

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

In concomitanza con

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

Per agire come un ripiego in cui l'ID del negozio non è impostato come ti aspetti (Magento connect ecc.)

+0

Sapevo che sarebbe stato qualcosa di semplice: P Grazie per il tuo aiuto! –

+0

@Colin che non catturerà tutto. –

14

Se si è in grado di utilizzare un osservatore, è possibile limitarlo all'area eventi "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> 
5

Mi piace la risposta della logica beep - ha senso nel contesto degli osservatori. Mi piace anche il punto di Alan che non c'è modo di conoscere lo stato admin in tutti i contesti, che è una funzione di "admin" che è uno stato che viene inserito dopo l'inizializzazione dell'app e del front controller.

Lo stato di amministratore di Magento viene effettivamente creato dal dispatching di controllo a un controller di azione dell'amministratore; vedi Mage_Adminhtml_Controller_Action::preDispatch(). Questo è il metodo che attiva l'evento adminhtml_controller_action_predispatch_start, che viene consumato da Mage_Adminhtml_Model_Observer::bindStore(), che è dove l'archivio dell'amministratore è inizialmente "impostato".In effetti, le aree di configurazione dell'osservatore (adminhtml vs frontend) "funzionano" a causa della classe del controller di azioni principale - vedi Mage_Core_Controller_Varien_Action::preDispatch(), in particolare Mage::app()->loadArea($this->getLayout()->getArea()); - si noti che l'oggetto di layout ha le informazioni sull'area impostate nella predispatch adminhtml.

Indipendentemente da come lo si divide, il comportamento dell'amministratore su cui ci affidiamo a così tanti contesti - anche qualcosa di alto livello come il sistema di osservazione degli eventi - si basa sulla struttura di controllo dei comandi.

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

nella definizione osservatore:

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: utilizzare un osservatore, anche utilizzare lo stesso modello dell'osservatore, ma passare nel contesto specificando un metodo di chiamata diversa.

HTH.

modificare: aggiunto esempio di codice utilizzando config di logica beep come punto di partenza

0

Se mi sbaglio o no (ma ho provato), alcuni eventi (come controller_front_init_before) può essere sovrascritto solo all'interno nodo globale. Di conseguenza, questa sostituzione avrà effetto sia sul frontend che sul backend.

Poi arriva la soluzione di Alan e Benmark in soccorso per specificare se si desidera applicare l'osservatore solo su frontend o solo backend.

Problemi correlati