1

For example, I've to override class Magento\Store\Block\Switcher to Vendor\Module\Block\Switcher Now I need to add custom method, constructor, and protected variable in upgraded class Vendor\Module\Block\Switcher.

I've tried following code but it's not working

Add code like below in /etc/frontend/di.xml file.

<?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\Store\Block\Switcher" type="Vendor\Module\Block\Switcher\Index" />
   </config>

Add below code in my override class Vendor\Module\Block\Switcher

<?php 
namespace Vendor\Module\Block\Switcher;

class Index extends \Magento\Framework\View\Element\Template
{

  protected $httpContext; //new variable

  public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Framework\App\Http\Context $httpContext, // Inject New Class Just before Data array if you want to inject
    array $data = []
    ) {

      $this->_postDataHelper = $postDataHelper;
      $this->httpContext = $httpContext; //New object Get of Injected Class
      parent::__construct($context, $data);
    }

    /**
     * Code by devloper
     */
    public function isLoggedIn()
    {
        return (bool)$this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
    }

    /**     
     * Code by developer
     */
    public function getBankUrl()
    {
        if (!$this->isLoggedIn()) {
            return '<li class="customer-login"><a href="javascript:void(0);">Bank sd</a></li>';
        } else {
            return '<li class=""><a href="'.$this->getUrl('rewards/referral').'">Bank</a></li>';        
        }
    }
}

?>
Aasim Goriya
  • 5,444
  • 2
  • 28
  • 53

3 Answers3

3

1 : Copy that block to your Module in Block Folder and override Using di.xml file in your custom module like :

A. find or add di.xml file at below location :

   /app/code/Vendor/Module/etc/frontend/di.xml

B. Add Code Like Below in di.xml file :

   <?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\Store\Block\Switcher" type="Vendor\Module\Block\Switcher" />
   </config>

2 : Change namespace According to your module on top

 namespace Magento\Store\Block\Switcher => namespace Vendor\Module\Block\Switcher

3 : Defining New Protected Variable , Injecting New Class, Defining New Function, Calling New function in Template File

    namespace Vendor\Module\Block\Switcher;
    class Index extends \Magento\Framework\View\Element\Template
    {

       protected $newVariable; //new variable

       public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
          /** All already injected classes**/,
          \Vendor\Module\Model\ModelClass $modelClassObject, // Inject New Class Just before Data array if you want to inject
          array $data = []
      ) {

          /** All Alreay Defined Variable**/
          $this->newVariable = $modelClassObject; //New object Get of Injected Class
          parent::__construct($context, $data);
       }

       /** New Function **/
       public function newFunction(){

       }
     }

4 : You Can get New Function in Associated template/view file like :

    $this->newFunction(); or $block->newFunction();
Ankita Patel
  • 592
  • 8
  • 31
Sujeet Pandit
  • 391
  • 1
  • 13
1

1.You have to copy whole Switcher Class Block File to your Custom Module BLock File, Donot Remove Any Thing i.e class variables,functions etc from Copied Class in your module .

  1. di.xml file according to you , Replace Vendor\Module according to yours :

       <?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\Store\Block\Switcher" type="Vendor\Module\Block\Switcher" />
       </config>
    
  2. Answer as you Required :

    <?php                                                                 
    namespace Vendor\Module\Block;  //replace Vendor\Module with your ones
    
    class Switcher extends \Magento\Framework\View\Element\Template
    {
    
      protected $customerSession; //new variable
    
      public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
        \Magento\Customer\Model\Session $session, // Inject Correct Session Class Just before Data array if you want to inject
        array $data = []
        ) {
    
          $this->_postDataHelper = $postDataHelper;
          $this->customerSession = $session; //New object Get of Injected Session Class
          parent::__construct($context, $data);
        }
    
        public function getBankUrl()
        {
            if ($this->customerSession->isLoggedIn()) {
                return '<li class="customer-login"><a href="javascript:void(0);">Bank sd</a></li>';
            } else {
                return '<li class=""><a href="'.$this->getUrl('rewards/referral').'">Bank</a></li>';        
            }
        }
    }
    ?>
    
Sujeet Pandit
  • 391
  • 1
  • 13
0

If you want to extend functionality of Magento\Store\Block\Switcher in your custom block, you should extend your block from the Magento\Store\Block\Switcher but not from \Magento\Framework\View\Element\Template as you do.

<?php 
namespace Vendor\Module\Block\Switcher;

class Index extends \Magento\Store\Block\Switcher {

protected $httpContext; //new variable

public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Data\Helper\PostHelper $postDataHelper, \Magento\Framework\App\Http\Context $httpContext, // Inject New Class Just before Data array if you want to inject array $data = [] ) {

  $this-&gt;_postDataHelper = $postDataHelper;
  $this-&gt;httpContext = $httpContext; //New object Get of Injected Class
  parent::__construct($context, $data);
}

/**
 * Code by devloper
 */
public function isLoggedIn()
{
    return (bool)$this-&gt;httpContext-&gt;getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
}

/**     
 * Code by developer
 */
public function getBankUrl()
{
    if (!$this-&gt;isLoggedIn()) {
        return '&lt;li class=&quot;customer-login&quot;&gt;&lt;a href=&quot;javascript:void(0);&quot;&gt;Bank sd&lt;/a&gt;&lt;/li&gt;';
    } else {
        return '&lt;li class=&quot;&quot;&gt;&lt;a href=&quot;'.$this-&gt;getUrl('rewards/referral').'&quot;&gt;Bank&lt;/a&gt;&lt;/li&gt;';        
    }
}

}

Also pay attention to what you put in the parent::__construct(). You should put there all dependencies which Magento\Store\Block\Switcher block requires.