Accessing the ServiceManager from the ViewHelperManager in ZF2

Sometimes the new ServiceManager(s) in Zend Framework 2 are a bit confusing. We don’t have one, we have several instances.

So recently I was writing a factory for a ViewHelper and wanted to access the application configuration from there. As usual, I was attempting it like this

    /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return MyConfiguration
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $instance       = new MyConfiguration();
        $configuration  = $serviceLocator->get('configuration');

        // haha - nope!

        if(!empty($configuration['whatever'])) {
            $instance->setConfiguration($configuration['whatever']);
        }

        return $instance;
    }

It ended up throwing an exception, saying the configuration could not be found. To make it short, after some searching I found this one

$serviceManager = $serviceLocator->getServiceLocator();

Intuitive, isn’t it? But it seems to work, so the factory looks like this now:

     /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return MyConfiguration
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serviceManager = $serviceLocator->getServiceLocator();
        $instance       = new MyConfiguration();
        $configuration  = $serviceManager->get('configuration');

        if(!empty($configuration['whatever'])) {
            $instance->setConfiguration($configuration['whatever']);
        }

        return $instance;
    }

URL ViewHelper and Child Routes in ZF2

Given this route configuration for a module

  'router' => array(
        'routes' => array(
            'test' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/test',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Test\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'default' => array(
                        'type'    => 'Segment',
                        'options' => array(
                            'route'    => '/[:controller[/:action]]',
                            'constraints' => array(
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                            ),
                            'defaults' => array(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),

I wanted to create an URL using the ViewHelper which directly links to an action of the Index Controller, e.g.

/test/index/my-action

To achieve this, it is important (and not so obvious, maybe) to append the name of the child route to the name of the parent route separated with a slash, e.g.

echo $this->url(
          'test/default', 
          array('action' => 'my-action', 'controller' => 'index')
        );

otherwise the helper won’t care about the child route and only link to /test. Tricky…