Zend routing issue with dynamic segment - php

I'm working on a Zend project and I have some issues with the router/routes.
I want the have these URLs:
www.mydomain.tld/contact/person
www.mydomain.tld/contact/person/formsend
www.mydomain.tld/contact/person/id
The third segment in the URL will be a fixed text "formsend" or it will contain an ID, which is a number like '123456789'.
URL 1 and 3 should both execute the indexAction(), URL 2 must execute the sendAction().
Now I have these route's setup to get URL 1 and 2 working:
return array(
'router' => array(
'routes' => array(
'contact' => array(
'type' => 'Segment',
'options' => array(
'route' => '/contact[/][:dns]',
'defaults' => array(
'__NAMESPACE__' => 'project\Controller',
'controller' => 'Contact',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'send' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/[:action[/]]]',
'defaults' => array(
'action' => 'send'
),
),
),
),
),
I have no idea how I must change my routes so I would be able to have segment_3 inside the indexAction(). What do I need to change?

It sounds to me you only need two routes:
First define /contact/:type/formsend, then /contact/:type[/:id].
You can make them children of a top-level (non-terminating) /contact or /contact/:type route, or not.

Related

Zend Framework 2 getting URL from route

What I'm trying to do is generate a URL using the url view helper in Zend Framework 2
The URL that I am trying to generate should be
my-website.com/app/## (where ## is equal to the "ownerID")
What happens when I generate this using the view helper like this:
$this->url('mymodule', array('action'=>'show', 'ownerID'=>'28'));
is it only generates "my-website.com/app", but I am expecting "my-website.com/app/28" based on the routing configuration.
Here is the route information from my module.config.php file
'router' => array(
'routes' => array(
'mymodule' => array(
'type' => 'segment',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'MyModule\Controller\MyModule',
'action' => 'show',
),
),
// Defines that "/app" can be matched on its own without a child route being matched
'may_terminate' => true,
'child_routes' => array(
'archive' => array(
'type' => 'segment',
'options' => array(
'route' => '/:action[/:ownerID[/:clientID]]',
'defaults' => array(
),
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'ownerID' => '[0-9]+',
'clientID' => '[0-9]+',
)
),
),
'single' => array(
'type' => 'segment',
'options' => array(
'route' => '/:ownerID[/:clientID]',
'defaults' => array(
'action' => 'show',
),
'constraints' => array(
'ownerID' => '[0-9]+',
'clientID' => '[0-9]+',
)
),
),
)
),
)
),
The same behavior occurs when using $this->redirect()->toRoute.
All of the routes work as expected when you type them manually, it is just the generation of the URL that has me stumped.
To more directly answer the question, it doesn't do what you expect because you are only passing the top level route name ("mymodule") to the URL helper. The ownerID is part of a child route.
What you actually want is:
$this->url('mymodule/archive', array('action'=>'show', 'ownerID'=>'28'));
(or possibly mymodule/single, depending on the output you want).

Routing issues and timeout in Zend Framework 2

I'm trying to achieve the routing explained in below but having a lot of trouble (the documentation is like a foreign language). Should routing for each module be kept separate in that module's config file?
"route": Module/Controller/Action
"/": Application/Index/index
"/:example": Application/Campaign/index (with param "campaign" = [example])
"/admin": Admin/Admin/index
"/admin/login": Admin/Access/login
"/admin/:controller/:action": Admin/[defined]/[defined]
I've tried to understand and use the skeleton application to do this and everything works up to the "/admin/controller/action" route where the script times out (I'm guessing there's a recursive loop in there somewhere). My route definitions are:
'home' => array(
'type' => 'literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'campaign' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:campaign]',
'constraints' => array(
'campaign' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Application\Controller\Campaign',
'action' => 'index',
'campaign' => ''
),
),
),
'admin' => array(
'type' => 'segment',
'options' => array(
'route' => '/admin',
'defaults' => array(
'controller' => 'Admin\Controller\Admin',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'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(
),
),
),
),
),
1) Yes, you should separate routing config to modules, ZF2 will merge it automatically. So you need to store home and campaign routes in Application/config/module.config.php and admin route in Admin/config/module.config.php
2) I don't see any global mistakes in your config. Two small things:
2.1) You can use literal instead of segment for admin parent route
2.2) If you want to use :controller as a route param, be sure to make shortcut for it via invokables section of config. For example:
'controllers' => array(
'invokables' => array(
'index' => 'Application\Controller\Index'
'admin' => 'Admin\Controller\Admin'
),
),
Now, for example, url /admin/admin/update is connected with Admin\Controller\Admin->updateAction()
3) I think it's not possible to make some recursive loops using only routing config. So check your code in controllers/services

zf2 AbstractRestfullController API routing

