2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
12 * @package ActionController
13 * @subpackage Paginator
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 require_once(AK_VENDOR_DIR
.DS
.'pear'.DS
.'HTML'.DS
.'Pager'.DS
.'Pager.php');
20 require_once(AK_VENDOR_DIR
.DS
.'pear'.DS
.'HTML'.DS
.'Pager'.DS
.'Common.php');
23 * AkPager and AkPaginator are a fork of Pear::Pager
24 * coded by Lorenzo Alberton <at quipo.it> and
25 * Richard Heyes <mailto:richard at phpguru.org>,
29 class AkPager
extends Pager_Common
36 * @param mixed $options An associative array of option names
40 function init($options = array())
42 //set default AkPager options
44 $this->_prevImg
= '«';
45 $this->_nextImg
= '»';
46 $this->_separator
= '|';
47 $this->_spacesBeforeSeparator
= 3;
48 $this->_spacesAfterSeparator
= 3;
49 $this->_curPageSpanPre
= '<b><u>';
50 $this->_curPageSpanPost
= '</u></b>';
53 $err = $this->_setOptions($options);
54 if ($err !== PAGER_OK
) {
55 return $this->raiseError($this->errorMessage($err), $err);
57 $this->_generatePageData();
58 $this->_setFirstLastText();
60 if ($this->_totalPages
> (2 * $this->_delta +
1)) {
61 $this->links
.= $this->_printFirstPage();
64 $this->links
.= $this->_getBackLink();
65 $this->links
.= $this->_getPageLinks();
66 $this->links
.= $this->_getNextLink();
68 $this->linkTags
.= $this->_getFirstLinkTag();
69 $this->linkTags
.= $this->_getPrevLinkTag();
70 $this->linkTags
.= $this->_getNextLinkTag();
71 $this->linkTags
.= $this->_getLastLinkTag();
73 if ($this->_totalPages
> (2 * $this->_delta +
1)) {
74 $this->links
.= $this->_printLastPage();
79 // {{{ getPageIdByOffset()
82 * "Overload" PEAR::Pager method. VOID. Not needed here...
83 * @param integer $index Offset to get pageID for
87 function getPageIdByOffset($index=null) { }
90 // {{{ getPageRangeByPageId()
93 * Given a PageId, it returns the limits of the range of pages displayed.
94 * While getOffsetByPageId() returns the offset of the data within the
95 * current page, this method returns the offsets of the page numbers interval.
96 * E.g., if you have pageId=5 and delta=2, it will return (3, 7).
97 * PageID of 9 would give you (4, 8).
98 * If the method is called without parameter, pageID is set to currentPage#.
100 * @param integer PageID to get offsets for
101 * @return array First and last offsets
104 function getPageRangeByPageId($pageid = null)
106 $pageid = isset($pageid) ?
(int)$pageid : $this->_currentPage
;
107 if (!isset($this->_pageData
)) {
108 $this->_generatePageData();
110 if (isset($this->_pageData
[$pageid]) ||
is_null($this->_itemData
)) {
111 if ($this->_expanded
) {
112 $min_surplus = ($pageid <= $this->_delta
) ?
($this->_delta
- $pageid +
1) : 0;
113 $max_surplus = ($pageid >= ($this->_totalPages
- $this->_delta
)) ?
114 ($pageid - ($this->_totalPages
- $this->_delta
)) : 0;
116 $min_surplus = $max_surplus = 0;
119 max($pageid - $this->_delta
- $max_surplus, 1),
120 min($pageid +
$this->_delta +
$min_surplus, $this->_totalPages
)
130 * Returns back/next/first/last and page links,
131 * both as ordered and associative array.
133 * @param integer $pageID Optional pageID. If specified, links
134 * for that page are provided instead of current one.
135 * @return array back/pages/next/first/last/all links
138 function getLinks($pageID = null)
140 if ($pageID != null) {
141 $_sav = $this->_currentPage
;
142 $this->_currentPage
= $pageID;
145 if ($this->_totalPages
> (2 * $this->_delta +
1)) {
146 $this->links
.= $this->_printFirstPage();
148 $this->links
.= $this->_getBackLink();
149 $this->links
.= $this->_getPageLinks();
150 $this->links
.= $this->_getNextLink();
151 if ($this->_totalPages
> (2 * $this->_delta +
1)) {
152 $this->links
.= $this->_printLastPage();
156 $back = str_replace(' ', '', $this->_getBackLink());
157 $next = str_replace(' ', '', $this->_getNextLink());
158 $pages = $this->_getPageLinks();
159 $first = $this->_printFirstPage();
160 $last = $this->_printLastPage();
162 $linkTags = $this->linkTags
;
164 if ($pageID != null) {
165 $this->_currentPage
= $_sav;
182 'linktags' => $linkTags
187 // {{{ _getPageLinks()
192 * @return string Links
195 function _getPageLinks($url = '')
197 //legacy setting... the preferred way to set an option now
198 //is adding it to the constuctor
203 //If there's only one page, don't display links
204 if ($this->_clearIfVoid
&& ($this->_totalPages
< 2)) {
209 if ($this->_totalPages
> (2 * $this->_delta +
1)) {
210 if ($this->_expanded
) {
211 if (($this->_totalPages
- $this->_delta
) <= $this->_currentPage
) {
212 $expansion_before = $this->_currentPage
- ($this->_totalPages
- $this->_delta
);
214 $expansion_before = 0;
216 for ($i = $this->_currentPage
- $this->_delta
- $expansion_before; $expansion_before; $expansion_before--, $i++
) {
217 $print_separator_flag = ($i != $this->_currentPage +
$this->_delta
); // && ($i != $this->_totalPages - 1)
219 $this->range
[$i] = false;
220 $this->_linkData
[$this->_urlVar
] = $i;
221 $links .= $this->_renderLink($this->_altPage
.' '.$i, $i)
222 . $this->_spacesBefore
223 . ($print_separator_flag ?
$this->_separator
.$this->_spacesAfter
: '');
227 $expansion_after = 0;
228 for ($i = $this->_currentPage
- $this->_delta
; ($i <= $this->_currentPage +
$this->_delta
) && ($i <= $this->_totalPages
); $i++
) {
234 // check when to print separator
235 $print_separator_flag = (($i != $this->_currentPage +
$this->_delta
) && ($i != $this->_totalPages
));
237 if ($i == $this->_currentPage
) {
238 $this->range
[$i] = true;
239 $links .= $this->_curPageSpanPre
. $i . $this->_curPageSpanPost
;
241 $this->range
[$i] = false;
242 $this->_linkData
[$this->_urlVar
] = $i;
243 $links .= $this->_renderLink($this->_altPage
.' '.$i, $i);
245 $links .= $this->_spacesBefore
246 . ($print_separator_flag ?
$this->_separator
.$this->_spacesAfter
: '');
249 if ($this->_expanded
&& $expansion_after) {
250 $links .= $this->_separator
. $this->_spacesAfter
;
251 for ($i = $this->_currentPage +
$this->_delta +
1; $expansion_after; $expansion_after--, $i++
) {
252 $print_separator_flag = ($expansion_after != 1);
253 $this->range
[$i] = false;
254 $this->_linkData
[$this->_urlVar
] = $i;
255 $links .= $this->_renderLink($this->_altPage
.' '.$i, $i)
256 . $this->_spacesBefore
257 . ($print_separator_flag ?
$this->_separator
.$this->_spacesAfter
: '');
262 //if $this->_totalPages <= (2*Delta+1) show them all
263 for ($i=1; $i<=$this->_totalPages
; $i++
) {
264 if ($i != $this->_currentPage
) {
265 $this->range
[$i] = false;
266 $this->_linkData
[$this->_urlVar
] = $i;
267 $links .= $this->_renderLink($this->_altPage
.' '.$i, $i);
269 $this->range
[$i] = true;
270 $links .= $this->_curPageSpanPre
. $i . $this->_curPageSpanPost
;
272 $links .= $this->_spacesBefore
273 . (($i != $this->_totalPages
) ?
$this->_separator
.$this->_spacesAfter
: '');
282 * Renders a link using the appropriate method
284 * @param altText Alternative text for this link (title property)
285 * @param linkText Text contained by this link
286 * @return string The link in string form
289 function _renderLink($altText, $linkText)
291 $href = $this->controller
->url_helper
->modify_current_url($this->_linkData
);
293 if ($this->_httpMethod
== 'GET') {
295 return sprintf('<a href="%s"%s title="%s">%s</a>',
297 empty($this->_classString
) ?
'' : ' '.$this->_classString
,
302 if ($this->_httpMethod
== 'POST') {
303 return sprintf("<a href='javascript:void(0)' onClick='%s'%s title='%s'>%s</a>",
304 $this->_generateFormOnClick($this->_url
, $this->_linkData
),
305 empty($this->_classString
) ?
'' : ' '.$this->_classString
,
318 * A class representing a paginator for an Active Record collection.
323 * Creates a new AkPaginator on the given +controller+ for a set of items
324 * of size +item_count+ and having +items_per_page+ items per page.
325 * Raises an error if items_per_page is out of bounds (i.e., less
326 * than or equal to zero). The page GET parameter for links defaults to
327 * "page" and can be overridden with +page_parameter+.
329 function &AkPaginator(&$controller, $item_count, $items_per_page, $current_page=1)
332 if($items_per_page <= 0){
333 trigger_error(Ak
::t('must have at least one item per page'),E_USER_WARNING
);
336 if(empty($current_page)){
338 $controller->params
[$controller->_pagination_options
['parameter']] = 1;
340 $this->controller
=& $controller;
341 $controller_name = $controller->Request
->getController();
342 $this->item_count
= !empty($item_count) ?
$item_count : 0;
343 $this->items_per_page
= $items_per_page;
344 $this->pages
= ceil($item_count/$items_per_page);
346 if(!isset($paginator[$controller_name.'_paginator'])){
348 $pager_options = array(
349 'totalItems'=>$item_count,// Number of items to page (used only if itemData is not provided).
350 'perPage'=>$items_per_page,//Number of items to display on each page.
351 'currentPage'=>$current_page,//Initial page number (if you want to show page #2 by default, set currentPage to 2)
352 'delta'=>4,// Number of page numbers to display before and after the current one.
353 'mode'=>'Sliding',// "Jumping" or "Sliding" -window - It determines pager behaviour.
354 'httpMethod'=>'GET',// Specifies the HTTP method to use. Valid values are 'GET' or 'POST'.
355 //'formID'=>'',//Specifies which HTML form to use in POST mode.
356 'importQuery'=>true,//if true (default behaviour), variables and values are imported from
357 //'extraVars'=>'',//additional URL vars to be added to the querystring.
358 //'excludeVars'=>'',//URL vars to be excluded from the querystring.
359 // the submitted data (query string) and used in the generated links, otherwise they're ignored completely
360 'expanded'=>true,// if TRUE, window size is always 2*delta+1
361 'linkClass'=> 'paginationLink',//Name of CSS class used for link styling.
362 'curPageLinkClassName'=>'paginationCurrent',//Name of CSS class used for current page link.
363 'urlVar'=>$controller->_pagination_options
['parameter'],//Name of URL var used to indicate the page number. Default value is "pageID".
364 'path'=> '',//Complete path to the page (without the page name).
365 'fileName'=>'?'.$controller->_pagination_options
['parameter'].'=%d',//name of the page, with a "%d" if append == TRUE.
366 'append'=>false,//If TRUE pageID is appended as GET value to the URL. If FALSE it is embedded in the URL according to fileName specs.
367 'altFirst'=>Ak
::t('first page'),//Alt text to display on the link of the first page. Default value is "first page";
368 //if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
369 'altPrev'=>Ak
::t('previous page'),// Alt text to display on the link of the previous page. Default value is "previous page";
370 'altNext'=>Ak
::t('next page'),//Alt text to display on the link of the next page. Default value is "next page";
371 'altLast'=>Ak
::t('last page'),//Alt text to display on the link of the last page. Default value is "last page";
372 //if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
373 'altPage'=>Ak
::t('page').' ',//Alt text to display before the page number. Default value is "page ".
374 'prevImg'=>'<span class="paginationPrevious">'.Ak
::t('previous')."</span>",//Something to display instead of "<<". It can be text such as "<< PREV" or an <img/> as well.
375 'nextImg'=>'<span class="paginationNext">'.Ak
::t('next').'</span>',//Something to display instead of ">>". It can be text such as "NEXT >>" or an <img/> as well.
376 'separator'=>' ',// What to use to separate numbers. It can be an <img/>, a comma, an hyphen, or whatever.
377 'spacesBeforeSeparator'=>0,//Number of spaces before the separator.
378 'spacesAfterSeparator'=>0,//Number of spaces after the separator.
379 'firstPagePre'=>' ',//String used before first page number. It can be an <img/>, a "{", an empty string, or whatever.
380 'firstPageText'=>'<span class="paginationFirst">'.Ak
::t('first').'</span>',//String used in place of first page number.
381 'firstPagePost'=>' ',//String used after first page number. It can be an <img/>, a "}", an empty string, or whatever.
382 'lastPagePre'=>' ',//Similar to firstPagePre, but used for last page number.
383 'lastPageText'=>'<span class="paginationLast">'.Ak
::t('last').'</span>',//Similar to firstPageText, but used for last page number.
384 'lastPagePost'=>' ',//Similar to firstPagePost, but used for last page number.
385 'clearIfVoid'=>true,//if there's only one page, don't display pager links (returns an empty string).
386 'useSessions'=>true,//if TRUE, number of items to display per page is stored in the $_SESSION[$_sessionVar] var.
387 'closeSession'=>false,//if TRUE, the session is closed just after R/W.
388 'sessionVar'=>$controller_name.'_paginator',//Name of the session var for perPage value. A value different from default can be useful when using more than one Pager istance in the page.
389 'showAllText'=>Ak
::t('show all')// Text to be used for the 'show all' option in the select box generated by getPerPageSelectBox()
392 $paginator[$controller_name.'_paginator'] =& new AkPager();
393 $paginator[$controller_name.'_paginator']->controller
=& $controller;
394 $paginator[$controller_name.'_paginator']->init($pager_options);
397 $this->paginator
=& $paginator[$controller_name.'_paginator'];
398 $this->controller
->paginator
=& $this->paginator
;
400 $this->links
= $this->links();
402 //$paginator[$controller_name.'_paginator']->links = 'Hola';
403 return $paginator[$controller_name.'_paginator'];
407 function &getController()
409 return $this->controller
;
412 function getItemCount()
414 return $this->item_count
;
417 function getItemsPerPage()
419 return $this->items_per_page
;
424 return array_shift($this->paginator
->getOffsetByPageId($this->getCurrent()))-1;
427 function getCurrent()
429 return $this->paginator
->getCurrentPageID();
432 function getCurrentPage()
434 return $this->paginator
->getCurrentPageID();
437 function getFirstPage()
448 return $this->paginator
->getLastPage();
453 return $this->paginator
->numPages();
458 return $this->pageCount();
462 * Returns true if this paginator contains the page of index +number+.
464 function hasPageNumber($number)
466 return $number >= 1 && $number <= $this->pageCount();
471 return $this->paginator
->links
;