Zend Framework 2 - route parameters after <home> route - php

I am trying to solve the routing problem I am facing right now with no luck (googled for hours, saw dozens of examples and solved questions but none works for me - the closest one is this Routing Zend Framework 2 Language in url but even this is not working for me).
I have created an SSO application (I mean the authentication part) and now I am porting it to ZF2 app (I have it almost working as I workarounded the router but need now the final routing to be done) where only these types of URLs are possible:
http[s]://domain.com/login/asfgsdgdsfgzsdgdsf/
http[s]://domain.com/login/tdhjsdgbndfnfgdnhd/
http[s]://domain.com/logout/asfgsdgdsfgzsdgdsf/
http[s]://domain.com/info/dthnzdfbdfhgnfsd/
Those login, logout or info parts are not the controllers nor actions but the methods names I then call on SSO service from within my IndexController and indexAction(). The rest part of the URL is the client application hash.
Now here is my router config which only matches the home route and when the other parts (method name [and hash]) are provided, I got 404 from the ZF2 app (so at least I am in the app context).
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'SSO\Controller\Index',
'action' => 'index',
'act' => 'login', // by doing this I am able to workaround the router and work with SSO
'client' => '<my_secret_hash>', // by doing this I am able to workaround the router and work with SSO
),
),
'child_routes' => array(
'action' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '[/:act]',
'defaults' => array(
'act' => 'login',
),
'constraints' => array(
'act' => '(login|logout|info)?', // only login, logout or info are allowed
),
),
'child_routes' => array(
'client' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '[/:client]',
'constraints' => array(
'client' => '[a-zA-Z0-9]+',
),
'defaults' => array(
'client' => '<my_secret_hash>',
),
'may_terminate' => true,
),
),
),
),
),
),
),
);
(only router part of my module.config is provided...)
Now with that router only http[s]://domain.com[/] is matched and either of http[s]://domain.com/(login|logout|info)[/] or http[s]://domain.com/(login|logout|info)/adfbsDVdfbzdbxfbndzxbxfnb[/] matches into A 404 error occured.
Though I try to define the route parts as optional (just for the testing and development purposes), they should by required in the production environment. Anyway, I tried to define them NOT optional too, but didn't work either.
Question: How should I configure the router to match my routes (URLs) defined in the beginning?

Couple of things:
My guess is that you have too many slashes in there -- a child route of / doesn't need to be defined with a slash at the beginning since it's parent already got it
I don't see a reason for 2 nested routes (of course I don't know the rest of your config, so it's a guess)
home route probably should be Literal and able to terminate (again a guess)
there was one unmatched parenthesis (probably 'misspasted' or something)
I suppose this should work for you:
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Literal',
'may_terminate' => true,
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'SSO\Controller\Index',
'action' => 'index',
),
),
'child_routes' => array(
'whateva' => array(
'type' => 'Segment',
'may_terminate' => true,
'options' => array(
'route' => '[:act[/:client]]', // as Sam suggested
'defaults' => array(
'act' => 'login',
'client' => 'fsadfasf32454g43g43543',
),
'constraints' => array(
'act' => '(login|logout|info)',
'client' => '[a-zA-Z0-9]+',
),
),
),
),
),
),
),

Related

ZF2 error 404 when child_routes

This is my last chance. I tried loooking for answers, but seriously, I can't see what I'm doing wrong...
I'm trying to set up a multi-domain on a website.
Everything is working fine when using literal routes.
When adding the other domain with Hostname route, still OK.
But when adding child_routes to that Hostname route, the parent route shoots a 404.
Here's my module.config :
'resources' => $resources,
'router' => array(
'routes' => array(
'example.com' => array(
'type' => 'Zend\Mvc\Router\Http\Hostname',
'options' => array(
'route' => '[:subdomain.]:domain.:tld', // domain levels from right to left
'contraints' => array(
'subdomain' => 'www',
'domain' => 'example',
'tld' => 'com',
),
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'itdoc',
),
),
'may_terminate' => true,
'child_routes' => array(
'customCatalog2' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/custom-catalog',
'defaults' => array(
'action' => 'customCatalog',
),
),
),
When accessing http://example.com, I'm getting a 404.
But the child route works fine (http://example.com/custom-catalog)
But if I comment out the child_routes (and may_terminate), I can access the root domain
Do you have any clue of what is wrong with my code ?
Thanks !!!
I test your code and in fact this is weird, but after some test and read the docs here is what i Found.
This documentaiton help
^
I looked forward to this component and found in the docs this :
'packages.zendframework.com' => array(
'type' => 'Zend\Mvc\Router\Http\Hostname',
'options' => array(
'route' => ':4th.[:3rd.]:2nd.:1st', // domain levels from right to left
'contraints' => array(
'4th' => 'packages',
'3rd' => '.*?', // optional 3rd level domain such as .ci, .dev or .test
'2nd' => 'zendframework',
'1st' => 'com',
),
// Purposely omit default controller and action
// to let the child routes control the route match
),
// child route controllers may span multiple modules as desired
'child_routes' => array(
'index' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Package\Controller\Index',
'action' = > 'index',
),
),
'may_terminate' => true,
),
),
),
As you can see, they have child route but the first route declared is the route match this pattern : '/', this is your main route you have to declare this equal to your code below :
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'itdoc',
),
After that, your main route is correct and you can continue with other child route, just the hostname is not the actual main route '/'.

