2011-03-13 9 views
13

Ho qualche codice nel checkout in cui imposto una chiave nella sessione se quella chiave è impostata su false in qualsiasi punto del checkout ho bisogno di rimandarli alla pagina di fatturazione. Ho il codice per questo, ma non posso nemmeno avere il codice che viene in genere eseguito dopo l'osservatore perché chiamerà un servizio di terze parti e tornerà come errato a causa di questa chiave mancante nella sessioneIn un metodo Observer, come si dice a Magento di non elaborare il codice dopo l'evento inviato

Ecco il mio codice, ho tutto quello che voglio ma ho bisogno che la risposta avvenga immediatamente e per nulla dopo che la riga dell'evento inviato è stata attivata solo la risposta inviata al browser.

public function checkForOrdKey(Varien_Event_Observer $observer) 
    { 
     $controllerAction = $observer->getControllerAction(); 
     $request = $controllerAction->getRequest(); 
     $controllerName = $request->getControllerName(); 
     $stepData = $this->_getCheckoutSession()->getStepData(); 
     $ordKeyRemoved = $this->_getCheckoutSession()->getOrdKeyRemoved(); 
     // if it is the checkout onepage controller or inventory controller don't do anything 
     if (isset($controllerName) && $controllerName === "onepage" && $stepData['shipping']['complete'] && $ordKeyRemoved) { 
      $this->_getCheckoutSession()->setStepData('shipping', 'complete', false); 
      $result['goto_section'] = 'billing'; 
      Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); 
      $this->_getCheckoutSession()->setOrdKeyRemoved(false); 

     } 
    } 

risposta

27

Fondamentalmente è necessario prendere il controllo della creazione e dell'invio dell'oggetto Risposta. Il normale flusso del controller elaborerà tutta la logica inline del metodo, accenderà i suoi eventi e raccoglierà aggiunte alla risposta lungo la strada, quindi il framework Magento finirà e invierà la risposta.

È possibile corto circuito che scorre nel Observer collegando all'evento preDispatch (controller_action_predispatch_checkout_onepage_savebilling) e quindi l'esecuzione di questo:

$request = Mage::app()->getRequest(); 
$action = $request->getActionName(); 
Mage::app()->getFrontController()->getAction()->setFlag($action, Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true); 

Le linee sopra istruire Mage_Core_Controller_Varien_Action (nonno di tutti i controller) per bypassare l'azione che è stato chiamato (revisione riga 414 in CE 1.4.2 per vedere come funziona). Quindi procedi creando la tua risposta e inviandola di nuovo al browser. Sarà necessario indagare il formato corretto JSON avere alla cassa classi JS rendono eventuali messaggi di errore, ma qualcosa in questo senso ...

$response = Mage::app()->getResponse(); 
$response->setHttpResponseCode(500); //adjust to be whatever code is relevant 
$json = Mage::helper('core')->jsonEncode($this->__('Your message here')); //adjust 
$response->setBody($json); 
//don't need to sendResponse() as the framework will do this later 

In questo modo si sta lavorando nel quadro Zend/Magento e si non è necessario sostituire il CheckoutController (per favore, mai e poi ...) o usare "hackiness" exit/die(). Il motivo per cui exit/die è negativo è che impedisce a qualsiasi Observer successivo che abbia registrato un interesse per quell'Evento che è in grado di agire. Sarebbe estremamente frustrante come uno sviluppatore registrare un Observer che non viene mai chiamato perché un altro sviluppatore ha terminato l'uscita prima di essere colpito !!

Nota che l'impostazione del flag no-dispatch sarà solo funziona se sei collegato all'evento di predispatch.

Per ulteriori informazioni, esaminare Magento sequence diagram per vedere come si ignorano le sezioni Layout/Blocco/Modello del flusso.

+0

hmm sembra ancora che stia cercando di eseguire il resto del codice anche dopo aver inviato la risposta. –

+0

euch, forse hai bisogno di un 'exit()' dopo il 'sendReponse()' ... –

+0

Ha funzionato dopo aver inserito exit() su di esso, perché è così brutto farlo? –