In the third and last article of this Magento overriding series, I'll explain how to override core controller files. In the previous two articles of this series, we discussed overriding core files for blocks and models by creating a custom module. In this tutorial, we'll look at overriding core controller files.
Why Overriding Controllers?
In Magento, the controller is responsible for handling incoming requests, and it's a backbone of the Magento routing implementation. To handle probably every request in Magento, the controller defines different actions in the form of controller class methods. The controller action method includes related application logic which interacts with views and models to prepare the output of that particular page. Sometimes, you need to alter the flow of controller execution to inject custom code or change the core code.
As I said in the previous tutorial, it's never recommended to change core files directly, as it makes upgrading Magento really difficult. To avoid this, we should follow the standard way of making desired changes to core files: we should either use event observers or override core files with our custom module files. We'll discuss the overriding feature today.
In this tutorial, we'll make a custom module to understand how controller overriding works in Magento. In this custom module, we'll see how to override a "Product" controller class of the core "Catalog" module. Overriding works by setting up certain XML tags as per the conventions of Magento.
I assume that you're familiar with the basic module creation process in Magento. If not, you can refer to this article on custom module creation.
A Glance at the Setup
Here's the list of files required for the desired setup:
-
app/etc/modules/Envato_All.xml
: It's a file used to enable our custom module. -
app/code/local/Envato/Catalog/etc/config.xml
: It's a module configuration file in which we'll set up controller class overriding using certain tags as per the Magento conventions. -
app/code/local/Envato/Catalog/controllers/ProductController.php
: It's a custom controller class file which we'll use to override the core "Product" controller class.
Creating Files and Folders: Custom Module
First, we need to create a module enabler file. Create a file "app/etc/modules/Envato_All.xml" and paste the following contents in that file. We've used Envato
as our module namespace and Catalog
as our module name. It'll enable our "Catalog" module by default.
<?xml version="1.0"?> <config> <modules> <Envato_Catalog> <active>true</active> <codePool>local</codePool> </Envato_Catalog> </modules> </config>
Next, we need to create a module configuration file. Create "app/code/local/Envato/Catalog/etc/config.xml" and paste the following contents in that file.
<?xml version="1.0"?> <config> <modules> <Envato_Catalog> <version>1.0</version> </Envato_Catalog> </modules> <frontend> <routers> <catalog> <args> <modules> <Envato_Catalog before="Mage_Catalog">Envato_Catalog</Envato_Catalog> </modules> </args> </catalog> </routers> </frontend> </config>
First, we've defined a module version number using the <version>
tag. The <catalog>
tag is the front controller router name of the "Catalog" core module. It informs the routing system that we want to override the controllers of the "Catalog" module.
Finally, the <Envato_Catalog before="Mage_Catalog">Envato_Catalog</Envato_Catalog>
tag is used to inform the Magento routing system that it should load your custom module's controller files if available. Of course, it'll load the core files of the "Catalog" module if it isn't able to find them under your module.
Finally, the only remaining thing is to define a controller class Envato_Catalog_ProductController
. Let's create a controller file "app/code/local/Envato/Catalog/controllers/ProductController.php" and paste the following contents in that file.
<?php /** * Product controller * * @category Envato * @package Envato_Catalog */ require_once 'Mage/Catalog/controllers/ProductController.php'; class Envato_Catalog_ProductController extends Mage_Catalog_ProductController { /** * Product view action */ public function viewAction() { // Include your custom code here! // Get initial data from request $categoryId = (int) $this->getRequest()->getParam('category', false); $productId = (int) $this->getRequest()->getParam('id'); $specifyOptions = $this->getRequest()->getParam('options'); // Prepare helper and params $viewHelper = Mage::helper('catalog/product_view'); $params = new Varien_Object(); $params->setCategoryId($categoryId); $params->setSpecifyOptions($specifyOptions); // Render page try { $viewHelper->prepareAndRender($productId, $this, $params); } catch (Exception $e) { if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) { if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) { $this->_redirect(''); } elseif (!$this->getResponse()->isRedirect()) { $this->_forward('noRoute'); } } else { Mage::logException($e); $this->_forward('noRoute'); } } } }
We've defined an Envato_Catalog_ProductController
class which extends the core Mage_Catalog_ProductController
controller class of the Catalog module. The important thing to note here is that we've included the core controller file "Mage/Catalog/controllers/ProductController.php" before the class definition as Magento won't include it automatically.
In the above example, we've overridden the viewAction
method of the Mage_Catalog_ProductController
class. It means that whenever a product detail page is viewed in the front-end, it'll call the viewAction
method defined in your custom controller class. So you can modify the code defined in that method as per your requirements.
Conclusion
So today, we learned how to override the core controller files in Magento using a custom module. I hope you've enjoyed this series and learned something useful which you can implement in your code! Share your queries and suggestions using the feed below!
Comments