how to create an optional route parameter for zend framework 2 restful route

I'm working with zend framework 2 and I need to create an optional parameter for a route segment that also has two required parameters. Below is a snippet from the module.config.php describing the route. My understanding is that in ZF2 an optional route parameter can be created by using the
[/:param]
which you can see is what I have. It works fine as long as I send the optional param, but when I leave it out the first two params "uname and appname" are appended together into the "uname" constraint. The route is a parent route.
'roles' => array(
'type' => 'segment',
'options' => array(
'route' => '/roles/:uname/:appname[/:locnames]',
'constraints' => array(
'uname' => '[a-zA-Z].+',
'appname' => '[a-zA-Z0-9_-].+',
'locnames' => 'locnames'
),
'defaults' => array(
'controller' => 'Roles/Controller/RolesController'
),
),
),
What am I missing here, I know you can have define optional parameters, but I can't figure out the correct format
Thanks to grizzm0 on #zftalk or helping me with this one. It was a simple regular expressions issue. Removing the dot(.) in the constraints correctly matched the incoming url parameters. So my route now looks like this:
'roles' => array(
'type' => 'segment',
'options' => array(
'route' => '/roles[/:action][/uname/:uname][/appname/:appname][/locnames/:locnames]',
'constraints' => array(
'uname' => '[a-zA-Z]+',
'appname' => '[a-zA-Z0-9_-]+',
'locnames' => 'locnames'
),
'defaults' => array(
'controller' => 'Roles/Controller/RolesController'
),
),
),
'roles' => array(
'type' => 'segment',
'options' => array(
'route' => '/roles[/:action][/uname/:uname][/appname/:appname][/locnames/:locnames]',
'constraints' => array(
'uname' => '[a-zA-Z].+',
'appname' => '[a-zA-Z0-9_-].+',
'locnames' => 'locnames'
),
'defaults' => array(
'controller' => 'Roles/Controller/RolesController'
),
),
),
You can configure your route like this way.
Here inside your roles controller
you have some action live index.
so your route will be
siteurl/roles/index/uname/john/appname/stackexchange/locanames/yourlocanames
here if you don't want to write appname then remove youre paramater so your route will work.

Zend2 - ZF2 - Routing Issue

