Existem várias abordagens, mas vou começar como isso não é feito para esclarecer alguns equívocos comuns:
- É não é possível para substituir classes do controlador copiando-os para
app/code/local
. Isso ocorre porque as classes do controlador não são carregadas Varien_Autoload
, mas os arquivos são incluídos explicitamente.
- Não é mais recomendado usar
<rewrite><controller><to>
sintaxe. Esta é uma técnica antiga e obsoleta desde o Magento 1.3 (consulte: Substituindo Controlador vs Substituindo Solicitação do Controlador de Ação )
Adicionar / substituir ações do controlador
Para adicionar ações do controlador a um controlador existente, use o seguinte em seu config.xml:
<frontend> <--- area (adminhtml or frontend)
<routers>
<checkout> <--- front name (in admin always "adminhtml")
<args>
<modules>
<stack_checkout before="Mage_Checkout">Stack_Checkout</stack_checkout>
^ ^
| |
module to override |
</modules> (in admin always |
</args> "Mage_Adminhtml") your module
</checkout>
</routers>
</frontend>
Em seguida, crie um controlador em seu módulo, como
class Stack_Checkout_OnepageController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
// here you override checkout/onepage/index
}
public function helloAction()
{
// here you create a new action checkout/onepage/hello
}
}
Você não precisa estender a classe do controlador original porque o Magento procurará nas duas classes, na ordem definida por before="..."
Se você precisar estender a classe original porque deseja reutilizar outros métodos, precisará incluí-la (lembre-se, os controladores não são carregados automaticamente):
require_once(Mage::getModuleDir('controllers','Mage_Checkout') . DS . 'OnepageController.php');
Use observadores para modificar as ações do controlador
Se você não adicionar novas ações, uma alternativa é usar observadores para modificar o comportamento das ações existentes. Toda ação do controlador aciona um evento dinâmico "predispatch" no formulário controller_action_predispatch_$FRONTNAME_$CONTROLLER_$ACTION
, por exemplocontroller_action_predispatch_checkout_onepage_index
No observador, você tem acesso à própria classe do controlador usando
$controller = $observer->getControllerAction();
Se você não deseja que o método original seja acionado, diga ao Magento para não despachar ainda mais a ação:
$controller->setFlag('', Mage_Core_Controller_Front_Action::FLAG_NO_DISPATCH, true);
Para garantir a integridade: Você também pode impedir eventos "pós-distribuição" de maneira semelhante, mas isso geralmente não é necessário (aqui está um exemplo em que é útil: XML possui conteúdo extra ):
$controller->setFlag('', Mage_Core_Controller_Front_Action::FLAG_NO_POST_DISPATCH);
Por falar nisso, você também pode adicionar um observador, controller_action_postdispatch_$FRONTNAME_$CONTROLLER_$ACTION
se desejar executar ações ou modificações adicionais da resposta após a ação original ter sido executada.