zend-framework2routerzend-config

ZF2 router configuration


I'm newbie in ZF2, but I try to write an application. And I faced a problem with invokables and routing config.

I have 2 modules with configs:

<?php
return array(
'controllers' => array(
    'invokables' => array(
        'Index' => 'Vocabulary\Controller\IndexController'
        ,'Add' => 'Vocabulary\Controller\AddController'
        ,'Admin' => 'Vocabulary\Controller\AdminController'
    )
)
,'router' => array(
    'routes' => array(
        'vocabulary' => array(
            'type' => 'segment'
            ,'options' => array(
                'route' => '/vocabulary[/:controller][/:action]'
                ,'constraints' => array(
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
                    ,'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
                )
                ,'defaults' => array(
                    'controller' => 'Index'
                    ,'action' => 'index'
                )
            )
        )
    )
)

and

<?php
return array(
'controllers' => array(
    'invokables' => array(
        'Admin' => 'Lang\Controller\AdminController'
        ,'Translation' => 'Lang\Controller\TranslationController'
    )
)
,'router' => array(
    'routes' => array(
        'lang' => array(
            'type' => 'segment'
            ,'options' => array(
                'route' => '/lang[/:controller][/:action]'
                ,'constraints' => array(
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
                    ,'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
                )
                ,'defaults' => array(
                    'controller' => 'Admin'
                    ,'action' => 'index'
                )
            )
        )
    )
)

But on page /vocabulary/admin I see content of page /lang/admin. It seems, that problem is that invokable array's keys "Admin" are equal. How can I modify my config to make application work correctly? I want to keep "lang/admin" and "vocabulary/admin" paths.

I tried to use "Vocabulary\Controller\Admin" instead of "Admin" as invokable key, but it didn't help.

UPDATE

I solved the problem using this variant of configuration (I hope it will be helpful for somebody):

return array(
'controllers' => array(
    'invokables' => array(
        'Lang\Controller\Admin' => 'Lang\Controller\AdminController'
        ,'Lang\Controller\Translation' => 'Lang\Controller\TranslationController'
    )
)
,'router' => array(
    'routes' => array(
        'lang' => array(
            'type' => 'Literal'
            ,'options' => array(
                'route' => '/lang'
                ,'defaults' => array(
                    '__NAMESPACE__' => 'Lang\Controller',
                    'controller' => 'Lang\Controller\Admin'
                    ,'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(
                        ),
                    ),
                ),
            ),
        )
    )
)

In this case view helper command $this->url('lang', array('controller' => 'translation')) returns only "lang/", but I use $this->serverUrl('/lang/translation'); Both of modules work correctly.


Solution

  • To answer the last part of your question (as I agree with @ChanlderTi on the first part) :

    In this case view helper command $this->url('lang', array('controller' => 'translation')) returns only "lang/"

    This is because the "lang" route is a literal defining only "lang/". What you're trying to do is define the child route's url, whose full route name is "lang/default". So your code should be :

    $this->url('lang/default', array('controller' => 'translation'))
    

    You should probably define a default action for the child route also. Although I don't remember if the Router will default to index if no action is specified.