i am trying to make my router working so that:
/Auth redirects to Auth controller of Auth MOdule
/Auth/Login redirects to Login controller of Auth Module
While the first works just right the /Auth/Login results in routing issue.
My router configuration file looks like below:
'router' => array(
'routes' => array(
'Auth' => array(
'type' => 'literal',
'options' => array(
'route' => '/Auth',
'defaults' => array(
'controller' => 'Auth\Controller\Auth',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'Auth/Login' => array(
'type' => 'literal',
'options' => array(
'route' => '/Login',
'defaults' => array(
'controller' => 'Auth\Controller\Login',
'action' => 'index')
),
),
),
),
),
),
edit this section
'child_routes' => array(
'Auth_Login' => array(
// ... your existing codes
Just remove / from Auth/Login and use hyphen - or _ instead.
The answer lies in #TimFountain his comment. Because you named the child route Auth/Login you will have to request Auth/Auth/Login to get a match.
As soon as you rename the child route to Login you will get the route match as expected on Auth/Login.

ZF2 - Language Routes

I need to create a router configuration in Zend Framework 2 like:
http://www.example.com/en
http://www.example.com/fr
http://www.example.com/es
Then the route of the modules like my "cms" module must match:
http://www.example.com/en/cms/test.html (english version)
http://www.example.com/fr/cms/test.html (french version)
http://www.example.com/es/cms/test.html (spanish version)
of course this link must match the english default language:
http://www.example.com/cms/test.html (english version)
I have already used the SimLocale without success because it doesn't handle the asset links as well. So I prefer to handle the language selection manually by a simple parameter for all my custom modules.
The question has been solved on #zftalk IRC today (thanks Michelangelo to contribute back based one what we explained to you...).
To solve the problem, we had to have a look at the defined routes:
'router' => array(
'routes' => array(
'language' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:lang]',
'defaults' => array(
'__NAMESPACE__' => 'Cms\Controller',
'controller' => 'Index',
'action' => 'page',
'lang' => 'en',
'slug' => 'homepage'
),
'constraints' => array(
'lang' => '[a-z]{2}'
)
),
'may_terminate' => true,
'child_routes' => array(
'list' => array(
'type' => 'Segment',
'options' => array(
'route' => '/cms',
'defaults' => array(
'__NAMESPACE__' => 'Cms\Controller',
'controller' => 'Index',
'action' => 'index',
'page' => 1
),
),
),
'page' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:slug].html',
'constraints' => array(
'slug' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'page',
),
),
),
'search' => array(
'type' => 'Segment',
'options' => array(
'route' => '/search/[query/:query]',
'constraints' => array(
'query' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'action' => 'search',
'query' => null,
),
),
),
'paginator' => array(
'type' => 'Segment',
'options' => array(
'route' => '/list/[page/:page]',
'constraints' => array(
'page' => '[0-9]*',
),
'defaults' => array(
'page' => 1,
),
),
),
),
),
Then, the updated description of the problem was the following:
mikunos: http://www.example.com/en (homepage) this is ok
mikunos: http://www.example.com/en/cms (cms list) this is ok
mikunos: http://www.example.com/en/cms/about.html (page) this not
Which have led us on changing the 'page' route as a child route of 'list' (/cms).
Then the discussion finished with indications on what to do to setup the default language if none have been selected:
mikunos: as you have seen I need two main routes
mikunos: the first one is /lang/module and the second one is /module
mikunos: so I have to create two branches
mikunos: right?
tdutrion: you may want to use an url rewriting or something here
tdutrion: I would go for a redirect 301 from /module to /en/module so you have no duplicate content
tdutrion: and then no route can be accessed without a language
mikunos: ok
tdutrion: you can do it different ways, but I think the best one would be creating a event listener and do that before routing
tdutrion: you can also do it in your .htaccess of you are using apache, but then what if you migrate to IIS or Ngnix or else...
mikunos: interesting
tdutrion: again I believe Jurian Sluiman’s code does that
You can use subdomains for each language you need witch I suppose you don't want or you really don't need (eg. /en) to change the language of your application and/or web site. Is mandatory to use /en, /fr, etc.?

Zend Framework 2 Routing subdomains to module

After searching a long time with no success.
before I give up, I would like to ask:
Is there a way to route a subdomain to a module in Zend Framework 2? like:
Subdomain => Module
api.site.com => api
dev.site.com => dev
admin.site.com => admin
site.com => public
...
I tried doing it like this but I can't get access to controllers other than the default (Index).
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Thank you for taking the time to help me.
Zend Framework 2 doesn't have a notion of routing to modules; all routing mappings are between a URI pattern (for HTTP routes) and a specific controller class. That said, Zend\Mvc provides an event listener (Zend\Mvc\ModuleRouteListener) which allows you to define a URI pattern that maps to multiple controllers based on a given pattern, and so emulates "module routing". To define such a route, you would place this as your routing configuration:
'router' => array(
'routes' => array(
// This defines the hostname route which forms the base
// of each "child" route
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This Segment route captures the requested controller
// and action from the URI and, through ModuleRouteListener,
// selects the correct controller class to use
'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(
'controller' => 'Index',
'action' => 'index',
),
),
),
),
),
),
),
(Click here to see an example of this # ZendSkeletonApplication)
This is only half of the equation, though. You must also register every controller class in your module using a specific naming format. This is also done through the same configuration file:
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
The array key is the alias ModuleRouteListener will use to find the right controller, and it must be in the following format:
<Namespace>\<Controller>\<Action>
The value assigned to this array key is the fully-qualified name of the controller class.
(Click here to see an example of this # ZendSkeletonApplication)
NOTE: IF you aren't using ZendSkeletonApplication, or have removed it's default Application module, you will need to register the ModuleRouteListener in one of your own modules. Click here to see an example of how ZendSkeletonApplication registers this listener
If i understand slide #39 of DASPRIDS Rounter Presentation correctly, it's as simple as - on a per module basis - to define your subdomain hosts, i.e.:
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'api.site.com',
'defaults' => array(
'__NAMESPACE__' => 'Api\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Etc, you'd do this for every Module on its own.

Categories