2012-11-06 9 views
10

Ich habe ein Problem mit Magento-Nachrichten. Ich baue ein benutzerdefiniertes Modul, das in der Lage sein sollte, den Zugang zu einigen Teilen des Ladens zu beschränken. Ich habe einen Beobachter erstellt, der sich in controller_action_predispatch Ereignis einklinkt und prüft, ob aktuelle Anfrage vom Benutzer zugegriffen werden kann. Wenn auf die Aktion nicht zugegriffen werden kann, leitet der Beobachter den Benutzer um und setzt die Fehlerinformation. Ich möchte die Weiterleitungs-URL auf die Seite setzen, von der der Kunde kommt, um zu vermeiden, dass der gesamte Shop durchsucht wird. Ich schaue mir die HTTP_REFERER an und benutze sie wenn sie eingestellt ist, sonst leite ich den Kunden auf die Homepage um. Das Problem ist, dass im späteren Fall (Homepage Redirect) alles gut funktioniert, aber wenn ich URL basierend auf dem Referer setze, sehe ich keine Fehlermeldung im Nachrichtenfeld.Magento Nachrichten nach Umleitung verlieren

Der Code vom Beobachter ($name Variable ist ein String):

Mage::getSingleton('core/session')->addError('Acces to '.$name.' section is denied'); 
$url = Mage::helper('core/http')->getHttpReferer() ? Mage::helper('core/http')->getHttpReferer() : Mage::getUrl(); 
Mage::app()->getResponse()->setRedirect($url); 

Was ich interessant fand, ist, dass wenn ich eine Änderung in der Beobachter-Datei tun und speichern, dann wird die nächste Anforderung, die fehlschlägt und Wird zu Referer weitergeleitet URL zeigt die Fehlerinformationen an, aber alle nachfolgenden verlieren die Nachrichten.

Ich dachte, dass das Problem in der vollständigen URL und meine lokale Installation ist (I .local Domäne bin mit), aber so habe ich versucht, das Hinzufügen

$url = str_replace(Mage::getBaseUrl(), '/', $url); 

aber das half nicht.

Ich versuchte auch Redirect mit PHP header() Funktion ohne Ergebnis auch.

Der gesamte Cache ist deaktiviert. Der Workflow, der das Problem löst sich wie folgt:

  1. Ich bin auf der berührbaren Seite gehen (zum Beispiel/Kunden/Konto)
  2. Klicken Sie auf Warenkorb Link (Wagen für dieses Konto ist deaktiviert)
  3. Zurück zu/Kunden/Konto und die Fehlermeldung wird
  4. Klicken Sie auf Warenkorb Link angezeigt wieder
  5. Zurück zur/Kunden/Konto aber keine Fehlermeldung

Jeder Tipp, wo Sie suchen können, wird geschätzt.

+0

Können Sie alle Ihre Caches (+ FPC wenn Magento EE) deaktivieren, um zu sehen, ob es ein Cache-Problem ist? Übrigens, ich habe nicht alle Ihre Erklärungen verstanden, Sie haben verstanden, dass Sitzungsfehlermeldungen nach der ersten Anzeige gelöscht werden? –

+0

Ich erweiterte die Beschreibung, hoffe es ist jetzt klar. – Zefiryn

Antwort

4

Ihre Nachrichten, weil verloren Sie verwenden einen ungünstigen Weg für eine Umleitung in controller_action_predispatch. Ihre Lösung verursacht zum einen die "verlorene Nachricht" und zum anderen verschwendet sie Rechenleistung Ihres Servers.

Wenn Sie sich Mage_Core_Controller_Varien_Action::dispatch() ansehen, sehen Sie, dass Ihre Lösung die Ausführung der aktuellen Aktion nicht stoppt, aber dies sollte mit einer Umleitung geschehen. Stattdessen führt Magento die aktuelle Aktion bis zum Ende durch, einschließlich der Wiedergabe der Nachricht, die Sie zuvor hinzugefügt hatten. Kein Wunder also, warum die Nachricht mit der nächsten Client-Anfrage verloren geht, die Magento bereits mit der Server-Antwort, die Ihre Weiterleitung beinhaltet, bereits gerendert hat.

