Question

I'm trying to access the service locator in a view helper so i can access to my config. I'm using this view helper for a recursive function so i don't know where to declare the service locator.

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;
use CatMgt\Model\CategoryTable as RecursiveTable;

class CategoryRecursiveViewHelper extends AbstractHelper
{
    protected $table;

    public function __construct(RecursiveTable $rec)
    {
        $this->table = $rec; 
    }

    public function __invoke($project_id, $id, $user_themes_forbidden, $level, $d, $role_level)
    {

       $config = $serviceLocator->getServiceLocator()->get('config');

       //So i can access $config['templates']

       $this->__invoke($val->project_id, $id, $user_themes_forbidden, $level, $d, $role_level);

    }

}

I tried the solution give here link

But it didn't helped, is it all right to do it that way?

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;
use CatMgt\Model\CategoryTable as RecursiveTable;
use Zend\View\HelperPluginManager as ServiceManager;

class CategoryRecursiveViewHelper extends AbstractHelper
{
    protected $table;
    protected $serviceManager;

    public function __construct(RecursiveTable $rec, ServiceManager $serviceManager)
    {
        $this->table = $rec; 
        $this->serviceManager = $serviceManager;
    }

    public function __invoke($project_id, $id, $user_themes_forbidden, $level, $d, $role_level)
    {

       $config = $this->serviceManager->getServiceLocator()->get('config');

       //So i can access $config['templates']

       $this->__invoke($val->project_id, $id, $user_themes_forbidden, $level, $d, $role_level);

    }

}
Was it helpful?

Solution

First of all, your ViewHelper is an infinite loop and your app will crash like that. You call the __invoke within the __invoke - this just can't work.

Registering a ViewHelper with dependencies

First off, you'd write your ViewHelper like:

class FooBarHelper extends AbstractHelper
{
    protected $foo;
    protected $bar;

    public function __construct(Foo $foo, Bar $bar)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }

    public function __invoke($args)
    {
        return $this->foo(
            $this->bar($args['something'])
        );
    }
}

Next comes registering the ViewHelper. As it requires a dependency you're required to use a factory as target.

// module.config.php
'view_helpers' => [
    'factories' => [
        'foobar' => 'My\Something\FooBarHelperFactory'
    ]
]

The target is now a factory-class, that we have yet to write. So onwards to it:

class FooBarHelperFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sl)
    {
        // $sl is instanceof ViewHelperManager, we need the real SL though
        $rsl = $sl->getServiceLocator();
        $foo = $rsl->get('foo');
        $bar = $rsl->get('bar');

        return new FooBarHelper($foo, $bar);
    }
}

Now you're able to use your ViewHelper via $this->foobar($args) in any of your view-files.

Don't ever use the ServiceLocator AS a dependency

Whenever you rely on the ServiceManager as a dependency you're falling down into bad design. Your classes will have dependencies of unknown type and they are hidden. Whenever your class needs some outside data, make it available through the __construct() directly and don't hide the dependencies by injecting the ServiceManager.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top