How to Override Block, Model, and Controller in Magento 2?

Magento 2 CMS offers flexible options to customize the default configurations. The customized features are helpful to offer enhanced customer experience, easy administration, improved SERPs and sales!

However, it is advisable to override block, model, and controller in Magento 2 than editing the core files. This guide walks you through the method to overriding block, model, controller, giving you the flexibility to make changes in the core functionalities.

The Magento 2 Controller is responsible for handling the incoming requests. Blocks are PHP classes used to connect or create a link between layout and templates. The Model represents the data of the application in MVC.

Method to Override Block, Model, and Controller in Magento 2:

  • Magento 2 override Model class using di.xml

    Use the following code to override Magento\ConfigurableProduct\Model\ConfigurableAttributeDataCreate file [Vendor]\[Module]\etc\di.xml
<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
        <preference for="Magento\ConfigurableProduct\Model\ConfigurableAttributeData" type="[Vendor]\[Module]\Model\Rewrite\ConfigurableAttributeData" />
    </config>

Create a class [Vendor]\[Module]\Model\Rewrite\ConfigurableAttributeData to override Magento Model

<?php
    namespace [Vendor]\[Module]\Model\Rewrite;

    use Magento\Catalog\Api\ProductRepositoryInterface;
    use Magento\Framework\Pricing\Helper\Data;

    class ConfigurableAttributeData extends \Magento\ConfigurableProduct\Model\ConfigurableAttributeData
    {
        private $productRepository;
        private $priceHelper;

        public function __construct(
            ProductRepositoryInterface $productRepository,
            Data $priceHelper
        )
        {
            $this->productRepository = $productRepository;
            $this->priceHelper = $priceHelper;

        }

        protected function getAttributeOptionsData($attribute, $config)
        {
            $attributeOptionsData = [];
            foreach ($attribute->getOptions() as $attributeOption) {

                $optionId = $attributeOption['value_index'];
                $product_details = $config[$attribute->getAttributeId()][$optionId];
                $productId = $product_details[0];
                $product = $this->productRepository->getById($productId);
                $attributeOptionsData[] = [
                    'id' => $optionId,
                    'label' => $attributeOption['label'],
                    'products' => isset($config[$attribute->getAttributeId()][$optionId])
                        ? $config[$attribute->getAttributeId()][$optionId]
                        : [],
                    'sku' => $product->getSku(),
                    'childProductPrice' => $this->priceHelper->currency($product->getFinalPrice(), true, false),
                ];
            }
            return $attributeOptionsData;
        }
    }
  • Magento 2 override block class using di.xmlCreate file : [Vendor]\[Module]\etc\di.xml
<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
        <preference for="Magento\Swatches\Block\Product\Renderer\Configurable" type="[Vendor]\[Module]\Block\Rewrite\Product\Renderer\Configurable" />
    </config>

Create class [Vendor]\[Module]\Block\Rewrite\Product\Renderer\Configurable to override Magento block

<?php
    namespace [Vendor]\[Module]\Block\Rewrite\Product\Renderer;

    class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable
    {

        protected function getRendererTemplate()
        {
            return $this->isProductHasSwatchAttribute() ?
                self::SWATCH_RENDERER_TEMPLATE : '[Vendor]_[Module]::product/view/type/options/configurable.phtml';
        }
    }
  • Magento 2 override controller class using di.xmlCreate file : [Vendor]\[Module]\etc\di.xml
<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
        <preference for="Magento\Catalog\Controller\Product\Gallery" type="[Vendor]\[Module]\Controller\Product\Gallery" />
    </config>

Create class [Vendor]\[Module]\Block\Rewrite\Product\Renderer\Configurable to override Magento block

<?php
    namespace [Vendor]\[Module]\Controller\Product;

    class Gallery extends \Magento\Catalog\Controller\Product\Gallery
    {

        public function execute()
        {
            $result = null;
            if (!$this->_initProduct()) {
                $store = $this->getRequest()->getQuery('store');
                if (isset($store) && !$this->getResponse()->isRedirect()) {
                    $result = $this->resultRedirectFactory->create();
                    $result->setPath('');
                } elseif (!$this->getResponse()->isRedirect()) {
                    // Apply custom code
                }
            }
            return $result ?: $this->resultPageFactory->create();
        }
    }

That’s all to override block, model, and controller in Magento 2!

Happy Customization.