ZF2 error 404 when child_routes - php

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 '/'.

Related

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.

Zend 2 redirect with toRoute not working

Why is Zend 2 such a !##(#(!##??
OK, so I'm trying to get a simple redirect working. I have a controller called 'listitems' with an action called 'editlistitem'. After hours of banging on it with a hand sledge, I've finally got the form to work and the validation to work and the hydration to Doctrine to work so I can save the result.
The last step is to redirect the user to the 'showlistitem' action which includes the id trailing it. (full route sub path is 'listitem/showlistitem/2' where 2 is the id I want to see)
I have tried:
$this->redirect()->toRoute('/listitem/showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem/2');
$this->redirect()->toRoute('showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem', array('id' => 2));
$this->redirect()->toRoute('listitem-showlistitem', array('id' => 2));
None of them flippin work! (they all return route not found)
A route to the controller is in modules.config.php with a child route to the action. I can go directly to the url by typing it in manually and it works fine. How in the bleep do I get Zend to redirect the user to that route from an action?
The toRoute method provided by the The Redirect plugin needs the route name to be passed as parameter. This is its desciption :
toRoute(string $route = null, array $params = array(), array $options = array(), boolean $reuseMatchedParams = false)
Redirects to a named route, using the provided $params and $options to assembled the URL.
Given this simple route configuration example :
//module.config.php
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Segment',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
),
'app' => array(
'type' => 'Literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id'=>'[0-9]+',
),
),
),
),
),
),
),
This redirection works :
return $this->redirect()->toRoute('app/default',
array('controller'=>'controller-name', 'action'=>'action-name', 'id'=>$id));
In your case, this would work :
return $this->redirect()->toRoute('app/default',
array('controller'=>'listitem', 'action'=>'showlistitem', 'id'=>2));

Zend Framework 2 - route parameters after <home> route

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]+',
),
),
),
),
),
),
),

Redirecting for child routes in ZF2 throws an error

I've have an problem to redirect on child routes in zend framework 2. I can access the controller and action but while redirecting it throws me an error missing parameter "id".
'admin' => array(
'type' => 'segment',
'options' => array(
'route' => '/admin[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Admin',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'settings' => array(
'type' => 'Segment',
'may_terminate' => true,
'options' => array(
'route' => '/general[/][:action][/][:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Settings\General',
'action' => 'index',
),
),
),
),
),
I have given redirect to route like below,
return $this->redirect()->toRoute('admin/settings');
But it throws an error,
Missing parameter "id"
as the error message implies you need to add the "id" parameter. You can redirect with a parameter like so.
return $this->redirect()->toRoute('admin', array('action'=>'settings', 'id' => $id));
You did not show us your Controller action's but I assume 'settings' is a action within your admin module.
At this point I cannot really see what kind of id the admin/settings function need's might aswell just try to add a 0 or 1 to try the route at first for testing purposes.
The route matching method doesn't seem to 'consume' the parent node of the route.
Changing the child route to include the /admin part of the grammar to
/admin/settings/general[/][:action][/][:id]
or
/admin/settings[/][:action][/][:id]
should allow $this->redirect()->toRoute('admin/settings'); to work.

Zend Framework 2: active menu items

Build navigation from config:
'navigation' => array(
'default' => array(
'admin' => array(
'label' => 'Administration',
'controller' => 'index',
'action' => 'index',
'route' => 'admin/default',
),
'album' => array(
'label' => 'Album',
'controller' => 'index',
'action' => 'index',
'route' => 'album/default',
),
/* ... */
Routing is configured like it is true. Navigation in the menu works. Links menu lead to the desired controller/action of the desired module. But while introducing menu and a transition to one or another menuitem, active marked both points simultaneously and 'Administration' and 'Album'. As I understand it, for the reason that match the names of controllers and actions with them, but there's still the 'route' and it's different... not for nothing that the generated different url for each item... but somehow, despite this, they both are marked as active.
Routing config:
'router' => array(
'routes' => array(
'admin' => array(
'type' => 'Literal',
'options' => array(
'route' => '/admin',
'defaults' => array(
'__NAMESPACE__' => 'Admin\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller][/:action[/id:id]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
),
),
),
Album routing config similar...
Why this is happening? Thanks.
Looks like it's how ZF2 works (read isActive() function in Zend\Navigation\Page\Mvc.php). Initially it checks matching of route/controller/action, but if it fails, ZF2 again check for just controller/action pair. So there are three possible ways:
Open a ticket at https://github.com/zendframework/zf2/issues and wait for response.
Override \Zend\Navigation\Page\Mvc.
Choose different names for controllers (and don't use index name because it's default name for controller in Mvc.php).
If you make your controller names include the the namespace then they will be unique and won't clash:
Admin\Controller\IndexController
Album\Controller\IndexController
Rather than
Index
Index

Categories