Zend Framework 2: Catch all route and url escape - php

I'm trying to create or find a route which will basically catch all.
What I need is something that can route the something like the following;
/some-page/some-childpage/another-childpage
/another-page
/yet-anotherpage/page
These urls will not be related to any module as such, they're more so an admin can create pages at any url.
I've got something which catches the routes at the moment using wildcard routing and a child wildcard route, but when I use it in the URL view helper it's encoding the forward slashes within the 'url' parameter.
Basically:
$this->url( 'public_page', array( 'url' => 'foo/bar' ) )
Is outputting /foo%2Fbar.
As well as not allowing /s, when trying to retrieve the url parameter, its returning the query string upto the first /.
Any help and suggestions would be great!
Regards,
Michael

I'm not sure you could do that with an arbitrary number of segments. You could specify a segment route with the maximum amount of segments you expect and then just allow them all to be optional, but that seems a dirty way to do it if you're trying to use lots of segments.
'route' => '/:controller[[[[/:action]/:third]/:fourth]/:fifth]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'controller' => 'Application\Controller\IndexController',
'action' => 'index',
'third' => 'something',
'fourth' => 'something-else',
),
You could possibly get something done with the Regex route, but again that's probably nasty as well.
http://framework.zend.com/manual/2.0/en/modules/zend.mvc.routing.html#zend-mvc-router-http-regex
I would probably suggest to use a better url structure as urls that deep aren't great anyway.

Related

Is it possible to dynamically change view name or create a view that does not exist yet in phalcon?

I would like to know how can i do this in phalcon. I have a web site build with phalcon. All is working great now i stumbled upon a problem, here is what i need.
When a user clicks on a post that was created by another user. It takes him to this post with pictures and all things he entered to DB. I would like that in browser the name of this view is not like www.website.com/posts/index but that it is like www.website.com/posts/Nameofthepost, and like that for each other postings on the website. So that all posts (really ads) show their name up in browser. I hope i wrote everything understandable.
Appreciate all suggestions
That has to do with routing doesn't it? I modified this from my own code, I used grouping, you don't have to. I didn't test this code.
// routes.php
$router = new \Phalcon\Mvc\Router();
$router->setDefaultModule("__YOUR_MODULE__");
$router->removeExtraSlashes(true);
... your other routes ...
// posts group
$posts = new \Phalcon\Mvc\Router\Group(array(
'module' => '__YOUR_MODULE__',
'controller' => 'posts',
'action' => 'index'
));
// All the routes start with /post
$posts->setPrefix('/post');
$posts->add('/{postName}/:params', array(
'action' => 'index',
'params' => 2
));
// Maybe this will be enough for your needs,
// the one above has a catch all params, which
// has to be manually parsed
$posts->add('/{postName}', array(
'action' => 'index',
));
$posts->add('[/]*', array(
'action' => 'index',
));
$router->mount($posts);
unset($posts);
... other routes ...
return $router;
On your controller, you can get the postName param this way:
$this->dispatcher->getParam('permaPath');
As shown in the phalcon routing documentation, you can use regex in your routing config, something like this?
$posts->add('/{postName:[-0-6_A-Za-z]+}/:params', array(
'action' => 'index',
'params' => 2
));
So, only -_, 0-9, A-Z, a-z allowed for postName. If the URL had a comma in there or something, then route doesn't match, 404 page not found.

PHP ZF2 - How to create dynamic urls

I have been tasked to explore the possibilities of creating dynamic urls.
What we try to achieve is serving a domain for the client.
eg. www.example.com/clients/john/
eg. www.example.com/clients/bill/
These urls are not fixed, but have to be made dynamically everytime a Client registers at our site. Our URL's are build of Controllers and Actions. Like www.example.com/controller/action.
How can this be achieved in the PHP Zend Framework 2?
Big thanks in advance!
All you need is the ZF2 Manual:
I suggest to use segment routes
You can define them like:
'client' => array(
'route' => '/clients/:username',
'constraints' => array(
'username' => '[a-zA-Z][a-zA-Z0-9-]+', //accepted value pattern
),
'defaults' => array( //which action to invoke
'controller' => 'Application\Controller\ClientController',
'action' => 'showclient',
),
));
Then you can create an url with url helper like:
$this->url('client', array('username' => 'John'));
And in your controller you will be able to get username param with:
$this->params()->fromRoute('username');

zend framework 2 default routing action change url to default action

