ZF2 optional route constraints in child routes
Asked Answered
M

2

6

I'm having an issue with an optional constraint in a route that is non-optional in it's children. My routing structure is as follows:

'profile' => [
    'type' => 'segment',
    'options' => [
        'route' => '/profile[/:id]',
        'constraints' => ['id' => '[0-9]*'],
        'defaults' => [
            'controller' => 'User\Controller\User',
            'action' => 'profile'
        ]
    ],
    'may_terminate' => true,
    'child_routes' => [
        'sessions' => [
            'type' => 'literal',
            'options' => [
                'route' => '/sessions',
                'defaults' => ['action' => 'sessions']
            ]
        ]
    ]
]

Which to my mind should give me the following routes:

  1. /profile - works
  2. /profile/123 - works
  3. /profile/sessions - doesn't work
  4. /profile/123/sessions - works

When I use route 3 in the URL view helper I get the following error:

$this->url('profile/sessions');

Zend\Mvc\Router\Exception\InvalidArgumentException: Missing parameter "id"

I originally had [0-9]+ as my constraint but making it optional (*) doesn't seem to have helped. Has anyone experienced this case before?

Marjoriemarjory answered 3/10, 2012 at 16:43 Comment(0)
D
3

I had the same issue once, the only solution I found was to create a separate route (in your case for /profile/sessions) as the optional parameter for the base route, seems to become obligatory when accessing a child route.

Depolarize answered 3/10, 2012 at 18:0 Comment(1)
I ended up taking this route as I prefer to clearly define each route (I dislike 'magical' /:controller[/:action] style routes).Marjoriemarjory
S
8

Add it to your parent route.

'profile' => [
    'type' => 'segment',
    'options' => [                 // ↓ 
        'route' => '/profile[/:id][/:action]',
        'constraints' => [ 'id' => '[0-9]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*' ],
        'defaults' => [
            'controller' => 'User\Controller\User',
            'action' => 'profile',
        ],
    ],
]

This will make it optional to have id and/or action. At least in theory it should make all your listed routes possible, there have been some issues with this.

Sawtoothed answered 5/10, 2012 at 7:51 Comment(0)
D
3

I had the same issue once, the only solution I found was to create a separate route (in your case for /profile/sessions) as the optional parameter for the base route, seems to become obligatory when accessing a child route.

Depolarize answered 3/10, 2012 at 18:0 Comment(1)
I ended up taking this route as I prefer to clearly define each route (I dislike 'magical' /:controller[/:action] style routes).Marjoriemarjory

© 2022 - 2024 — McMap. All rights reserved.