change CakePhp1.3 paginator destination url? - php

I'm new to cakephp...and I have a page with a url this:
http://localhost/books/filteredByAuthor/John-Doe
so the controller is ´books´, the action is ´filteredByAuthor´ and ´John-Doe´ is a parameter.. but the url looks ugly so i've added a Route like this:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'), array('pass'=>array('name'),'name'=>".*"));
and now my link is:
http://localhost/author/John-Doe
the problem is that the view has a paginator and when i change the page (by clicking on the next or prev button).. the paginator won't consider my routing... and will change the url to this
http://localhost/books/filteredByAuthor/John-Doe/page:2
the code on my view is just:
<?php echo $this->Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
the documentation doesn't say anything about avoiding this and i've spent hours reading the paginators source code and api.. and in the end i just want my links to be something like this: (with the sort and direction included on the url)
http://localhost/author/John-Doe/1/name/asc
Is it possible to do that and how?

hate to answer my own question... but this might save some time to another developper =) (is all about getting good karma)
i found out that you can pass an "options" array to the paginator, and inside that array you can specify the url (an array of: controller, action and parameters) that the paginator will use to create the links.. so you have to write all the possible routes in the routes.php file. Basically there are 3 possibilities:
when the "page" is not defined
For example:
http://localhost/author/John-Doe
the paginator will assume that the it's the first page. The corresponding route would be:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name'),'name'=>'[a-zA-Z\-]+'));
when the "page" is defined
For example:
http://localhost/author/John-Doe/3 (page 3)
The route would be:
Router::connect('/author/:name/:page', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name','page'),'name'=>'[a-zA-Z\-]+','page'=>'[0-9]+'));
finally when the page and the sort is defined on the url (by clicking on the sort links created by the paginator).
For example:
http://localhost/author/John-Doe/3/title/desc (John Doe's books ordered desc by title)
The route is:
Router::connect('/author/:name/:page/:sort/:direction', array( 'controller' => 'books','action' => 'filteredByAuthor'),
array('pass'=>array('name','page','sort','direction'),
'name'=>"[a-zA-Z\-]+",
'page'=>'[0-9]*',
'sort'=>'[a-zA-Z\.]+',
'direction'=>'[a-z]+',
));
on the view you have to unset the url created by the paginator, cause you'll specify your own url array on the controller:
Controller:
function filteredByAuthor($name = null,$page = null , $sort = null , $direction = null){
$option_url = array('controller'=>'books','action'=>'filteredByAuthor','name'=>$name);
if($sort){
$this->passedArgs['sort'] = $sort;
$options_url['sort'] = $sort;
}
if($direction){
$this->passedArgs['direction'] = $direction;
$options_url['direction'] = $direction;
}
Send the variable $options_url to the view using set()... so in the view you'll need to do this:
View:
unset($this->Paginator->options['url']);
echo $this->Paginator->prev(__('« Précédente', true), array('url'=>$options_url), null, array('class'=>'disabled'));
echo $this->Paginator->numbers(array('separator'=>'','url'=>$options_url));
echo $this->Paginator->next(__('Suivante »', true), array('url'=>$options_url), null, array('class' => 'disabled'));
Now, on the sort links you'll need to unset the variables 'sort' and 'direction'. We already used them to create the links on the paginator, but if we dont delete them, then the sort() function will use them... and we wont be able to sort =)
$options_sort = $options_url;
unset($options_sort['direction']);
unset($options_sort['sort']);
echo $this->Paginator->sort('Produit <span> </span>', 'title',array('escape'=>false,'url'=>$options_sort));
hope this helps =)

Related

Access id of paginator in controller

Hello guys I am new to Zendframework2.
I have the following line in view\partial\paginator.phtml
<a href="<?php echo $this->url($this->route);?>?page=<?php echo $page; ?>?id=<?php echo $this->id?>">
In browser it looks like http://new_project.localhost/districts?page=2?id=4
new_project is the name of my project, districts is route of controller and
in id=4, 4 is id which I want to access in controller.
I tried:
$_GET['id'];
$this->params()->fromRoute('id'); //also
$this->params()->fromQuery('id'); //also
But non of these works.
How I will access this id in controller?
I solve it, just by putting condition like below:
if (isset($_GET['id']))
{
// perform operation here.
}
Don't build your A element tag href yourself but use the framework like you should.
Url view helper:
// $this->url($routeName, $routeParams, $options, $reuseMatchedParams = false)
$this->url('my/route', ['id' => $object->getId()], ['query' => ['page' => $page]])
Controller plugin:
$this->params('id') // will take ID either from routeParameters or queryParameters.
$this->params()->fromRoute('id') // will take the id from the routeParameters
$this->params()->fromQuery('page') // will take the page from the route query
So when you've got a route with a routeParameter id but your query also has the id within it's query its best practice to keep on using the $this->params()->fromRoute('id') or $this->params()->fromQuery('id') so you always know where the value comes from instead of using $this->params('id').
As with the params plugin you can also define default values on the second argument, like: $this->params()->fromQuery('page', 1). So page will always be 1 if the user did not provide one. The default of the second argument is null. Hope this helps and makes you stop using $_GET['bla']
I think your url should look like this:
http://new_project.localhost/districts?page=2&id=4
^
not ?
Because of the mistake you made the parser probably doesn't parse the id in your url correctly meaning you cannot access it like you tried.
It would be better to use the url view helper for rendering the query parameters in the url then you wouldn't make such a mistake. You can check this post on StackOverflow for reference on how to add query parameters to a url using the url view helper. In your case it would look something like this:
<?php
$href = $this->url($this->route, [], ['query' => [
'page' => $page,
'id' => $id,
]]);
?>
<a href="<?php echo $href ?>">
Now you get the correct url:
http://new_project.localhost/districts?page=2&id=4
Meaning the parser also manages to parse the id correctly.
You should be able to access it now like you tried with:
$this->params()->fromQuery('id'); //returns your id from the url

cakephp 2 - pagination - don't pass variable in url

I have a search form which, if someone fills it in and there are no results to report, I want to make them aware of that but then show them a result set of my choosing. The problem is that when I show them this result set of my choosing and I use the paginator helpers for prev/next they want to pass the search term which is in my URL along with the page number.
That obviously causes problems because there isn't a page:2 for the results search:termHasNoResults
How can I stop the paginator helper passing my search variable in the URL when I'm showing them my alternative result set?
Thanks
Use
$this->Paginator->options('url' => array(
'controller' => 'YOUR CONTROLLER', 'action' => 'YOUR ACTION', 'OTHER PARAMS');
You can pass 'url' option to pagination in your view like this:
$url = array_merge($this->request->pass, $this->request->named);
unset($url['page']);
$parts = explode('?', $_SERVER['REQUEST_URI'], 2);
if (count($parts) == 2) {
$url['?'] = $parts[1];
}
$this->Paginator->options(array(
'url' => $url,
));
More here: http://api.cakephp.org/2.2/class-PaginatorHelper.html
and here: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::options
If you widely use filters and additional url params - make an element which will handle it for you

Kohana 3.2 - How do you send variables whith your routing?

I have the following route set at the end of the route list for my site which allows a final check on the uri value to provide my site users with a vanity URL (http://example.com/username)
Route::set('profile', '<path>/(<page>)',
array(
"path" => "[a-zA-Z0-9_-]+",
"page" => (blog|photos)))
->defaults(array(
'controller' => 'welcome',
'action' => 'profile'
));
This route directs properly to the welcome controller and the profile method, however I was wondering if there was a way to get the path and page values sent to the method like so:
action_profile($var1, $var2) {
echo $var1 . ' ' . $var2;
}
I don't want to rely on $this->request->uri() and exploding the result into an array unless there is absolutely no other way of doing this.
Read the manuals please: http://kohanaframework.org/3.0/guide/kohana/routing#request-parameters. $this->request->param('param-name') will helps.

Append param to current URL with view helper in Zend

In my layout-script I wish to create a link, appending [?|&]lang=en to the current url, using the url view helper. So, I want this to happen:
http://localhost/user/edit/1 => http://localhost/user/edit/1?lang=en
http://localhost/index?page=2 => http://localhost/index?page=2&lang=en
I have tried the solution suggested Zend Framework: Append query strings to current page url, accessing the router directly, but that does work.
My layout-script contains:
English
If the default route is used, it will append /lang/en, but when another route is used, nothing is appended at all.
So, is there any way to do this with in Zend without me having to parse the url?
Edit
Sorry for my faulty explanation. No, I haven't made a custom router. I have just added other routes. My bad. One route that doesn't work is:
$Routes = array(
'user' => array(
'route' => 'admin/user/:mode/:id',
'defaults' => array('controller' => 'admin', 'action' => 'user', 'mode'=>'', 'id' => 0)
)
);
foreach( $Routes as $k=>$v ) {
$route = new Zend_Controller_Router_Route($v['route'], $v['defaults']);
$router->addRoute($k, $route);
}
Upd:
You must add wildcard to your route or define 'lang' parameter explicitly.
'admin/user/:mode/:id/*'
Additionally, according to your comment, you can do something like this:
class controllerplugin extends Zend_Controller_Plugin_Abstract
{
function routeShutdown($request)
{
if($request->getParam('lang', false) {
//store lang
Zend_Controller_Front::getInstance()->getRouter()->setGlobalParam('lang', NULL); //check if this will remove lang from wildcard parameters, have no working zf installation here to check.
}
}
}

CakePHP Routing help

I want to make my /pages/about become just `/about
I tried doing it with the routing in routes.php but couldn't get it working e.g. Router::connect('/pages/about', array('controller' => 'pages', 'action' => 'display'));
can anyone help?
ALSO
for my portfolio controller I have it currently showing work like /portfolio/view/102 but I would like to display it something like /portfolio/view/Paperview_Magazine-102 where Paperview Magazine is the title of the post and 102 is the ID of the post. I have looked at the Cake Book but if someone could post up some code that'd be awesome.
Thanks
To make a route for /about, you need to make a route for /about, not /pages/about:
Router::connect('/about',
array('controller' => 'pages', 'action' => 'display', 'about'));
To use URLs like /portfolio/view/Paperview_Magazine-102, you can use standard routes, but you'll have to do a little work in the controller:
// PortfolioController
// $identifier == "Paperview_Magazine-102"
public function view($identifier) {
if (!preg_match('/^(.+)-(\d+)$/', $identifier, $matches)) {
// $identifier is not in format 'Title-Id'
$this->cakeError('error404');
}
// $matches[1] == Paperview_Magazine
// $matches[2] == 102
$post = $this->Portfolio->read(null, $matches[2]);
$this->set(compact('post'));
}
Maybe a bit of a long shot, but in the first one you could try Router::connect('/:controller/about', array('action'=>'display'));? I seem to remember having some similar problems with my routes and this maybe helping, though I can't remember why.
With the second question, can't you just rework the view function so it accepts a $slug parameter instead of $id, and find the right portfolio record by searching on the slug instead? Or check if the parameter is_numeric, and search for an id if it is, or a slug if it isn't...

Categories