I am pretty new to zf2. I am trying to build a RESTful API for our contact management system. We are extending the AbstractRestfulController which uses getList(), get(), etc actions.
Everything works as I would expect it to with the exception of one url route. When I go to this url
/contacts
it successfully routes to the getList() method of my ContactsController. However when I go here.
/contacts/1253378/stats
it routes to the get() method of my StatsController. I would expect that url to route to the getList() method, which I would then return a list of stats.
I would expect adding an /idnumber to the end of that url would route to the get() method of my StatsController, which would return one stat with that id.
Basically I am trying to replicate what is laid out in this REST tutorial, under the But how do you deal with relations section.
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful
I am hoping my routes are not correct in my module.config.php file
'router' => array(
'routes' => array(
'contacts' => array(
'type' => 'segment',
'options' => array(
'route' => '/contacts[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Contacts\Controller\ContactsController',
),
),
),
'stats' => array(
'type' => 'segment',
'options' => array(
'route' => '/contacts/[:id]/stats[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Contacts\Controller\StatsController',
),
),
),
),
),
Any help would be greatly appreciated.
In your case problem is that id parameter conflicts, recommended way is to use specific parameter names, eg:
'router' => array(
'routes' => array(
'contacts' => array(
'type' => 'segment',
'options' => array(
'route' => '/contacts[/:contactId]',
'constraints' => array(
'contactId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Contacts\Controller\ContactsController',
),
),
'may_terminate' => true,
'child_routes' => array(
'stats' => array(
'type' => 'segment',
'options' => array(
'route' => '/stats[/:statId]',
'constraints' => array(
'statId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Contacts\Controller\StatsController',
),
),
),
),
),
),
),
Url /contacts/1253378/stats will match contacts/stats route with contactId set to 1253378
To make that change work, you will need to set protected property identifierName in Contacts\Controller\ContactsController to 'contactId' and in Contacts\Controller\StatsController to statId
Now controllers will properly use separate variables for Id and everything should work fine.

Zend Framework 2 - trailing slashes in route

Havin in a Zend Module following structure
Name of Module
Test
config
src
view
layout
test
index
index.phtml
login
index.phtml
register
index.phtml
Module.php
Now when accessing website for example for login file it will be as following http://justsite.something.com/login
Problem Need to change to http://justsite.something.com/login/ for that i added to login folder another folder index and there putted index.phtml file like this
login
index
index.phtml
But that doesn't seem to work. Should i change in LoginController.php for this to work?
module.confing.php
'router' => array(
'routes' => array(
'test' => array(
'type' => 'Literal',
'options' => array(
'route' => '/test',
'defaults' => array(
'__NAMESPACE__' =>'Test\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'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(),
),
),
),
),
'login' => array(
'type' => 'Literal',
'options' => array(
'route' => '/login/', // PUT HERE WHATEVER YOU WANT
'defaults' => array( // AND MAP THAT URL TO CONTROLLER/ACTION
'__NAMESPACE__' =>'Test\Controller',
'controller' => 'Login',
'action' => 'index',
),
),
),
),
),
Fixed Just added
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' =>
'/[:controller[/:action]/]',
Like #tasmaniski wrote you don't need to make changes to LoginController or whatever, all comes down to your route config. You are not the only one who wants "trailing slashes" in his routes, here you can read how you can achieve this.
Apparently you need to put it between []
'route' => '/[:controller[/[:action[/]]]]',
Hope that solves it for you.
NOTE Some people suggest using a rewrite rule for this, I thought this might be worth mentioning too.
No matter what is your forlder structure. You need to make a change in the config file module.config.php, section "routes".
You only need to put in "route" value with slash at the end and map it to controller/action.
'routes' => array(
'login' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/login/', // PUT HERE WHATEVER YOU WANT
'defaults' => array( // AND MAP THAT URL TO CONTROLLER/ACTION
'controller' => 'Application\Controller\Login',
'action' => 'index',
),
),
),
)

ZF2 Child route issues

I am trying to get some basic routing done in ZF2 but I am running into some problems.
The section that is giving me trouble is this:
'parent-categories' => array(
'type' => 'literal',
'options' => array(
'route' => '/kategorier/',
'defaults' => array(
'controller' => 'categories',
'action' => 'parent-categories',
),
),
'may_terminate' => true,
'child_routes' => array(
'child-categories' => array(
'type' => 'segment',
'options' => array(
'route' => '/kategorier[/:slug][/:parentCategoryid]/',
'constraints' => array(
'parentCategoryid' => '[0-9]+',
),
'defaults' => array(
'controller' => 'categories',
'action' => 'child-categories',
)
),
),
),
),
The original 'parent-categories' route works just fine, no problem. The problem though is the child-categories route isn't doing anything. I have the URL:
/kategorier/test-test-test-test-test/1/
but this is never matched to anything. I get the error:
The requested URL could not be matched by routing.
If I take the child-categories route out of the "child_routes" section, it always catches the request, even if the url is only /kategorier/. Can anyone see what I am doing wrong here?
A child route appends to the parent route. I.e. what you're currently matching is
/kategorier//kategorier[/:slug][/:parentCategoryid]/
Do it like this
'parent-categories' => array(
'type' => 'literal',
'options' => array(
'route' => '/kategorier',
'defaults' => array(
'controller' => 'categories',
'action' => 'parent-categories',
),
),
'may_terminate' => true,
'child_routes' => array(
'child-categories' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:slug][/:parentCategoryid]',
'constraints' => array(
'parentCategoryid' => '[0-9]+',
),
'defaults' => array(
'controller' => 'categories',
'action' => 'child-categories',
)
),
),
),
),
And i guess this should be working out alright. It's a good advice to NOT have trailing slashes, as you'd ideally always want to begin new routes with one for better readability ;)

Categories