ZF2 Segment Route doesn't match parent's constraint when using children - regex

I created the following routes:
'relatorios' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/relatorios/:tipo',
'defaults' => array(
'controller' => 'Relatorios',
'action' => 'index',
'tipo' => 'normais',
),
'constraints' => array('tipo' => '(normais|administrativos)$',
),
'may_terminate' => true,
'child_routes' => array(
'view' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/view/:id_relatorio',
'defaults' => array('action' => 'view'),
'constraints' => array('id_relatorio' => '[0-9]+'),
),
),
),
);
This is supposed to match the following routes:
/relatorios/normais //matches
/relatorios/administrativos //matches
/relatorios/normais/view/1 //doesn't match
/relatorios/administrativos/view/1 //doesn't match
So basically the :tipo parameter must be either normais or administrativos and there is a child /view/any_digits.
When the parent route is called it matches, when the child view is called it doesn't match because of my tipo constraint. Why is that?

As per my comment, the $ on the constraint means 'end of the string' (which in this case is the URL path), so it shouldn't be there.

Related

ZF2 Routing regexp

I try to validate a route in zend framework 2.
Example:
valid - /foo/overview/1-2015
valid - /foo/overview/9999-2015
invalid /foo/overview/sd-2015
invalid - /foo/overview/10001-2015
I tried this code, but I received 404 error:
'overview' => array(
'type' => 'segment',
'options' => array(
'route' => '/foo/overview/:nr',
'constraints' => array('nr' => '^[0-9]{1,4}-[0-9]{4}$',),
'defaults' => array(
'controller' => 'Foo\Controller\Foo',
'action' => 'overview',
),
),
),
thanks
It is enough to use [0-9]{1,4}-[0-9]{4} for your constraint value, since the starting ^ and the closing $ are automatically added by the framework (check the match function in the Zend\Mvc\Router\Http\Segment class).

zf2 regex routing

I am struggling with regex routing....
The following urls should be valid:
/shop/api/list
/shop/api/cart
/shop/api/login
/shop/api/details/0123456789
And the details url, the last one, is not really cooperating with the following route:
'child_routes' => array(
'angularlist' => array(
'type' => 'Regex',
'options' => array(
'regex' => '/api/(?<page>login|cart|list|details(?<id>\/[0-9]+))',
'spec' => '/api/%page%[/:%id%]',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
//'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => 'list',
// 'param' => '[0-9]',
),
/* todo ipv elke child toe te voegen 'route' => '/api/[:action]', 'constraints' => array(
'action' => 'list|details|login|dashboard'
)*/
),
),
)
Instead of struggling with less-readable & dirty regex hacks, you can easily implement a Segment route stack like below:
'shop' => array(
'type' => 'Segment',
'options' => array(
'route' => '/shop/api',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'angularlist' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:action[/:id]', // id is optional
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'action' => 'index',
),
),
),
)

Zend Framework 2 child regex and literal routing

Based on this stackoverflow question 15077075 i have accomplished that my application has a regex based route so i can pass this to my view and edit action.
app/123 - app controller view action (get by article id)
app/name-of-article - app controller view action (get by article name)
app/123/edit - app controller edit action (article id)
app/name-of-article/edit - app controller edit action (article name)
app/search/{search-string} - app controler search action (currently only accepts a searchstring without spaces and special characters)
This i have accomplished with the code below and is similar to the code in the link above:
'app' => array(
'type' => 'literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
'priority' => -1000,
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
'priority' => -1000,
),
I have twoone issue
the first is that the url viewhelper doesn't recognize my routes
$controller = app
$action = recent
$this->url( $controller, array( 'action' => $action ) )
it just prints /app instead of /app/recent,
The same occurs when $action = 'search' or $action = 'new' it only prints /app
the second is that the search is recognized to its controller action only it fails when i put spaces or special characters in it
when i try to add \s in the constraints of the searchkey ( '[\sa-zA-Z0-9_-]+' ) it routes to the edit function
the route of search looks like this
Edited the route to this and it worked
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[a-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
),
),
),
i hope it's clear what i want if any code snippits are needed please ask
Sorted it out!
If one needs to get routes in his application this way you can use the code below
/App App/Index
/App/name-of-article App/View
/App/123 App/View
/App/name-of-article/edit App/Edit
/App/123/edit App/Edit
/App/recent App/Recent
/App/search App/Search
/App/new App/New
In my module.config.php i changed the route to:
'app' => array(
'type' => 'segment',
'options' => array(
'route' => '/app[/:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'priority' => 1,
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[\sa-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
'priority' => 2,
'may_terminate' => true,
),
),
),
'new' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/new',
'defaults' => array(
'controller' => 'App',
'action' => 'recent',
),
),
'priority' => 2,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
),
If you need other routes you can just add a new literal route below te app route, make sure you don't forget to set the priority

YamlDriver for Doctrine2 in Zend2

I'm using the DoctrineORMModule to integrate Doctrine2 with Zend2. Everything works just fine when I'm using the AnnotationDriver as described in various examples. However, I cannot get the YamlDriver to work. In my module.config.php I tried:
'doctrine' => array(
'driver' => array(
'ApplicationDriver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Application/Entity')
),
'YamlDriver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
'cache' => 'array',
'extension' => '.dcm.yml',
'paths' => array(__DIR__ . '/../src/Application/Mapping')
),
'orm_default' => array(
'drivers' => array(
'Application\Entity' => 'ApplicationDriver',
'Application\Mapping' => 'YamlDriver'
)
)
)
)
However, the EntityManager cannot find my classes. Cam you give me a working example of how to use yaml with doctrine2 and zend2?
I assume your entities are in namespace Application\Entity: this means your driver should be assigned for that namespace as in following example:
'doctrine' => array(
'driver' => array(
'MyYamlDriver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
'cache' => 'array',
'extension' => '.dcm.yml',
'paths' => array(__DIR__ . '/mappings')
),
'orm_default' => array(
'drivers' => array(
'Application\Entity' => 'MyYamlDriver',
)
)
)
)
Basically, the configuration maps a particular named driver to a namespace that you want to use. In this case, MyYamlDriver is assigned to handle any mapping for the namespace Application\Entity

ZendFramework: Simple Router_Regex problem

I have never been any good at regular expressions. I am trying to use them in building a simple site. I construct a URL just fine like /some-course/some-vtm-1, but when it tries to lookup the defined controller, it fails. Here is the route I have defined:
chapter' => array(
'type' => 'Zend_Controller_Router_Route_Regex',
'route' => '/:course/:vtm\-(\d+)',
'defaults' => array(
'module' => 'learn',
'controller' => 'chapter',
'action' => 'index'
),
'map' => array(
1 => 'course',
2 => 'vtm',
3 => 'id'
),
'reverse' => '%s/%s-%d/'
),
How should I correct this Regex so it finds the correct module/controller/action when I a link like /some-course/some-vtm-1 is clicked
Your problem is that you're trying to mix the syntax of Zend_Controller_Router_Route (named variables in the route starting with :) and Zend_Controller_Router_Route_Regex (bracketed regular expression patterns in the route). You want to drop the former and just use the regexp syntax, leaving you with something like this:
array(
'type' => 'Zend_Controller_Router_Route_Regex',
'route' => '([\w]+)/(vtm)-([\d]+)',
'defaults' => array(
'module' => 'learn',
'controller' => 'chapter',
'action' => 'index'
),
'map' => array(
1 => 'course',
2 => 'vtm',
3 => 'id'
),
'reverse' => '%s/%s-%d'
),