[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionController/ -> AkPaginator.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   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  // +----------------------------------------------------------------------+
  10  
  11  /**
  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>
  17   */
  18  
  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');
  21  
  22  /**
  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>,
  26   */
  27  
  28  
  29  class AkPager extends Pager_Common
  30  {
  31      // {{{ AkPager()
  32  
  33      /**
  34       * Constructor
  35       *
  36       * @param mixed $options    An associative array of option names
  37       *                          and their values
  38       * @access public
  39       */
  40      function init($options = array())
  41      {
  42          //set default AkPager options
  43          $this->_delta                 = 2;
  44          $this->_prevImg               = '&laquo;';
  45          $this->_nextImg               = '&raquo;';
  46          $this->_separator             = '|';
  47          $this->_spacesBeforeSeparator = 3;
  48          $this->_spacesAfterSeparator  = 3;
  49          $this->_curPageSpanPre        = '<b><u>';
  50          $this->_curPageSpanPost       = '</u></b>';
  51  
  52          //set custom options
  53          $err = $this->_setOptions($options);
  54          if ($err !== PAGER_OK) {
  55              return $this->raiseError($this->errorMessage($err), $err);
  56          }
  57          $this->_generatePageData();
  58          $this->_setFirstLastText();
  59  
  60          if ($this->_totalPages > (2 * $this->_delta + 1)) {
  61              $this->links .= $this->_printFirstPage();
  62          }
  63  
  64          $this->links .= $this->_getBackLink();
  65          $this->links .= $this->_getPageLinks();
  66          $this->links .= $this->_getNextLink();
  67  
  68          $this->linkTags .= $this->_getFirstLinkTag();
  69          $this->linkTags .= $this->_getPrevLinkTag();
  70          $this->linkTags .= $this->_getNextLinkTag();
  71          $this->linkTags .= $this->_getLastLinkTag();
  72  
  73          if ($this->_totalPages > (2 * $this->_delta + 1)) {
  74              $this->links .= $this->_printLastPage();
  75          }
  76      }
  77  
  78      // }}}
  79      // {{{ getPageIdByOffset()
  80  
  81      /**
  82       * "Overload" PEAR::Pager method. VOID. Not needed here...
  83       * @param integer $index Offset to get pageID for
  84       * @deprecated
  85       * @access public
  86       */
  87      function getPageIdByOffset($index=null) { }
  88  
  89      // }}}
  90      // {{{ getPageRangeByPageId()
  91  
  92      /**
  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#.
  99       *
 100       * @param integer PageID to get offsets for
 101       * @return array  First and last offsets
 102       * @access public
 103       */
 104      function getPageRangeByPageId($pageid = null)
 105      {
 106          $pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
 107          if (!isset($this->_pageData)) {
 108              $this->_generatePageData();
 109          }
 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;
 115              } else {
 116                  $min_surplus = $max_surplus = 0;
 117              }
 118              return array(
 119                  max($pageid - $this->_delta - $max_surplus, 1),
 120                  min($pageid + $this->_delta + $min_surplus, $this->_totalPages)
 121              );
 122          }
 123          return array(0, 0);
 124      }
 125  
 126      // }}}
 127      // {{{ getLinks()
 128  
 129      /**
 130       * Returns back/next/first/last and page links,
 131       * both as ordered and associative array.
 132       *
 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
 136       * @access public
 137       */
 138      function getLinks($pageID = null)
 139      {
 140          if ($pageID != null) {
 141              $_sav = $this->_currentPage;
 142              $this->_currentPage = $pageID;
 143  
 144              $this->links = '';
 145              if ($this->_totalPages > (2 * $this->_delta + 1)) {
 146                  $this->links .= $this->_printFirstPage();
 147              }
 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();
 153              }
 154          }
 155  
 156          $back  = str_replace('&nbsp;', '', $this->_getBackLink());
 157          $next  = str_replace('&nbsp;', '', $this->_getNextLink());
 158          $pages = $this->_getPageLinks();
 159          $first = $this->_printFirstPage();
 160          $last  = $this->_printLastPage();
 161          $all   = $this->links;
 162          $linkTags = $this->linkTags;
 163  
 164          if ($pageID != null) {
 165              $this->_currentPage = $_sav;
 166          }
 167  
 168          return array(
 169              $back,
 170              $pages,
 171              trim($next),
 172              $first,
 173              $last,
 174              $all,
 175              $linkTags,
 176              'back'  => $back,
 177              'pages' => $pages,
 178              'next'  => $next,
 179              'first' => $first,
 180              'last'  => $last,
 181              'all'   => $all,
 182              'linktags' => $linkTags
 183          );
 184      }
 185  
 186      // }}}
 187      // {{{ _getPageLinks()
 188  
 189      /**
 190       * Returns pages link
 191       *
 192       * @return string Links
 193       * @access private
 194       */
 195      function _getPageLinks($url = '')
 196      {
 197          //legacy setting... the preferred way to set an option now
 198          //is adding it to the constuctor
 199          if (!empty($url)) {
 200              $this->_path = $url;
 201          }
 202          
 203          //If there's only one page, don't display links
 204          if ($this->_clearIfVoid && ($this->_totalPages < 2)) {
 205              return '';
 206          }
 207  
 208          $links = '';
 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);
 213                  } else {
 214                      $expansion_before = 0;
 215                  }
 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)
 218                      
 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 : '');
 224                  }
 225              }
 226  
 227              $expansion_after = 0;
 228              for ($i = $this->_currentPage - $this->_delta; ($i <= $this->_currentPage + $this->_delta) && ($i <= $this->_totalPages); $i++) {
 229                  if ($i < 1) {
 230                      ++$expansion_after;
 231                      continue;
 232                  }
 233  
 234                  // check when to print separator
 235                  $print_separator_flag = (($i != $this->_currentPage + $this->_delta) && ($i != $this->_totalPages));
 236  
 237                  if ($i == $this->_currentPage) {
 238                      $this->range[$i] = true;
 239                      $links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
 240                  } else {
 241                      $this->range[$i] = false;
 242                      $this->_linkData[$this->_urlVar] = $i;
 243                      $links .= $this->_renderLink($this->_altPage.' '.$i, $i);
 244                  }
 245                  $links .= $this->_spacesBefore
 246                          . ($print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
 247              }
 248  
 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 : '');
 258                  }
 259              }
 260  
 261          } else {
 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);
 268                  } else {
 269                      $this->range[$i] = true;
 270                      $links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
 271                  }
 272                  $links .= $this->_spacesBefore
 273                         . (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
 274              }
 275          }
 276          return $links;
 277      }
 278  
 279      // }}}
 280      
 281      /**
 282       * Renders a link using the appropriate method
 283       *
 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
 287       * @access private
 288       */
 289      function _renderLink($altText, $linkText)
 290      {        
 291          $href = $this->controller->url_helper->modify_current_url($this->_linkData);
 292          
 293          if ($this->_httpMethod == 'GET') {
 294  
 295              return sprintf('<a href="%s"%s title="%s">%s</a>',
 296                             $href,
 297                             empty($this->_classString) ? '' : ' '.$this->_classString,
 298                             $altText,
 299                             $linkText
 300              );
 301          }
 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,
 306                             $altText,
 307                             $linkText
 308              );
 309          }
 310          return '';
 311      }
 312  
 313  
 314  }
 315  
 316  
 317  /**
 318  * A class representing a paginator for an Active Record collection.
 319  */
 320  class AkPaginator
 321  {
 322      /**
 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+.
 328      */
 329      function &AkPaginator(&$controller, $item_count, $items_per_page, $current_page=1)
 330      {
 331          static $paginator;
 332          if($items_per_page <= 0){
 333              trigger_error(Ak::t('must have at least one item per page'),E_USER_WARNING);
 334          }
 335  
 336          if(empty($current_page)){
 337              $current_page = 1;
 338              $controller->params[$controller->_pagination_options['parameter']] = 1;
 339          }
 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);
 345  
 346          if(!isset($paginator[$controller_name.'_paginator'])){
 347              
 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()
 390              );
 391              
 392              $paginator[$controller_name.'_paginator'] =& new AkPager();
 393              $paginator[$controller_name.'_paginator']->controller =& $controller;
 394              $paginator[$controller_name.'_paginator']->init($pager_options);
 395          }
 396  
 397          $this->paginator =& $paginator[$controller_name.'_paginator'];
 398          $this->controller->paginator =& $this->paginator;
 399          
 400          $this->links = $this->links();
 401          
 402          //$paginator[$controller_name.'_paginator']->links = 'Hola';
 403          return $paginator[$controller_name.'_paginator'];
 404  
 405      }
 406  
 407      function &getController()
 408      {
 409          return $this->controller;
 410      }
 411  
 412      function getItemCount()
 413      {
 414          return $this->item_count;
 415      }
 416  
 417      function getItemsPerPage()
 418      {
 419          return $this->items_per_page;
 420      }
 421      
 422      function getOffset()
 423      {
 424          return array_shift($this->paginator->getOffsetByPageId($this->getCurrent()))-1;
 425      }
 426  
 427      function getCurrent()
 428      {
 429          return $this->paginator->getCurrentPageID();
 430      }
 431      
 432      function getCurrentPage()
 433      {
 434          return $this->paginator->getCurrentPageID();
 435      }
 436  
 437      function getFirstPage()
 438      {
 439          return 1;
 440      }
 441      function getFirst()
 442      {
 443          return 1;
 444      }
 445  
 446      function getLast()
 447      {
 448          return $this->paginator->getLastPage();
 449      }
 450  
 451      function pageCount()
 452      {
 453          return $this->paginator->numPages();
 454      }
 455  
 456      function lenght()
 457      {
 458          return $this->pageCount();
 459      }
 460  
 461      /**
 462        * Returns true if this paginator contains the page of index +number+.
 463        */
 464      function hasPageNumber($number)
 465      {
 466          return $number >= 1 && $number <= $this->pageCount();
 467      }
 468      
 469      function links()
 470      {
 471          return $this->paginator->links;
 472      }
 473  
 474  }
 475  
 476  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6