Weiter sehen Sie in Mage_Core_Controller_Varien_Action::dispatch() nur eine Möglichkeit, die Ausführung der aktuellen Aktion zu stoppen und direkt zu der Umleitung zu springen, die in Zeile 428 catch (Mage_Core_Controller_Varien_Exception $e) [...] ist. Sie müssen also Mage_Core_Controller_Varien_Exception verwenden, was ziemlich unpopulär ist, aber die einzig richtige Lösung für Ihren Zweck. Das einzige Problem ist, dass diese Klasse einen Fehler hat, seit sie in Magento 1.3.2 eingeführt wurde. Aber das kann leicht behoben werden.

Sie Ihre eigene Klasse erstellen, die von Mage_Core_Controller_Varien_Exception abgeleitet:

/** 
* Controller exception that can fork different actions, 
* cause forward or redirect 
*/ 
class Your_Module_Controller_Varien_Exception 
    extends Mage_Core_Controller_Varien_Exception 
{ 
    /** 
    * Bugfix 
    * 
    * @see Mage_Core_Controller_Varien_Exception::prepareRedirect() 
    */ 
    public function prepareRedirect($path, $arguments = array()) 
    { 
     $this->_resultCallback = self::RESULT_REDIRECT; 
     $this->_resultCallbackParams = array($path, $arguments); 
     return $this; 
    } 
} 

So können Sie Ihre Lösung wirklich sauber mit, dass implementieren:

/** 
* Your observer 
*/ 
class Your_Module_Model_Observer 
{ 
    /** 
    * Called before frontend action dispatch 
    * (controller_action_predispatch) 
    * 
    * @param Varien_Event_Observer $observer 
    */ 
    public function onFrontendActionDispatch($observer) 
    { 
     // [...] 

     /* @var $action Mage_Core_Model_Session */ 
     $session = Mage::getSingleton('core/session'); 
     /* @var $helper Mage_Core_Helper_Http */ 
     $helper = Mage::helper('core/http'); 
     // puts your message in the session 
     $session->addError('Your message'); 
     // prepares the redirect url 
     $params = array(); 
     $params['_direct'] = $helper->getHttpReferer() 
      ? $helper->getHttpReferer() : Mage::getHomeUrl(); 
     // force the redirect 
     $exception = new Your_Module_Controller_Varien_Exception(); 
     $exception->prepareRedirect('', $params); 
     throw $exception; 
    } 
} 
24
//A Success Message 
Mage::getSingleton('core/session')->addSuccess("Some success message"); 

//A Error Message 
Mage::getSingleton('core/session')->addError("Some error message"); 

//A Info Message (See link below) 
Mage::getSingleton('core/session')->addNotice("This is just a FYI message..."); 

//These lines are required to get it to work 
session_write_close(); //THIS LINE IS VERY IMPORTANT! 
$this->_redirect('module/controller/action'); 

// or 
$url = 'path/to/your/page'; 
$this->_redirectUrl($url); 

Dies wird in einem Controller arbeiten, aber wenn Sie versuchen, nach der Ausgabe umleiten bereits gesendet wurde, dann kann man nur, dass durch Javascript tun:

<script language=”javascript” type=”text/javascript”> 
window.location.href=”module/controller/action/getparam1/value1/etc"; 
</script>  
+7

Danke, session_write_close(); hat den Trick für mich gemacht. –

+0

+1 für session_write_close(), war für immer fest! Danke –

0

dies funktionieren wird, so versuchen Sie es:

$url = 'path/to/your/page'; 
$this->_redirectUrl($url); 
return false; 

Dies bedeutet, dass Sie nicht wieder etwas anderes ausführen dürfen.