PHP ZF2 - How to create dynamic urls - php

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

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.

How can I simply serve static pages with child routes in ZF2?

Maybe I am overcomplicating this, but the documentation isn't very clear to me. I am using Zend Framework 2 to serve some dynamic content, but I also have a few routes that are purely static HTML pages. Those static pages are all children of a parent route. For example:
/foo/bar
/foo/baz
/foo/cat
How can I just simply serve up these static pages if I already have a "FooController" I should add that /foo doesn't have a view itself, but all of the foo children do.
The easiest would be to set up your route like this:
'foopage' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/foo/:action',
'defaults' => array(
'controller' => 'My\Controller\Foo',
'action' => 'index'
),
'constraints' => array(
'action' => '[a-zA-Z]+'
)
),
)
Then inside your FooController simply create a couple of empty actions like indexAction, fooAction, barAction, bazAction and create the respective templates.
An alternative would be to use the Module of Matthew called PhlySimplePage

zend framework url helper - how to pass variable before controller?

I have specific problem with Zend Framework (1.12) - url helper.
I have site, divided by languages in this form:
/en/contact
/de/gallery/gal1
etc..
I have changed router to accept first parameter as variable and it's accessible by GET.
How can I set URL helper to follow this guideline and pass this variable before controller in URL ? (I'm not using modules).
Many thanks.
Ivan
Let me reply to myself. Router setup:
$router = $frontController->getRouter();
$routeLang = new Zend_Controller_Router_Route(
':lang/:controller/:action/*',
array(
'lang' => 'de',
'controller' => 'index',
'action' => 'index'
),
array('lang' => '[a-z]{2}')
);
$router->addRoute('lang', $routeLang);
URL creation:
$this->url(array('lang' => 'bar', 'controller'=>'contact','action'=>'index'));
Please correct me, if my understanding is wrong.
Ivan

Zend Framework 2: Catch all route and url escape

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.

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