zend-framework2zend-framework-routing

Zend Framework 2 - Segment Route


I'm building an app using Zend Framework v2.2.0 and I'm creating different modules for each section.

In a module, called Company, there is this route:

'company_wines' => array(
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(
        'route'    => '/:slug_company/:action/',
        'constraints'=>array(
            ':slug_company'=>'[a-zA-Z0-9\-_]+',
            ':action'=>'(wines|red\-wines|white\-wines|sparkling\-wines|dessert\-wines|rose\-wines){1}',
        ),
        'defaults' => array(
            'controller' => 'Company\Controller\Company',
        ),
    ),
),

In another module, called Vineyard, I have this route:

'vineyard_page' => array(
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(
        'route'    => '/vineyard/:slug_vineyard/',
        'constraints'=>array(
            ':slug_vineyard'=>'[a-zA-Z0-9\-_]+',
        ),
        'defaults' => array(
            'controller' => 'Vineyard\Controller\Vineyard',
            'action'     => 'vineyard',
        ),
    ),
),

When I test with url domain.ext/Company-name/red-wines/ or domain.ext/Company-name/white-wines etc, the Company controller is invoked.

If I test with domain.ext/vineyard/Vineyard-name/, the Vineyard controller is not invoked, is still invoked the Company one and the error message say that the controller cannot dispatch the request. Off course there is no method called VineyardnameAction() in CompanyController class.

I was expecting that the route match against the list of values specified on regex for :action, also if the :slug_company regex match the "flag" vineyard, then there is no action that match the Vineyard-name part...

If I test the :action regex with preg_match_all, nothing is found in a string like domain.ext/vineyard/Vineyard-name/.

If I disable Company module or delete the the company_wines route, vineyard route is working.

I've solved creating different routes for each wines types, but I would like to understand whath I'm doing wrong :)


Solution

  • Your syntax is wrong:

    'constraints' => array(
        'slug_vineyard'=>'[a-zA-Z0-9\-_]+',
    ),
    
    'constraints'=>array(
        'slug_company'=>'[a-zA-Z0-9\-_]+',
        'action'=>'(wines|red\-wines|white\-wines|sparkling\-wines|dessert\-wines|rose\-wines){1}',
    ),
    

    remove the colon from the default / constraints section and it should work fine.

    As you have put the colon in there the constraints aren't being forced so default constraints will be used, which ever route comes first will match.