How to Override or Rewrite Controller in Magento 2?

Wanting to update a feature in Magento can sometimes be tricky due to the core functions of the application. Many people need to customize Magento to override the controller and ensure it works as they need it to. What if we told you there was an easy way to do it?

This article will describe the steps you need to take to overwrite or rewrite a controller in Magento 2 to tailor the platform to your needs.

In Magento 2, you can rewrite or override a controller by creating a custom module. Here's a step-by-step guide on how to achieve this, including routing:

Overriding controller in Magento 2

Step 1: Create a Custom Module

Create a new module in the app/code directory of your Magento 2 installation. For example, let's call the module "Custom_Module".

# Replace Vendor_Module with your actual vendor and module name
mkdir -p app/code/Vendor/ModuleName

Step 2: Declare the Module

Create the registration.php file to register your module.

# app/code/Vendor/ModuleName/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_ModuleName',
__DIR__
);

Step 3: Create Module Configuration

Create the module.xml file to define the module configuration.

# app/code/Vendor/ModuleName/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_ModuleName" setup_version="1.0.0"/>
</config>

Step 4: Create a Controller Class

Create your custom controller class by extending the original controller you want to override.

# app/code/Vendor/ModuleName/Controller/Path/To/OriginalController.php
<?php
namespace Vendor\ModuleName\Controller\Path\To;

class OriginalController extends \Magento\Catalog\Controller\Category\View
{
// Your custom controller logic here
}

Step 5: Create a di.xml file

Create a di.xml file to configure the dependency injection.

# app/code/Vendor/ModuleName/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Controller\Category\View" type="Vendor\ModuleName\Controller\Path\To\OriginalController" />
</config>

Step 6: Create a routes.xml file

Create a routes.xml file to configure the custom route.

# app/code/Vendor/ModuleName/etc/frontend/routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="custom" frontName="custom">
<module name="Vendor_ModuleName"/>
</route>
</router>
</config>

Step 7: Verify and Enable the Module

Run the following commands from your Magento 2 root directory to enable the module:

bin/magento module:enable Vendor_ModuleName
bin/magento setup:upgrade
bin/magento cache:flush

Now, your custom controller should be in effect, and you can access it using the custom route, for example: http://yourmagento.com/custom/path/to/originalcontroller.

Remember to replace "Vendor_ModuleName" with your actual vendor and module names, and "Path\To" with the actual path to the original controller. Additionally, modify the controller logic as needed for your specific requirements.

Rewriting controller in Magento 2

In Magento 2, you can rewrite controllers without using preferences by using the method of routing. This involves creating a new controller and specifying it in the routes.xml file. Here's a step-by-step guide:

Step 1. Create a new controller

Create a new controller file in your custom module. The controller should be located at app/code/[Vendor]/[Module]/Controller/[Controller]/[Action].php. Replace [Vendor], [Module], [Controller], and [Action] with your actual values.

For example, if you want to override the 'Index' controller's 'execute' action from the 'Magento_Catalog' module, you might create the following file:

// app/code/[Vendor]/[Module]/Controller/Index/Index.php

namespace [Vendor]\[Module]\Controller\Index;

class Index extends \Magento\Catalog\Controller\Category\View
{
public function execute()
{
// Your custom code here
}
}

Step 2. Create a routes.xml file

In the same module, create a routes.xml file at app/code/[Vendor]/[Module]/etc/frontend/routes.xml. This file will define the new route and map it to the controller.

<!-- app/code/[Vendor]/[Module]/etc/frontend/routes.xml -->
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="[route_id]" frontName="[front_name]">
<module name="[Vendor]_[Module]" before="[Magento_Module]" />
</route>
</router>
</config>

Replace [route_id], [front_name], [Vendor], [Module], and [Magento_Module] with your specific values.

Step 3. Update the controller in routes.xml

In the routes.xml file, the <module> node includes the 'before' attribute, which specifies the module that contains the original controller you want to override.

Step 4. Clear the cache

After making these changes, clear the Magento cache to apply your modifications. You can do this using the following command:

php bin/magento cache:clean

After completing these steps, your custom controller should be invoked instead of the original controller when the specified route and action are accessed. This method allows you to override controllers without using the preference approach, making it more flexible and modular.

How can we help you?

Didn’t you find the answer to your question? We are always happy to help you out.