Question

Is there a clean way to initiate and access a custom helper without using the constructor? Currently I instantiate the custom helper using the constructor of the model as shown here as the accepted answer.

This is great in most cases but now I would like to access a helper method on a model that adds a bit of functionality to the product model - extending \Magento\Catalog\Model\Product. It seems a bit overkill to overwrite this constructor so I am wondering if there is an alternative, acceptable way to do this? Can I just grab it directly via the ObjectManager or roll out my own factory like @philwinkle suggested here or is this not recommended?

Was it helpful?

Solution

the clean way to do it is to inject it in the constructor. Exactly what you are trying to avoid.
Also it can work if you instantiate it via objectManager, but this is discouraged. Even if there are classes instantiated via object manager in the core, this is not the recommended way to do it.
I'm not 100% sure, but I think the suggestion you mention from @philwinke is not valid anymore. That was for an older version. A lot has changed since then.
But even so, if you want to instantiate it via a helper factory, you still need to inject the helper factory in the constructor.
My recommendation is to inject it in the constructor, but if you absolutely don't want that, and you have an instance of the object manager available, instantiate it via object manager.

OTHER TIPS

What really is overkill, is extending the product model to add some functionality.

Depending on what you are trying to achieve, a plugin with interception might suit you better, this plugin again can use its own constructor injection.

Or even better, if possible, move your extended functionality to a completely different class.

Remember these principles:

  • Favor composition over inheritance
  • Don't f***ing rewrite the product model

you can make a plugin for required block/model and extend as you want.

namespace Your\Namespace\Plugin;

class Test
{
    /**
     * @param $subject
     * @param \Closure $proceed
     * @param string $method
     * @param array $args
     * @return string
     */
    public function around__call(
        $subject,
        \Closure $proceed,
        $method,
        array $args
    ) {
        switch($method) {
            case 'iWantMyHelper':
                return $this->_getHelper($args);
        }
        return $proceed($method, $args);
    }

    protected function _getHelper($args)
    {
        return 'I am your helper!';
    }
}

you can call now this method from appropriate block/model/view: echo $this->iWantMyHelper();

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top