home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / Sliding.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  34.3 KB  |  1,136 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: Pager_Sliding                                                |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2002 The PHP Group                                |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.0 of the PHP license,       |
  8. // | that is bundled with this package in the file LICENSE, and is        |
  9. // | available at through the world-wide-web at                           |
  10. // | http://www.php.net/license/2_02.txt.                                 |
  11. // | If you did not receive a copy of the PHP license and are unable to   |
  12. // | obtain it through the world-wide-web, please send a note to          |
  13. // | license@php.net so we can mail you a copy immediately.               |
  14. // +----------------------------------------------------------------------+
  15. // | Author: Lorenzo Alberton <l.alberton at quipo.it>                    |
  16. // +----------------------------------------------------------------------+
  17. //
  18. // $Id: Sliding.php,v 1.19 2003/12/16 20:48:49 quipo Exp $
  19. /**
  20.  * File Sliding.php
  21.  *
  22.  * @package Pager_Sliding
  23.  */
  24. /**
  25.  * Two constants used to guess the path- and file-name of the page
  26.  * when the user doesn't set any pther value
  27.  */
  28. define('CURRENT_FILENAME', basename($_SERVER['PHP_SELF']));
  29. define('CURRENT_PATHNAME', str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])));
  30. /**
  31.  * Error codes
  32.  */
  33. if (!defined('ERROR_PAGER_SLIDING_INVALID')) {
  34.     define('ERROR_PAGER_SLIDING_INVALID', -1);
  35. }
  36. /**
  37.  * Pager_Sliding - Generic data paging class  ("sliding window" style)
  38.  *
  39.  * Usage examples can be found in the doc provided
  40.  *
  41.  * @author  Lorenzo Alberton <l.alberton at quipo.it>
  42.  * @version $Id: Sliding.php,v 1.19 2003/12/16 20:48:49 quipo Exp $
  43.  * @package Pager_Sliding
  44.  */
  45. class Pager_Sliding
  46. {
  47.  
  48.     // {{{ private class vars
  49.  
  50.     /**
  51.      * @var integer number of items
  52.      * @access private
  53.      */
  54.     var $_totalItems;
  55.  
  56.     /**
  57.      * @var integer number of items per page
  58.      * @access private
  59.      */
  60.     var $_perPage     = 10;
  61.  
  62.     /**
  63.      * @var integer number of page links before and after the current one
  64.      * @access private
  65.      */
  66.     var $_delta       = 2;
  67.  
  68.     /**
  69.      * @var integer current page number
  70.      * @access private
  71.      */
  72.     var $_currentPage = 1;
  73.  
  74.     /**
  75.      * @var string CSS class for links
  76.      * @access private
  77.      */
  78.     var $_linkClass   = '';
  79.  
  80.     /**
  81.      * @var string wrapper for CSS class name
  82.      * @access private
  83.      */
  84.     var $_classString = '';
  85.  
  86.     /**
  87.      * @var string path name
  88.      * @access private
  89.      */
  90.     var $_path        = CURRENT_PATHNAME;
  91.  
  92.     /**
  93.      * @var string file name
  94.      * @access private
  95.      */
  96.     var $_fileName    = CURRENT_FILENAME;
  97.  
  98.     /**
  99.      * @var boolean you have to use FALSE with mod_rewrite
  100.      * @access private
  101.      */
  102.     var $_append      = true;
  103.  
  104.     /**
  105.      * @var string name of the querystring var for pageID
  106.      * @access private
  107.      */
  108.     var $_urlVar      = 'pageID';
  109.  
  110.     /**
  111.      * @var string name of the url without the pageID number
  112.      * @access private
  113.      */
  114.     var $_url         = '';
  115.  
  116.     /**
  117.      * @var string alt text for "previous page"
  118.      * @access private
  119.      */
  120.     var $_altPrev     = 'previous page';
  121.  
  122.     /**
  123.      * @var string alt text for "next page"
  124.      * @access private
  125.      */
  126.     var $_altNext     = 'next page';
  127.  
  128.     /**
  129.      * @var string alt text for "page"
  130.      * @access private
  131.      */
  132.     var $_altPage     = 'page';
  133.  
  134.     /**
  135.      * @var string image/text to use as "prev" link
  136.      * @access private
  137.      */
  138.     var $_prevImg     = '«';
  139.  
  140.     /**
  141.      * @var string image/text to use as "next" link
  142.      * @access private
  143.      */
  144.     var $_nextImg     = '»';
  145.  
  146.     /**
  147.      * @var boolean TRUE => expanded mode
  148.      * @access private
  149.      */
  150.     var $_expanded    = true;
  151.  
  152.     /**
  153.      * @var string link separator
  154.      * @access private
  155.      */
  156.     var $_separator   = '|';
  157.  
  158.     /**
  159.      * @var integer number of spaces before separator
  160.      * @access private
  161.      */
  162.     var $_spacesBeforeSeparator = 3;
  163.  
  164.     /**
  165.      * @var integer number of spaces after separator
  166.      * @access private
  167.      */
  168.     var $_spacesAfterSeparator  = 3;
  169.  
  170.     /**
  171.      * @var string CSS class name for current page link
  172.      * @access private
  173.      */
  174.     var $_curPageLinkClassName  = '';
  175.  
  176.     /**
  177.      * @var string Text before current page link
  178.      * @access private
  179.      */
  180.     var $_curPageSpanPre        = '<b><u>';
  181.  
  182.     /**
  183.      * @var string Text after current page link
  184.      * @access private
  185.      */
  186.     var $_curPageSpanPost       = '</u></b>';
  187.  
  188.     /**
  189.      * @var string Text before first page link
  190.      * @access private
  191.      */
  192.     var $_firstPagePre  = '[';
  193.  
  194.     /**
  195.      * @var string Text to be used for first page link
  196.      * @access private
  197.      */
  198.     var $_firstPageText = '';
  199.  
  200.     /**
  201.      * @var string Text after first page link
  202.      * @access private
  203.      */
  204.     var $_firstPagePost = ']';
  205.  
  206.     /**
  207.      * @var string Text before last page link
  208.      * @access private
  209.      */
  210.     var $_lastPagePre   = '[';
  211.  
  212.     /**
  213.      * @var string Text to be used for last page link
  214.      * @access private
  215.      */
  216.     var $_lastPageText  = '';
  217.  
  218.     /**
  219.      * @var string Text after last page link
  220.      * @access private
  221.      */
  222.     var $_lastPagePost  = ']';
  223.  
  224.     /**
  225.      * @var string Will contain the HTML code for the spaces
  226.      * @access private
  227.      */
  228.     var $_spacesBefore  = '';
  229.  
  230.     /**
  231.      * @var string Will contain the HTML code for the spaces
  232.      * @access private
  233.      */
  234.     var $_spacesAfter   = '';
  235.  
  236.     /**
  237.      * @var array data to be paged
  238.      * @access private
  239.      */
  240.     var $_itemData      = null;
  241.  
  242.     /**
  243.      * @var boolean If TRUE and there's only one page, links aren't shown
  244.      * @access private
  245.      */
  246.     var $_clearIfVoid   = true;
  247.  
  248.     /**
  249.      * @var boolean Use session for storing the number of items per page
  250.      * @access private
  251.      */
  252.     var $_useSessions   = false;
  253.  
  254.     /**
  255.      * @var boolean Close the session when finished reading/writing data
  256.      * @access private
  257.      */
  258.     var $_closeSession  = false;
  259.  
  260.     /**
  261.      * @var string name of the session var for number of items per page
  262.      * @access private
  263.      */
  264.     var $_sessionVar    = 'setPerPage';
  265.  
  266.     /**
  267.      * Pear error mode (when raiseError is called)
  268.      * (see PEAR doc)
  269.      *
  270.      * @var int $_pearErrorMode
  271.      */
  272.     var $_pearErrorMode = null;
  273.  
  274.     // }}}
  275.  
  276.     /**
  277.      * @var string Complete set of links
  278.      * @access public
  279.      */
  280.     var $links = '';
  281.  
  282.     /**
  283.      * @var array Array with a key => value pair representing
  284.      *            page# => bool value (true if key==currentPageNumber).
  285.      *            can be used for extreme customization.
  286.      * @access public
  287.      */
  288.     var $range = array();
  289.  
  290.     // {{{ Pager_Sliding()
  291.  
  292.     /**
  293.      * Constructor
  294.      *
  295.      * -------------------------------------------------------------------------
  296.      * VALID options are (default values are set some lines before):
  297.      *  - totalItems (int):    # of items to page.
  298.      *  - perPage    (int):    # of items per page.
  299.      *  - delta      (int):    # of page #s to show before and after the current
  300.      *                         one
  301.      *  - expanded   (bool):   if true, window size is always 2*delta+1
  302.      *  - linkClass  (string): name of CSS class used for link styling.
  303.      *  - append     (bool):   if true pageID is appended as GET value to the
  304.      *                         URL - if false it is embedded in the URL
  305.      *                         according to "fileName" specs
  306.      *  - path       (string): complete path to the page (without the page name)
  307.      *  - fileName   (string): name of the page, with a %d if append=true
  308.      *  - urlVar     (string): name of pageNumber URL var, for example "pageID"
  309.      *  - altPrev    (string): alt text to display for prev page, on prev link.
  310.      *  - altNext    (string): alt text to display for next page, on next link.
  311.      *  - altPage    (string): alt text to display before the page number.
  312.      *  - prevImg    (string): sth (it can be text such as "<< PREV" or an
  313.      *                         <img/> as well...) to display instead of "<<".
  314.      *  - nextImg    (string): same as prevImg, used for NEXT link, instead of
  315.      *                         the default value, which is ">>".
  316.      *  - separator  (string): what to use to separate numbers (can be an
  317.      *                         <img/>, a comma, an hyphen, or whatever.
  318.      *  - spacesBeforeSeparator
  319.      *               (int):    number of spaces before the separator.
  320.      *  - firstPagePre (string):
  321.      *                         string used before first page number (can be an
  322.      *                         <img/>, a "{", an empty string, or whatever.
  323.      *  - firstPageText (string):
  324.      *                         string used in place of first page number
  325.      *  - firstPagePost (string):
  326.      *                         string used after first page number (can be an
  327.      *                         <img/>, a "}", an empty string, or whatever.
  328.      *  - lastPagePre (string):
  329.      *                         similar to firstPagePre.
  330.      *  - lastPageText (string):
  331.      *                         similar to firstPageText.
  332.      *  - lastPagePost (string):
  333.      *                         similar to firstPagePost.
  334.      *  - spacesAfterSeparator
  335.      *               (int):    number of spaces after the separator.
  336.      *  - curPageLinkClassName
  337.      *               (string): name of CSS class used for current page link.
  338.      *  - clearIfVoid(bool):   if there's only one page, don't display pager.
  339.      *  - itemData   (array):  array of items to page.
  340.      *  - useSessions (bool):  if true, number of items to display per page is
  341.      *                         stored in the $_SESSION[$_sessionVar] var.
  342.      *  - closeSession (bool): if true, the session is closed just after R/W.
  343.      *  - sessionVar (string): name of the session var for perPage value.
  344.      *                         A value != from default can be useful when
  345.      *                         using more than one Pager istance in the page.
  346.      *  - pearErrorMode (constant):
  347.      *                         PEAR_ERROR mode for raiseError().
  348.      *                         Default is PEAR_ERROR_RETURN.
  349.      * -------------------------------------------------------------------------
  350.      * REQUIRED options are:
  351.      *  - fileName IF append==false (default is true)
  352.      *  - itemData OR totalItems (if itemData is set, totalItems is overwritten)
  353.      * -------------------------------------------------------------------------
  354.      *
  355.      * @param mixed $options    An associative array of option names and
  356.      *                          their values.
  357.      * @access public
  358.      */
  359.     function Pager_Sliding($options = array())
  360.     {
  361.         $this->_setOptions($options);
  362.         $this->_generatePageData();
  363.         $this->_setFirstLastText();
  364.  
  365.         if ($this->_totalPages > (2 * $this->_delta + 1)) {
  366.             $this->links .= $this->_printFirstPage();
  367.         }
  368.  
  369.         $this->links .= $this->_getBackLink();
  370.         $this->links .= $this->_getPageLinks();
  371.         $this->links .= $this->_getNextLink();
  372.  
  373.         if ($this->_totalPages > (2 * $this->_delta + 1)) {
  374.             $this->links .= $this->_printLastPage();
  375.         }
  376.     }
  377.  
  378.     // }}}
  379.     // {{{ getPageData()
  380.  
  381.     /**
  382.      * Returns an array of current pages data
  383.      *
  384.      * @param $pageID Desired page ID (optional)
  385.      * @return array Page data
  386.      * @access public
  387.      */
  388.     function getPageData($pageID = null)
  389.     {
  390.         if (isset($pageID)) {
  391.             if (!empty($this->_pageData[$pageID])) {
  392.                 return $this->_pageData[$pageID];
  393.             } else {
  394.                 return false;
  395.             }
  396.         }
  397.  
  398.         if (!isset($this->_pageData)) {
  399.             $this->_generatePageData();
  400.         }
  401.  
  402.         return $this->getPageData($this->_currentPage);
  403.     }
  404.  
  405.     // }}}
  406.     // {{{ getPageIdByOffset()
  407.  
  408.     /**
  409.      * "Overload" PEAR::Pager method. VOID. Not needed here...
  410.      * @param integer $index Offset to get pageID for
  411.      * @deprecated
  412.      * @access public
  413.      */
  414.     function getPageIdByOffset($index = null) { }
  415.  
  416.     // }}}
  417.     // {{{ getOffsetByPageId()
  418.  
  419.     /**
  420.      * Returns offsets for given pageID. Eg, if you
  421.      * pass it pageID one and your perPage limit is 10
  422.      * it will return you 1 and 10. PageID of 2 would
  423.      * give you 11 and 20.
  424.      *
  425.      * @param integer PageID to get offsets for
  426.      * @return array  First and last offsets
  427.      * @access public
  428.      */
  429.     function getOffsetByPageId($pageid = null)
  430.     {
  431.         $pageid = isset($pageid) ? $pageid : $this->_currentPage;
  432.         if (!isset($this->_pageData)) {
  433.             $this->_generatePageData();
  434.         }
  435.  
  436.         if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
  437.             return array(
  438.                         max(($this->_perPage * ($pageid - 1)) + 1, 1),
  439.                         min($this->_totalItems, $this->_perPage * $pageid)
  440.                    );
  441.         } else {
  442.             return array(0, 0);
  443.         }
  444.     }
  445.  
  446.     // }}}
  447.     // {{{ getPageRangeByPageId()
  448.  
  449.     /**
  450.      * Given a PageId, it returns the limits of the range of pages displayed.
  451.      * While getOffsetByPageId() returns the offset of the data within the
  452.      * current page, this method returns the offsets of the page numbers interval.
  453.      * E.g., if you have pageId=5 and delta=2, it will return (3, 7).
  454.      * PageID of 9 would give you (4, 8).
  455.      * If the method is called without parameter, pageID is set to currentPage#.
  456.      *
  457.      * @param integer PageID to get offsets for
  458.      * @return array  First and last offsets
  459.      * @access public
  460.      */
  461.     function getPageRangeByPageId($pageid = null)
  462.     {
  463.         $pageid = isset($pageid) ? (int)$pageid : $this->_currentPage;
  464.         if (!isset($this->_pageData)) {
  465.             $this->_generatePageData();
  466.         }
  467.         if (isset($this->_pageData[$pageid]) || is_null($this->_itemData)) {
  468.             if ($this->_expanded) {
  469.                 $min_surplus = ($pageid <= $this->_delta) ? ($this->_delta - $pageid + 1) : 0;
  470.                 $max_surplus = ($pageid >= ($this->_totalPages - $this->_delta)) ?
  471.                                 ($pageid - ($this->_totalPages - $this->_delta)) : 0;
  472.             } else {
  473.                 $min_surplus = 0;
  474.                 $max_surplus = 0;
  475.             }
  476.             return array(   max($pageid - $this->_delta - $max_surplus, 1),
  477.                             min($pageid + $this->_delta + $min_surplus, $this->_totalPages));
  478.         } else {
  479.             return array(0, 0);
  480.         }
  481.     }
  482.  
  483.     // }}}
  484.     // {{{ getCurrentPageID()
  485.  
  486.     /**
  487.      * Returns ID of current page
  488.      *
  489.      * @return integer ID of current page
  490.      * @access public
  491.      */
  492.     function getCurrentPageID()
  493.     {
  494.         return $this->_currentPage;
  495.     }
  496.  
  497.     // }}}
  498.     // {{{ getNextPageID()
  499.  
  500.     /**
  501.      * Returns next page ID. If current page is last page
  502.      * this function returns FALSE
  503.      *
  504.      * @return mixed Next pages' ID
  505.      * @access public
  506.      */
  507.     function getNextPageID()
  508.     {
  509.         return ($this->_currentPage == $this->_totalPages ?
  510.                            false : $this->_currentPage + 1);
  511.     }
  512.  
  513.     // }}}
  514.     // {{{ getPreviousPageID()
  515.  
  516.     /**
  517.      * Returns previous page ID. If current page is first page
  518.      * this function returns FALSE
  519.      *
  520.      * @return mixed Previous pages' ID
  521.      * @access public
  522.      */
  523.     function getPreviousPageID()
  524.     {
  525.         return $this->isFirstPage() ? false : $this->getCurrentPageID() - 1;
  526.     }
  527.  
  528.     // }}}
  529.     // {{{ numItems()
  530.  
  531.     /**
  532.      * Returns number of items
  533.      *
  534.      * @return int Number of items
  535.      * @access public
  536.      */
  537.     function numItems()
  538.     {
  539.         return $this->_totalItems;
  540.     }
  541.  
  542.     // }}}
  543.     // {{{ numPages()
  544.  
  545.     /**
  546.      * Returns number of pages
  547.      *
  548.      * @return int Number of pages
  549.      * @access public
  550.      */
  551.     function numPages()
  552.     {
  553.         return (int)$this->_totalPages;
  554.     }
  555.  
  556.     // }}}
  557.     // {{{ isFirstPage()
  558.  
  559.     /**
  560.      * Returns whether current page is first page
  561.      *
  562.      * @return bool First page or not
  563.      * @access public
  564.      */
  565.     function isFirstPage()
  566.     {
  567.         return ($this->_currentPage < 2);
  568.     }
  569.  
  570.     // }}}
  571.     // {{{ isLastPage()
  572.  
  573.     /**
  574.      * Returns whether current page is last page
  575.      *
  576.      * @return bool Last page or not
  577.      * @access public
  578.      */
  579.     function isLastPage()
  580.     {
  581.         return ($this->_currentPage == $this->_totalPages);
  582.     }
  583.  
  584.     // }}}
  585.     // {{{ isLastPageComplete()
  586.  
  587.     /**
  588.      * Returns whether last page is complete
  589.      *
  590.      * @return bool Last page complete or not
  591.      * @access public
  592.      */
  593.     function isLastPageComplete()
  594.     {
  595.         return !($this->_totalItems % $this->_perPage);
  596.     }
  597.  
  598.     // }}}
  599.     // {{{ getLinks()
  600.  
  601.     /**
  602.      * Returns back/next/first/last and page links,
  603.      * both as ordered and associative array.
  604.      *
  605.      * @param integer $pageID Optional pageID. If specified, links
  606.      *                for that page are provided instead of current one.
  607.      * @return array back/pages/next/first/last/all links
  608.      * @access public
  609.      */
  610.     function getLinks($pageID = null)
  611.     {
  612.         if (!is_null($pageID)) {
  613.             $_sav = $this->_currentPage;
  614.             $this->_currentPage = $pageID;
  615.  
  616.             $this->links = '';
  617.             if ($this->_totalPages > (2 * $this->_delta + 1)) {
  618.                 $this->links .= $this->_printFirstPage();
  619.             }
  620.             $this->links .= $this->_getBackLink();
  621.             $this->links .= $this->_getPageLinks();
  622.             $this->links .= $this->_getNextLink();
  623.             if ($this->_totalPages > (2 * $this->_delta + 1)) {
  624.                 $this->links .= $this->_printLastPage();
  625.             }
  626.         }
  627.  
  628.         $back  = str_replace(' ', '', $this->_getBackLink());
  629.         $next  = str_replace(' ', '', $this->_getNextLink());
  630.         $pages = $this->_getPageLinks();
  631.         $first = $this->_printFirstPage();
  632.         $last  = $this->_printLastPage();
  633.         $all   = $this->links;
  634.  
  635.         if ($pageID != null) {
  636.             $this->_currentPage = $_sav;
  637.         }
  638.  
  639.         return array(
  640.                     $back,
  641.                     $pages,
  642.                     trim($next),
  643.                     $first,
  644.                     $last,
  645.                     $all,
  646.                     'back'  => $back,
  647.                     'pages' => $pages,
  648.                     'next'  => $next,
  649.                     'first' => $first,
  650.                     'last'  => $last,
  651.                     'all'   => $all
  652.                 );
  653.     }
  654.  
  655.     // }}}
  656.     // {{{ getPerPageSelectBox()
  657.  
  658.     /**
  659.      * Returns a string with a XHTML SELECT menu,
  660.      * useful for letting the user choose how many items per page should be
  661.      * displayed. If parameter useSessions is TRUE, this value is stored in
  662.      * a session var. The string isn't echoed right now so you can use it
  663.      * with template engines.
  664.      *
  665.      * @param integer $start
  666.      * @param integer $end
  667.      * @param integer $step
  668.      * @return string xhtml select box
  669.      * @access public
  670.      */
  671.     function getPerPageSelectBox($start=5, $end=30, $step=5)
  672.     {
  673.         $start = (int)$start;
  674.         $end   = (int)$end;
  675.         $step  = (int)$step;
  676.         if (!empty($_SESSION[$this->_sessionVar])) {
  677.             $selected = (int)$_SESSION[$this->_sessionVar];
  678.         } else {
  679.             $selected = $start;
  680.         }
  681.  
  682.         $tmp = '<select name="'.$this->_sessionVar.'">';
  683.         for ($i=$start; $i<=$end; $i+=$step) {
  684.             $tmp .= '<option value="'.$i.'"';
  685.             if ($i == $selected) {
  686.                 $tmp .= ' selected="selected"';
  687.             }
  688.             $tmp .= '>'.$i.'</option>';
  689.         }
  690.         $tmp .= '</select>';
  691.         return $tmp;
  692.     }
  693.  
  694.     // }}}
  695.     // {{{ _getPageLinks()
  696.  
  697.     /**
  698.      * Returns pages link
  699.      *
  700.      * @return string Links
  701.      * @access private
  702.      */
  703.     function _getPageLinks()
  704.     {
  705.         $links = '';
  706.         if ($this->_totalPages > (2 * $this->_delta + 1)) {
  707.             if ($this->_expanded) {
  708.                 if (($this->_totalPages - $this->_delta) <= $this->_currentPage) {
  709.                     $_expansion_before = $this->_currentPage - ($this->_totalPages - $this->_delta);
  710.                 } else {
  711.                     $_expansion_before = 0;
  712.                 }
  713.                 for ($i = $this->_currentPage - $this->_delta - $_expansion_before; $_expansion_before; $_expansion_before--, $i++) {
  714.                     if (($i != $this->_currentPage + $this->_delta)){ // && ($i != $this->_totalPages - 1)) {
  715.                         $_print_separator_flag = true;
  716.                     } else {
  717.                         $_print_separator_flag = false;
  718.                     }
  719.  
  720.                     $this->range[$i] = false;
  721.                     $links .= sprintf('<a href="%s" %s title="%s">%d</a>',
  722.                                         ( $this->_append ? $this->_url.$i : $this->_url.sprintf($this->_fileName, $i) ),
  723.                                         $this->_classString,
  724.                                         $this->_altPage.' '.$i,
  725.                                         $i)
  726.                            . $this->_spacesBefore
  727.                            . ($_print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
  728.                 }
  729.             }
  730.  
  731.  
  732.             $_expansion_after = 0;
  733.             for ($i = $this->_currentPage - $this->_delta; ($i <= $this->_currentPage + $this->_delta) && ($i <= $this->_totalPages); $i++) {
  734.                 if ($i<1) {
  735.                     $_expansion_after++;
  736.                     continue;
  737.                 }
  738.  
  739.                 // check when to print separator
  740.                 if (($i != $this->_currentPage + $this->_delta) && ($i != $this->_totalPages )) {
  741.                     $_print_separator_flag = true;
  742.                 } else {
  743.                     $_print_separator_flag = false;
  744.                 }
  745.  
  746.                 if ($i == $this->_currentPage) {
  747.                     $this->range[$i] = true;
  748.                     $links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost
  749.                                  . $this->_spacesBefore
  750.                                  . ($_print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
  751.                 } else {
  752.                     $this->range[$i] = false;
  753.                     $links .= sprintf('<a href="%s" %s title="%s">%d</a>',
  754.                                         ( $this->_append ? $this->_url.$i : $this->_url.sprintf($this->_fileName, $i) ),
  755.                                         $this->_classString,
  756.                                         $this->_altPage.' '.$i,
  757.                                         $i)
  758.                                  . $this->_spacesBefore
  759.                                  . ($_print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
  760.                 }
  761.             }
  762.  
  763.             if ($this->_expanded && $_expansion_after) {
  764.                 $links .= $this->_separator . $this->_spacesAfter;
  765.                 for ($i = $this->_currentPage + $this->_delta +1; $_expansion_after; $_expansion_after--, $i++) {
  766.                     if (($_expansion_after != 1)) {
  767.                        $_print_separator_flag = true;
  768.                     } else {
  769.                         $_print_separator_flag = false;
  770.                     }
  771.  
  772.                     $this->range[$i] = false;
  773.                     $links .= sprintf('<a href="%s" %s title="%s">%d</a>',
  774.                                         ( $this->_append ? $this->_url.$i : $this->_url.sprintf($this->_fileName, $i) ),
  775.                                         $this->_classString,
  776.                                         $this->_altPage.' '.$i,
  777.                                         $i)
  778.                            . $this->_spacesBefore
  779.                            . ($_print_separator_flag ? $this->_separator.$this->_spacesAfter : '');
  780.                 }
  781.             }
  782.  
  783.         } else {
  784.             //if $this->_totalPages <= (2*Delta+1) show them all
  785.             for ($i=1; $i<=$this->_totalPages; $i++) {
  786.                 if ($i != $this->_currentPage) {
  787.                     $this->range[$i] = false;
  788.                     $links .= sprintf('<a href="%s" %s title="%s">%d</a>',
  789.                                     ( $this->_append ? $this->_url.$i : $this->_url.sprintf($this->_fileName, $i) ),
  790.                                     $this->_classString,
  791.                                     $this->_altPage.' '.$i,
  792.                                     $i);
  793.                 } else {
  794.                     $this->range[$i] = true;
  795.                     $links .= $this->_curPageSpanPre . $i . $this->_curPageSpanPost;
  796.                 }
  797.                 $links .= $this->_spacesBefore
  798.                        . (($i != $this->_totalPages) ? $this->_separator.$this->_spacesAfter : '');
  799.             }
  800.         }
  801.  
  802.         if ($this->_clearIfVoid) {
  803.             //If there's only one page, don't display links
  804.             if ($this->_totalPages < 2) $links = '';
  805.         }
  806.  
  807.         return $links;
  808.     }
  809.  
  810.     // }}}
  811.     // {{{ _getBackLink()
  812.  
  813.     /**
  814.      * Returns back link
  815.      *
  816.      * @param  string $url  URL to use in the link
  817.      * @param  string $link HTML to use as the link
  818.      * @return string The link
  819.      * @access private
  820.      */
  821.     function _getBackLink()   //function _getBackLink($url, $link = '<< Back')
  822.     {
  823.         if ($this->_currentPage > 1) {
  824.             $back = sprintf('<a href="%s" %s title="%s">%s</a>',
  825.                             ( $this->_append ? $this->_url.$this->getPreviousPageID() :
  826.                                     $this->_url.sprintf($this->_fileName, $this->getPreviousPageID()) ),
  827.                             $this->_classString,
  828.                             $this->_altPrev,
  829.                             $this->_prevImg)
  830.                   . $this->_spacesBefore . $this->_spacesAfter;
  831.         } else {
  832.             $back = '';
  833.         }
  834.         return $back;
  835.     }
  836.  
  837.     // }}}
  838.     // {{{ _getNextLink()
  839.  
  840.     /**
  841.      * Returns next link
  842.      *
  843.      * @return string The link
  844.      * @access private
  845.      */
  846.     function _getNextLink()   //function _getNextLink($url, $link = 'Next >>')
  847.     {
  848.         if ($this->_currentPage < $this->_totalPages) {
  849.             $next = $this->_spacesAfter
  850.                 . sprintf('<a href="%s" %s title="%s">%s</a>',
  851.                             ( $this->_append ? $this->_url.$this->getNextPageID() :
  852.                                     $this->_url.sprintf($this->_fileName, $this->getNextPageID()) ),
  853.                             $this->_classString,
  854.                             $this->_altNext,
  855.                             $this->_nextImg)
  856.                  . $this->_spacesBefore . $this->_spacesAfter;
  857.         } else {
  858.             $next = '';
  859.         }
  860.         return $next;
  861.     }
  862.  
  863.     // }}}
  864.     // {{{ _printFirstPage()
  865.  
  866.     /**
  867.      * Print [1]
  868.      *
  869.      * @return string String with link to 1st page,
  870.      *                or empty string if this is the 1st page.
  871.      * @access private
  872.      */
  873.     function _printFirstPage()
  874.     {
  875.         if ($this->isFirstPage()) {
  876.             return '';
  877.         } else {
  878.             return sprintf('<a href="%s" %s title="%s">%s%s%s</a>',
  879.                             ( $this->_append ? $this->_url.'1' : $this->_url.sprintf($this->_fileName, 1) ),
  880.                             $this->_classString,
  881.                             $this->_altPage.' 1',
  882.                             $this->_firstPagePre,
  883.                             $this->_firstPageText,
  884.                             $this->_firstPagePost)
  885.                  . $this->_spacesBefore . $this->_spacesAfter;
  886.  
  887.         }
  888.     }
  889.  
  890.     // }}}
  891.     // {{{ _printLastPage()
  892.  
  893.     /**
  894.      * Print [numPages()]
  895.      *
  896.      * @return string String with link to last page,
  897.      *                or empty string if this is the 1st page.
  898.      * @access private
  899.      */
  900.     function _printLastPage()
  901.     {
  902.         if ($this->isLastPage()) {
  903.             return '';
  904.         } else {
  905.             return sprintf('<a href="%s" %s title="%s">%s%s%s</a>',
  906.                             ( $this->_append ? $this->_url.$this->_totalPages : $this->_url.sprintf($this->_fileName, $this->_totalPages) ),
  907.                             $this->_classString,
  908.                             $this->_altPage.' '.$this->_totalPages,
  909.                             $this->_lastPagePre,
  910.                             $this->_lastPageText,
  911.                             $this->_lastPagePost);
  912.         }
  913.     }
  914.  
  915.     // }}}
  916.     // {{{ _generatePageData()
  917.  
  918.     /**
  919.      * Calculates all page data
  920.      *
  921.      * @access private
  922.      */
  923.     function _generatePageData()
  924.     {
  925.         // Been supplied an array of data?
  926.         if (!is_null($this->_itemData)) {
  927.             $this->_totalItems = count($this->_itemData);
  928.         }
  929.         $this->_totalPages = ceil((float)$this->_totalItems / (float)$this->_perPage);
  930.         $i = 1;
  931.         if (!empty($this->_itemData)) {
  932.             foreach ($this->_itemData as $key => $value) {
  933.                 $this->_pageData[$i][$key] = $value;
  934.                 if (count($this->_pageData[$i]) >= $this->_perPage) {
  935.                     $i++;
  936.                 }
  937.             }
  938.         } else {
  939.             $this->_pageData = array();
  940.         }
  941.  
  942.         //prevent URL manual modification
  943.         $this->_currentPage = min($this->_currentPage, $this->_totalPages);
  944.     }
  945.  
  946.  
  947.     // }}}
  948.     // {{{ _setFirstLastText()
  949.  
  950.     /**
  951.      * sets the private _firstPageText, _lastPageText variables
  952.      * based on whether they were set in the options
  953.      *
  954.      * @access private
  955.      */
  956.     function _setFirstLastText()
  957.     {
  958.         if ($this->_firstPageText == '') {
  959.             $this->_firstPageText = '1';
  960.         }
  961.  
  962.         if ($this->_lastPageText == '') {
  963.             $this->_lastPageText = $this->_totalPages;
  964.         }
  965.     }
  966.  
  967.     // }}}
  968.     // {{{ _getLinksUrl()
  969.  
  970.     /**
  971.      * Returns the correct link for the back/pages/next links
  972.      *
  973.      * @return string Url
  974.      * @access private
  975.      */
  976.     function _getLinksUrl()
  977.     {
  978.         // Sort out query string to prevent messy urls
  979.         $querystring = array();
  980.         $qs = array();
  981.         if (!empty($_SERVER['QUERY_STRING'])) {
  982.             $qs = explode('&', str_replace('&', '&', $_SERVER['QUERY_STRING']));
  983.             for ($i=0, $cnt=count($qs); $i<$cnt; $i++) {
  984.                 list($name, $value) = explode('=', $qs[$i]);
  985.                 if ($name != $this->_urlVar) {
  986.                     $qs[$name] = $value;
  987.                 }
  988.                 unset($qs[$i]);
  989.             }
  990.         }
  991.  
  992.         foreach ($qs as $name => $value) {
  993.             $querystring[] = $name . '=' . $value;
  994.         }
  995.  
  996.         return '?' . implode('&', $querystring) . (!empty($querystring) ? '&' : '') . $this->_urlVar .'=';
  997.     }
  998.  
  999.  
  1000.     // }}}
  1001.     // {{{ raiseError()
  1002.  
  1003.     /**
  1004.      * conditionally includes PEAR base class and raise an error
  1005.      *
  1006.      * @param string $msg  Error message
  1007.      * @param int    $code Error code
  1008.      * @access private
  1009.      */
  1010.     function raiseError($msg, $code)
  1011.     {
  1012.         include_once 'PEAR.php';
  1013.         if (empty($this->_pearErrorMode)) {
  1014.             $this->_pearErrorMode = PEAR_ERROR_RETURN;
  1015.         }
  1016.         PEAR::raiseError($msg, $code, $this->_pearErrorMode);
  1017.     }
  1018.  
  1019.     // }}}
  1020.     // {{{ _setOptions()
  1021.  
  1022.     /**
  1023.      * Set and sanitize options
  1024.      *
  1025.      * @param mixed $options    An associative array of option names and
  1026.      *                          their values.
  1027.      * @access private
  1028.      */
  1029.     function _setOptions($options)
  1030.     {
  1031.         $allowed_options = array(
  1032.             'totalItems',
  1033.             'perPage',
  1034.             'delta',
  1035.             'linkClass',
  1036.             'path',
  1037.             'fileName',
  1038.             'append',
  1039.             'urlVar',
  1040.             'altPrev',
  1041.             'altNext',
  1042.             'altPage',
  1043.             'prevImg',
  1044.             'nextImg',
  1045.             'expanded',
  1046.             'separator',
  1047.             'spacesBeforeSeparator',
  1048.             'spacesAfterSeparator',
  1049.             'curPageLinkClassName',
  1050.             'firstPagePre',
  1051.             'firstPageText',
  1052.             'firstPagePost',
  1053.             'lastPagePre',
  1054.             'lastPageText',
  1055.             'lastPagePost',
  1056.             'itemData',
  1057.             'clearIfVoid',
  1058.             'useSessions',
  1059.             'closeSession',
  1060.             'sessionVar',
  1061.             'pearErrorMode'
  1062.         );
  1063.  
  1064.         foreach ($options as $key => $value) {
  1065.             if (in_array($key, $allowed_options) && ($value !== null)) {
  1066.                 $this->{'_' . $key} = $value;
  1067.             }
  1068.         }
  1069.  
  1070.         $this->_fileName = ltrim($this->_fileName, '/');  //strip leading slash
  1071.         $this->_path     = rtrim($this->_path, '/');      //strip trailing slash
  1072.  
  1073.         if ($this->_append) {
  1074.             $this->_fileName = CURRENT_FILENAME; //avoid easy-verified user error;
  1075.             $this->_url = $this->_path.'/'.$this->_fileName.$this->_getLinksUrl();
  1076.         } else {
  1077.             $this->_url = $this->_path.'/';
  1078.             if (!strstr($this->_fileName,'%d')) {
  1079.                 $msg = '<b>Pager_Sliding Error:</b>'
  1080.                       .' "fileName" format not valid. Use "%d" as placeholder.';
  1081.                 return $this->raiseError($msg, ERROR_PAGER_SLIDING_INVALID);
  1082.             }
  1083.         }
  1084.  
  1085.         if (strlen($this->_linkClass)) {
  1086.             $this->_classString = 'class="'.$this->_linkClass.'"';
  1087.         } else {
  1088.             $this->_classString = '';
  1089.         }
  1090.  
  1091.         if (strlen($this->_curPageLinkClassName)) {
  1092.             $this->_curPageSpanPre  = '<span class="'.$this->_curPageLinkClassName.'">';
  1093.             $this->_curPageSpanPost = '</span>';
  1094.         }
  1095.  
  1096.         if ($this->_perPage < 1) {   //avoid easy-verified user error
  1097.             $this->_perPage = 1;
  1098.         }
  1099.  
  1100.         if ($this->_useSessions && !isset($_SESSION)) {
  1101.             session_start();
  1102.         }
  1103.         if (!empty($_REQUEST[$this->_sessionVar])) {
  1104.             $this->_perPage = max(1, (int)$_REQUEST[$this->_sessionVar]);
  1105.  
  1106.             if ($this->_useSessions) {
  1107.                 $_SESSION[$this->_sessionVar] = $this->_perPage;
  1108.             }
  1109.         }
  1110.  
  1111.         if (!empty($_SESSION[$this->_sessionVar])) {
  1112.              $this->_perPage = $_SESSION[$this->_sessionVar];
  1113.         }
  1114.  
  1115.         if ($this->_closeSession) {
  1116.             session_write_close();
  1117.         }
  1118.  
  1119.         for ($i=0; $i<$this->_spacesBeforeSeparator; $i++) {
  1120.             $this->_spacesBefore .= ' ';
  1121.         }
  1122.  
  1123.         for ($i=0; $i<$this->_spacesAfterSeparator; $i++) {
  1124.             $this->_spacesAfter .= ' ';
  1125.         }
  1126.  
  1127.         if (isset($_GET[$this->_urlVar])) {
  1128.             $this->_currentPage = max((int)@$_GET[$this->_urlVar], 1);
  1129.         } else {
  1130.             $this->_currentPage = 1;
  1131.         }
  1132.     }
  1133.  
  1134.     // }}}
  1135. }
  1136. ?>