0

May be i'm missing something really small.

Here is a class Class1

namespace Vendor\Module\Helper;
class Class1 extends AbstractHelper
{
    /** @var Client */
    private $client;

    /** @var ConfigHelper */
    private $config;

    public function __construct(
        Context $context,
    ){
        parent::__construct($context);

        $this->config = $configHelper;
        //stuff are here
    }

Here is Class2 which i want to override

namespace Vendor\Module\Helper;
use Vendor\Module\Helper\Class1;

class Data
{

    private $class1Helper;
    private $pageHelper;
    private $productHelper;
    private $storeManager;

    public function __construct(
        Class1 $class1Helper,
        ConfigHelper $configHelper,
        PageHelper $pageHelper,
        StoreManagerInterface $storeManager
    ) {

        $this->class1Helper = $class1Helper ;
        $this->configHelper = $configHelper;
        $this->pageHelper = $pageHelper;
        $this->storeManager = $storeManager;
    }

Now Here is my class. Added preference in di.xml

<preference for="Vendor\Module\Helper\Data" type="Vendornew\Module\Helper\Data"/>
namespace Vendornew\Module\Helper;

class Data extends \Vendor\Module\Helper\Data;
{
    public function __construct(
        Class1 $class1Helper,
        ConfigHelper $configHelper,
        PageHelper $pageHelper,
        StoreManagerInterface $storeManager
    ) {

        $this->class1Helper = $class1Helper ;
        parent::__construct(
            $class1Helper,
            $configHelper,
            $pageHelper,
            $storeManager
        );
    }

    public function getSomething()
    {
        return 'something';
    }
}

Any idea why it gives Vendor\Module\Helper\Data doesn't extends Magento\Framework\App\Helper\AbstractHelper

0

I not sure I get your question 100% but you are getting that message because your class \Vendor\Module\Helper\Data probably needs to extend Magento\Framework\App\Helper\AbstractHelper.

Could you please explain what it is you're attempting to do, maybe with links to the code source or actual classes. This is very abstract.

Why does Class1 Matter if it's Class 2 that you want to override?

The more I look at this the more I believe you're trying to change the helper that is injected in a class. You don't need to set a preference for that. Preferences are global. If all you want is to change the injected type for a single class I would suggest using type instead of preference in your di.xml file.

For instance :

    <type name="Vendor\Module\Helper\Data">
        <arguments>
            <argument name="class1Helper" xsi:type="object">
                Vendornew\Module\Helper\Data
            </argument>
        </arguments>
    </type>

In this case, your Vendornew\Module\Helper\Data class extends Vendor\Module\Helper and then only the Vendor\Module\Helper\Data class will have the change. Because if you use a preference, other classes might make use of that helper too, so your changes might have unwanted impacts.

Ok, let me try to make this a bit more clear... Say we have these classes:


class Helper1 extends Magento\Framework\App\Helper\AbstractHelper {
    public function __construct(
        \Magento\Framework\App\Helper\Context $context
    ) {
        parent::__construct($context);
    }

    public function tellMeYourName()
    {
        return "Helper1"; // I want to change this value!
        // Question you need to ask yourself is do you need to change this
        // every where in the code base or just in a certain use case?
    }
}

class ClassThatUsesHelper1 {

    /**
     * @var \Helper1
     */
    protected $helper1;

    public function __construct(
        Helper1 $helper1
    ) {
        $this->helper1 = $helper1;

        // I would like the result here to be NewHelper2
        $result1 = $helper1->tellMeYourName();
    }
}

class OtherClassThatUsesHelper1 {
    /**
     * @var \Helper1
     */
    protected $helper1;

    public function __construct(
        Helper1 $helper1
    ) {
        $this->helper1 = $helper1;

        // But this class also uses it and here I would like the result to 
        // remain Helper1
        $result2 = $helper1->tellMeYourName();
    }
}

class NewHelper2 extends Helper1 {
    //this class extends Helper 1 but changes the name it returns
    public function __construct(
        \Magento\Framework\App\Helper\Context $context
    ) {
        parent::__construct($context);
    }

    public function tellMeYourName()
    {
        return "NewHelper2";
    }
}

Now if you use a preference like this both of the results $result1 and $result2 will change.

<preference for="Helper1" type="NewHelper2"/>

But if instead you only change the argument for ClassThatUsesHelper1 then the reuslt in OtherClassThatUsesHelper1 will not be affected.

<type name="ClassThatUsesHelper1">
    <arguments>
        <argument name="helper1" xsi:type="object">NewHelper2</argument>
    </arguments>
</type>

I hope this helps but I believe you should share more information on what is the goal, what do you want to change? That way you'll get a more clear answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.