I am writing this post just after finishing 30mins of really annoying problems with sfPropelPager and implementing a pager partial, which can be re-used though out the project. The problem that I was facing was that there is no way (or at-least I don’t know off) to ensure that the current params from the browser are also passed as the user paginates from page to page.
So here I was dealing with two situations:
-
User posts in a search box (GET request) and the parameters are passed like
search/index?q=foo&p=10
Now as the results appears on the page I want the following links for my pager:
search/index?page=1&q=foo&p=10 search/index?page=2&q=foo&p=10
and so on.
-
Where I have a neat url coming from symfony already. Like.
website/show/flickr.html
In this case I want urls to appear as
website/show/flickr/1 website/show/flickr/2
and so on.
I dont claim this is the best way to do, if you think there is one, please leave a comment, however for others who have spent some time trying to figure this out, this might get them up and running quickly and then then an improvise this further. So here’s my solution.
Code form the Partial (_pager.php)
<?php
$query_string = '';
$pager_param_name = 'page';
// use this value in case you are getting your parameters from a get request
// e.g. search where you are showing results as part of submitting a get form
$query_params = $sf_request->getGetParameters();
// use this when you already have a proper fancy url in place
// and you want to get the internal rep of the query params.
// this doesnt return any query params if the intial request is sent thru
// the query string (e.g. in the above case this would return nothing after ? in the url)
$uri = sfContext::getInstance()->getRouting()->getCurrentInternalUri();
$args = explode('?', $uri);
if (isset($args[1])) {
$params = $args[1];
} else {
$params = $sf_request->getGetParameters();
$counter = 0;
$len = count($params);
$tmp = '';
foreach($params as $key => $value) {
$tmp .= $key . '=' . $value;
$counter +=1;
if ($counter < $len) {
$tmp .= '&';
}
}
$params = $tmp;
}
// fancy reg to make sure we dont reset the value for the pager param again
$query_string = eregi_replace('(&){0,1}' . $pager_param_name . '=[0-9]{1,}(&){0,1}', '', $params);
if ('' != $query_string) {
$query_string = '&' . $query_string;
}
?>
<div class="mod pager">
<div class="bd">
<?php if ($pager->haveToPaginate()): ?>
<ol>
<li><?php echo link_to('«', $route .'?' . $pager_param_name. '='.$pager->getFirstPage() . $query_string) ?></li>
<li><?php echo link_to('<', $route . '?' . $pager_param_name. '='.$pager->getPreviousPage() . $query_string) ?></li>
<?php $links = $pager->getLinks(); foreach ($links as $pagecount): ?>
<li>
<?php echo ($pagecount == $pager->getPage()) ?
'<span class="current">' . $pagecount . '</span>' :
link_to($pagecount, $route . '?' . $pager_param_name. '='.$pagecount . $query_string)
?>
</li>
<?php endforeach ?>
<li><?php echo link_to('>', $route . '?' . $pager_param_name. '='.$pager->getNextPage(). $query_string) ?></li>
<li><?php echo link_to('»', $route . '?' . $pager_param_name. '='.$pager->getLastPage() . $query_string) ?></li>
</ol>
<?php endif ?>
</div>
</div>
Code Inside the action class
public function executeShow(sfWebRequest $request)
{
$pager = UsernamePeer::getListByWebsitePager($website, $count);
$pager->setPage($this->getRequestParameter('page',1));
$pager->init();
$this->pager = $pager;
}
And then finally the template that calls the partial
<?php include_partial('global/username_list', array('pager' => $pager, 'route' => 'website/show'))?>
