Zend optional route segment and parameter - php

I'm trying to create a route in Zend 1.12 with a optional segment, but i don't know and i can't find a way to do it.
The situation is, i have the route:
$routes['news'] = array(
'route' => '/news/page/:page',
'defaults' => array(
'module' => 'default',
'controller' => 'news',
'action' => 'index',
'page' => 1,
),
'reqs' => array(
'page' => '([2-9][0-9]*)',
),
);
But i need the segment of the route /page/:page does not appear when the page is 1
Example:
Page = 1 -> /news
Page = 2 -> /news/page/2
Any ideas how can i do it?

Related

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));

Using route in Zend Framework 2

i need to route urls like in zf1.
in particular i need that these urls will be automatically redirect to appropriate actions without specify a new route every time.
/site/getData
/site/getData?param=5&par2=test
/site/getOther
...
So a segment route doesn't work, i've tried a Literal route but i can't reach a working solutions.
Anyone can help me?
Thanks a lot
This should be solved by a pretty default segment route like the one provided in the documentation.
'type' => 'Zend\Mvc\Router\Http\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' => 'default-controller-alias',
'action' => 'index',
),
)
Now if you set up your controller names like the following:
'controllers' => array(
'invokables' => array(
'sites' => 'Namespace\Controller\SitesController',
'other' => 'Namespace\Controller\OtherController'
Then you should be able to achieve exactly what you want. And to create params to your route, you simply use the ViewHelper correctly ;)
$this->url('routename',
array(
'controller' => 'site',
'action' => 'getData'
),
array (
'query' => array(
'param1' => 'foo',
'param2' => 'bar',
'paramN' => 'baz',
)
)
)

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.

Zend Framework 2 Part Route Assembly

My Zend Framework 2 application has a route definition that's trying to mimic the default Zend Framework 1 route. It looks like:
'router' => array(
'routes' => array(
'default' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'wildcard',
),
),
),
),
),
It matches routes just fine, but I can't assemble routes with arbitrary parameters using the Url view helper.
For example,
$this->url('default', array('controller' => 'test', 'action' => 'test', 'id' => 5));
results in /test/test instead of /test/test/id/5.
Does anyone know how to assemble partial routes like this? Or is there a better way of getting ZF1-style routes?
It turns out that you need to specify the entire route name (including child routes) in the Url view helper.
Using the router defined in my question, the proper view helper call would look like:
$this->url('default/wildcard', array('controller' => 'test', 'action' => 'test', 'id' => 5));
which would result in a url of /test/test/id/5.

Zend_Controller_Router_Route

I'm trying to make a Router that can respond to this structure:
module/controller/action/id and module/controller/action/page
The only difference is is 'id' or 'page'. I'm using this code:
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0,
'pg' => 1
),
array(
'id' => '\d+',
'pg' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
The problem is that in some situations i want:
'http://www.domain.cl/administrador/productos/2' => (module=>administrador, controller=>productos,page=>2) but with the router 'administrador' result in 'http://www.domain.cl/administrador/productos/index/0/2' (module=>administrador, controller=>productos,action=>index,id=>0,page=>2)
I'm very confused about how it works for cases like this. I tried to make two router where the first only have 'id' param and the other 'page' param. And from url helper use it like:
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'id' => 0), 'administradorId');
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'page' => 1), 'administradorPg');
But when I used the routers always select the last one added to the router ($router->addRoute('routerIdentifier', $route);)
Thanks
I have had a similar issue and I got around this by defining just one route like this
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0
),
array(
'id' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
In your actions you'd then need to get the id and check for it somewhere where that id might be, for example if you were in /administrador/events/view/1 then you might look in the events table or if you were in /administrador/pages/view/1 then you would look for a page.
But the problems really start when the id could be either an event or a page in a given controller and action. The only real way around this is explicitly set the type of id your using for example
/administrador/events/view/index/id/1
or
/administrador/pages/view/index/page/1
If you want to remove the index part then set up routes like
$routeAdmin = new Zend_Controller_Router_Route(
// Remove the action from here and explicitly set the controller
'administrador/pages/:pg',
array(
'module' => 'administrador',
'controller' => 'pages',
// Then set the default action here
'action' => 'index',
'pg' => 0
),
array(
'pg' => '\d+'
)
);
$router->addRoute('administradorpages', $routeAdmin);
What your asking for basically results in a lot of guess work and therefore risk of producing unexpected results.
Have a look at dynamic segments in routes. It is not exactly what you want, but it might be helpful in your case.

Categories