Una delle caratteristiche più interessanti di Magento è la semplicità con cui possiamo estendere il core originario. Vediamo oggi come sovrascrivere un controller, ereditando la classe iniziale e modificando un unico metodo
Una delle caratteristiche più interessanti, ma forse meno sfruttate, di Magento risiede nell'estendibilità del codice. Vediamo oggi come eseguire un overwrite di un controller, ad esempio quello che gestisce la rubrica degli indirizzi di un cliente. Svolgeremo un'operazione a puro scopo didattico, molto semplice (aggiungeremo la scritta 'non disponibile' nel campo "fax" se questo non viene compilato dall'utente).
Per prima cosa, creiamo il nostro modulo. Creiamo dentro app/code/local/<nome del vostro namespace>/<nome del modulo>/etc il file config.xml. Nel mio caso il namespace è Infocurci, il nome del modulo è Fax, per cui dentro app/code/local/Infocurci/fax/etc/config.xml avrò queste istruzioni:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Infocurci_Fax>
<version>0.1.1</version>
</Infocurci_Fax>
</modules>
<frontend>
<routers>
<customer>
<args>
<modules>
<Infocurci_Fax before="Mage_Customer">Infocurci_Fax</Infocurci_Fax>
</modules>
</args>
</customer>
</routers>
</frontend>
</config>
Oltre alla configurazione iniziale del modulo, ho aggiunto dentro il blocco <frontend> l'istruzione che segnala a Magento di sostituire i controller del modulo "customer" (dove appunto troviamo, tra gli altri, quello delegato alla gestione degli indirizzi: AddressController) con quelli che troverà dentro il nostro modulo.
Creiamo quindi il file app/code/local/Infocurci/Fax/controllers/AddressController.php, vale a dire il controller con il quale sovascriveremo quello di Magento. Dentro questo file vanno eseguite queste tre operazioni:
va incluso il controller di base di Magento (un semplice require_once)
va ovviamente creata la nostra classe personalizzata, facendole estendere quella di base che abbiamo appena incluso
va creata la funzione o le funzioni che sovrascrivono quelle del controller, secondo il classico sistema di estensione delle classi nella programmazione oop
Ecco quindi il contenuto del nostro file:
<?php
require_once(Mage::getModuleDir('controllers','Mage_Customer').DS.'AddressController.php');
class Infocurci_Fax_AddressController extends Mage_Customer_AddressController
{
public function formPostAction()
{
if (!$this->_validateFormKey()) {
return $this->_redirect('*/*/');
}
// Save data
if ($this->getRequest()->isPost()) {
$customer = $this->_getSession()->getCustomer();
/* @var $address Mage_Customer_Model_Address */
$address = Mage::getModel('customer/address');
$addressId = $this->getRequest()->getParam('id');
if ($addressId) {
$existsAddress = $customer->getAddressById($addressId);
if ($existsAddress->getId() && $existsAddress->getCustomerId() == $customer->getId()) {
$address->setId($existsAddress->getId());
}
}
$errors = array();
/* @var $addressForm Mage_Customer_Model_Form */
$addressForm = Mage::getModel('customer/form');
$addressForm->setFormCode('customer_address_edit')
->setEntity($address);
$addressData = $addressForm->extractData($this->getRequest());
$addressErrors = $addressForm->validateData($addressData);
if ($addressErrors !== true) {
$errors = $addressErrors;
}
try {
$addressForm->compactData($addressData);
$address->setCustomerId($customer->getId())
->setIsDefaultBilling($this->getRequest()->getParam('default_billing', false))
->setIsDefaultShipping($this->getRequest()->getParam('default_shipping', false));
$addressErrors = $address->validate();
if ($addressErrors !== true) {
$errors = array_merge($errors, $addressErrors);
}
if (count($errors) === 0) {
$fax = $this->getRequest()->getPost('fax');
if(empty($fax)){
$address->setFax('Non disponibile');
}
$address->save();
$this->_getSession()->addSuccess($this->__('The address has been saved.'));
$this->_redirectSuccess(Mage::getUrl('*/*/index', array('_secure'=>true)));
return;
} else {
$this->_getSession()->setAddressFormData($this->getRequest()->getPost());
foreach ($errors as $errorMessage) {
$this->_getSession()->addError($errorMessage);
}
}
} catch (Mage_Core_Exception $e) {
$this->_getSession()->setAddressFormData($this->getRequest()->getPost())
->addException($e, $e->getMessage());
} catch (Exception $e) {
$this->_getSession()->setAddressFormData($this->getRequest()->getPost())
->addException($e, $this->__('Cannot save address.'));
}
}
return $this->_redirectError(Mage::getUrl('*/*/edit', array('id' => $address->getId())));
}
}
il contenuto della funzione formPostAction() (richiamata quando un utente entra nel proprio profilo e modifica un indirizzo, ad esempio quello d spedizione) è praticamente identico alla funzione originale; abbiamo solo aggiunto queste righe:
$fax = $this->getRequest()->getPost('fax');
if(empty($fax)){
$address->setFax('Non disponibile');
}
per fare una piccola modifica, come detto prima a solo scopo didattico.
Non ci rimane altro che attivare il modulo, dentro app/etc/modules creiamo il solito file <Namespace>/<Modulo>, nel mio caso Infocurci_Fax.xml:
<?xml version="1.0"?>
<config>
<modules>
<Infocurci_Fax>
<active>true</active>
<codePool>local</codePool>
<version>0.1.1</version>
</Infocurci_Fax>
</modules>
</config>
Per testare il funzionamento del modulo, entriamo nel nostro sito, logghiamoci (se non abbiamo un account creiamolo ed inoltriamo un ordine cosi da esser sicuri di avere indirizzi da gestire) ed entriamo nel profilo utente.
Clicchiamo su "address book" ...
...e proviamo a modificare un indirizzo senza compilare il campo Fax.
Salviamo i dati e infatti ora il campo fax, se non compilato, risulta con la scritta "Non disponibile".
Eseguiamo la prova inversa: modifichiamo l'indirizzo inserendo però un numero di fax. Il numero ora viene correttamente registrato!