Magento – How to Override or Extend protected or parent function in Magento 2 using Plugin

magento2overridespluginvirtualtype

I need to override protected function or parent function ex

Magento\Checkout\Controller\Cart\Add is extended from Magento\Checkout\Controller\Cart

and getBackUrl() is a Magento\Checkout\Controller\Cart function, in this case how to do it

as per this post Overwriting the Magento\Checkout\Controller\Cart\Add::getBackUrl with Plugin

I tried to implement using virtualType but not working
in di.xml

<virtualType name="myUrlBulder" type="Magento\Framework\Url">
     <arguments>
        <argument name="cust-add-url" xsi:type="object">Magento\Checkout\Controller\Cart\Add</argument>
    </arguments>
</virtualType>  
<type name="myUrlBulder">
    <plugin name="custom-url" type="Sugarcode\Test\Model\Plugin\Product" sortOrder="1"/>
</type>

in Model/Plugin/Product.php

protected function afterGetBackUrl(\Magento\Checkout\Controller\Cart\Add $subject, $result)
{
    print_r($result); exit;
    return $this->_url->getUrl('some/custom/url');
}

I use plugin for other function that working fine,
I can also achieve it by preference but I need it implement using plugin
can any one help on this

and also i tried below way also , this plugin for same to change url but at the time of update cart

<virtualType name="myCustomUrl" type="Magento\Framework\Url" />
    <type name="Magento\Checkout\Controller\Cart\UpdatePost">
        <arguments>
            <argument name="url" xsi:type="object">myCustomUrl</argument>
        </arguments>
    </type>
    <type name="myCustomUrl">
        <plugin name="my-custom-url-plugin" type="Sugarcode\Test\Model\Plugin\Cart" sortOrder="10"/>
    </type>

and in cart.php

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Model\Plugin;



class Cart
{       


    public function aroundGetUrl(\Magento\Framework\Url $subject, \Closure $proceed)
    {
        echo 'aroundGetUrl<br>';
        $returnValue = $proceed(); // it get you old function return value
        //$name='#'.$returnValue->getName().'#';
        //$returnValue->setName($name);
        echo 'aroundGetUrl <br>';
        exit;
        return $returnValue;// if its object make sure it return same object which you addition data
    }
}

can any one suggest me how to do it

Best Answer

\Magento\Checkout\Controller\Cart::getBackUrl() is protected method and that's why it cannot be pluginized. Plugins can be created only for public non-static methods.

In the provided example with virtual type, virtual URL should be passed as an argument to action controller, not vice versa. Something like this:

<virtualType name="myCustomUrl" type="Magento\Framework\Url">
    <plugin name="my-custom-url-plugin" type="VendorName\ModuleName\Model\Plugin\CustomUrlPlugin"/>
</virtualType>
<virtualType name="myCustomContext" type="Magento\Framework\App\Action\Context">
    <arguments>
        <argument name="url" xsi:type="object">myCustomUrl</argument>
    </arguments>
</virtualType>
<type name="Magento\Checkout\Controller\Cart\Add">
    <arguments>
        <argument name="context" xsi:type="object">myCustomContext</argument>
    </arguments>
</type>

Plugin content:

<?php
namespace VendorName\ModuleName\Model\Plugin;

use Magento\Framework\UrlInterface;

class CustomUrlPlugin
{
    public function aroundGetUrl(UrlInterface $subject, \Closure $proceed, $routePath = null, $routeParams = null)
    {
        if ($routePath === 'checkout/cart') {
            return "custom_url_goes_here";
        }
        return $proceed($routePath, $routeParams);
    }
}

All the above should work, but plugins declared for virtual types are not executed at the moment (internal issue MAGETWO-46041).

As a workaround try to declare plugin directly for UrlInterface in frontend area and implement conditional logic so it works only in necessary cases. Also make sure that return $this->_url->getUrl('checkout/cart') is invoked by \Magento\Checkout\Controller\Cart::getBackUrl() (it is invoked conditionally).

Related Topic