i thought i had the routing under control until i found out that i have now clue of how to have the default action url change, that means:
when ever a user enters a url, for example:
http://www.mysite.com/form/myform
the routing will always redirect him to the default action "show" (one of many actions this controller has):
http://www.mysite.com/form/myform/show
but my url remains the same (with the "show" action):
http://www.mysite.com/form/myform
what am i missing here?
'routes' => array(
'form' => array(
'type' => 'segment',
'options' => array(
'route' => '/form[/:form[/:action]]',
'constraints' => array(
'form' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Form\Controller\Form',
'action' => 'show',
),
),
),
),
thanks!
edited note:
i have noticed (thanks to #codeHeart marks) that i had some mistakes/misclarification trying to explain the problem, so i edited the main question examples.
thanks again all!
Looking at this in your question/
http://www.mysite.com/controller
and your router configuration I expect that should be throwing a 404 error, as there is no matching route in your config that matches /controller(If there are more routes other than the one that you show in you question, let us know or maybe you mistyped this url).
Apart from above,
your route tells to do the following:-
if url is
http://yoursite/form OR
http://yoursite/form/controller
go to the controller action that you have mentioned in the defaults, as the route was matched to the url but didn't get matched completely to an action so going to the default.
A non existing controller or a non existing action should be throwing 404. e.g
http://yoursite/form/controller/non-existing-action
Even this url
http://yoursite/form/
won't get matched according to your route and will be throwing a 404.
And for your question if you want to change the default action to something other then the "show" action, simply change the action parameter/key in defaults
'defaults' => array(
'controller' => 'Form\Controller\Form',
'action' => 'some-other-action',
),
Hope this helps and sorry if I was of no help.

Zend Regex Router does not match anything

I currently have a Zend Framework route defined as such:
$route = new Zend_Controller_Router_Route('brand/:brand_name/series/:page',
array('controller' => 'brand',
'action' => 'series',
'page'=>'1'));
$router->addRoute('Brand Series', $route);
I'm trying to adapt this route so that the page parameter only catches numbers, so that I can add another route that uses words in the same place without the two conflicting, something like:
brand/:brand_name/series/:series_name/:page
I figured I would step along with the examples in the ZF documentation here. The very first step would be to change the route to something like this:
$route = new Zend_Controller_Router_Route_Regex('brand/:brand_name/series/(\d+)',
array('controller' => 'brand',
'action' => 'series'));
However, this small change causes routes that matched perfectly before, like /brand/johnnycupcakes/series/2 to fail, telling me Action "johnnycupcakes" does not exist and was not trapped in __call(). And in the stack trace I see:
'controller' => 'brand',
'action' => 'johnnycupcakes',
'series' => '2',
'module' => 'default'
In fact, even if I leave the route and default parameters exactly the same as in the first example, and simply change the class to Router_Route_Regex, I get the same error.
I know that the error isn't a routing conflict, because I haven't added the route that would have conflicted. Plus, it appears that it's attempting to match to the standard route. I'm testing this on version 1.11, so my version should be perfectly compatible with the code in the example.
As far as I can tell, the regex route is simply not matching, despite that it very clearly fits. Why could this possibly be failing?
EDIT:
I omitted the addRoute from the question the first time. I always had it in the code, that's not the issue.
What you need is to name a captured numeric parameter by adding third argument to Zend_Controller_Router_Route_Regex:
$route = new Zend_Controller_Router_Route_Regex(
'brand/:brand_name/series/(\d+)',
array(
'controller' => 'brand',
'action' => 'series'
),
array(
1 => 'series', // name the parameter captured by (\d+)
)
);
The second array may have keys and values in opposite relation 'series' => 1 and it will still work. Check more in ZF manual on regex routes

Routing in Zend Framework 2, skip 'index' action in url but get id

I have a controller that can be invoked as modulename/xmlcoverage with index action and some other actions, let say testAction().
The url to this controller is xml/coverage.
The default way is then that xml/coverage maps to my index action. And that xml/coverage/test maps to testAction. If I need an id for testAction, the url would be like xml/coverage/test/33 for instance.
However, for index action, it would need to be xml/coverage/index/33
Where I would like it to be xml/coverage/33.
This is my route
'xmlcoverage' => array(
'type' => 'segment',
'options' => array(
'route' => '/xml/coverage[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'modulename/xmlcoverage',
'action' => 'index',
),
),
),
When trying the url xml/coverage/33, I believe 33 should map to id, as it doesn't match the regex of action and both are optional. And since it doesn't match an action, the default (index) should be used.
Instead I get an error saying that the url cannot be matched by routing.
So for me, it acts as if the route was '/xml/coverage[/:action[/:id]]' because I for some reason have to specify action for it to recognize the id.
What am I doing wrong, and how can I get the urls to work as I'd like?
Thanks.
EDIT: Here is a problem.
Doing this in my view:
$this->url('xmlcoverage', array('action' => 'index', 'id' => $someid))
actually gives an URL on the form xml/coverage/1 which will crash!
Changing the route to /xml/coverage[/:action[/:id]] will at least make the url helper produce working urls..
After talking and debugging with the nice ZF2 folks on IRC, we tracked down a bug in the routing.
During the discussion I made a small example to my issue, which is here.
As you can see from the var dump here, the action gets lost in the second case where it should default to "index".
But if anyone needs this functionality to work right now, here are ways that fix it:
Instead of having the route to be /test[/:action][/:id] have it to be /test[/:action[/:id]], then the url helper will add /index/ and at least it works.
Make a new route where you only listen for /test[/:id] in addition to the other one.
In your controller, do public function notFoundAction() { $view = new ViewModel($this->indexAction()); //etc} Kinda hacky, but with this bug it will dispatch a not found action, which you can piggyback.

Categories