source: branches/eli_branch/lib/PageNumbers.inc.php @ 439

Last change on this file since 439 was 439, checked in by anonymous, 11 years ago

added public and private keywords to all properties and methods, changed old classname constructor function to construct, removed more ?> closing tags

File size: 14.0 KB
RevLine 
[1]1<?php
2/**
[362]3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
[396]5 * Copyright 2001-2012 Strangecode, LLC
[362]6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
[1]24 * PageNumbers.inc.php
25 *
[136]26 * The PageNumbers class provides a common abstracted interface to the
[1]27 * multiple pages features. It sets the various numbers needed to display items
28 * on a page, and includes functions for working with these numbers.
29 * You must call set setTotalItems(), setPerPage() and setPageNumber() before calling calculate()
30 * this the other various values will be set automatically. Then you can call printPerPageLinks,
31 * printPageNumbers, etc, and use the various page object properties in your page templates.
32 *
33 * @author    Quinn Comendant <quinn@strangecode.com>
34 * @version   1.61
35 */
[42]36
[1]37require_once dirname(__FILE__) . '/Prefs.inc.php';
38
39class PageNumbers {
[42]40
[439]41    public $total_items;       // Total quantity of items.
42    public $total_pages;       // The total number of pages.
43    public $current_page = 1;  // Current page number.
44    public $first_item;        // The counter for the first item on this page (zero index).
45    public $last_item;         // The counter for the last item on this page (zero index).
46    public $max_num_links = 9; // The max number of links to show on page (odd numbers look best).
47    private $_num_links;        // The number of links to show on page.
48    private $_per_page = 25;    // Items per page.
[1]49
50    // Flags to ensure all necessary values have been set before calling calculate().
[439]51    public $set_per_page_initialized = false;
52    public $set_page_number_initialized = false;
53    public $set_total_items_initialized = false;
[42]54
[1]55    // These are initialized in the constructor.
[439]56    public $per_page_options;
57    public $left_arrow;
58    public $left_arrow_disabled;
59    public $left_dbl_arrow;
60    public $left_dbl_arrow_disabled;
61    public $right_arrow;
62    public $right_arrow_disabled;
63    public $right_dbl_arrow;
64    public $right_dbl_arrow_disabled;
[42]65
[1]66    /**
67     * PageNumbers constructor. All arguments are depreciated. Use set* functions instead.
68     */
[439]69    public function __construct()
[1]70    {
71        // Default options for the quantity per page links.
72        $this->per_page_options = array(25, 50, 100, 200);
[42]73
[1]74        // Default options for the page number links.
75        $this->left_arrow = _("back");
76        $this->left_arrow_disabled = '<span style="color: #aaaaaa;">' . _("back") . '</span>';
77        $this->left_dbl_arrow = '<strong>&laquo;</strong>';
78        $this->left_dbl_arrow_disabled = '<span style="color: #aaaaaa;"><strong>&laquo;</strong></span>';
79        $this->right_arrow = _("next");
80        $this->right_arrow_disabled = '<span style="color: #aaaaaa;">' . _("next") . '</span>';
81        $this->right_dbl_arrow = '<strong>&raquo;</strong>';
82        $this->right_dbl_arrow_disabled = '<span style="color: #aaaaaa;"><strong>&raquo;</strong></span>';
[42]83
84        // Default url base. This will be set manually after instantiation
[1]85        // in special cases like using a /my/page/# scheme.
86        $this->url_base = $_SERVER['PHP_SELF'] . '?page_number=';
[153]87       
[154]88        $this->prefs = new Prefs($_SERVER['PHP_SELF']);
[153]89        $this->prefs->setParam(array('persistent' => false));
[1]90    }
[42]91
[1]92    /**
93     * Set the number of items per page.
94     */
[439]95    public function setPerPage($per_page, $default=25, $save_value=true)
[1]96    {
[136]97        // (1) By provided argument, if valid.
[1]98        // (2) By saved preference, if available.
99        // (3) Set to default value if provided and valid.
100        // (4) Keep as Class default of 25.
101        if (is_numeric($per_page) && $per_page > 0) {
102            $this->_per_page = $per_page;
103            if ($save_value) {
[153]104                $this->prefs->set('items_per_page', $this->_per_page);
[1]105            }
[153]106        } else if ($save_value && $this->prefs->exists('items_per_page')) {
107            $this->_per_page = (int)$this->prefs->get('items_per_page');
[1]108        } else if (is_numeric($default) && $default > 0) {
109            $this->_per_page = $default;
110        }
111        $this->set_per_page_initialized = true;
112    }
[42]113
[1]114    /**
115     * Set the current page number.
116     */
[439]117    public function setPageNumber($page_number, $save_value=true)
[1]118    {
[152]119        // (1) By provided argument, if valid.
[1]120        // (2) By saved preference, if available.
121        // (3) Don't change from what was provided at class instantiation.
122        if (is_numeric($page_number)) {
123            if ($page_number < 1) {
124                // FIXME: How to go back around to the last page? Hmmm. Set to 1 for now.
125                $this->current_page = 1;
126            } else {
127                $this->current_page = $page_number;
128            }
129            if ($save_value) {
[153]130                $this->prefs->set('page_number', $this->current_page);
[1]131            }
[153]132        } else if ($save_value && $this->prefs->exists('page_number')) {
133            $this->current_page = (int)$this->prefs->get('page_number');
[1]134        }
135        $this->set_page_number_initialized = true;
136    }
[42]137
[1]138    /**
139     * Set the total number of items.
140     */
[439]141    public function setTotalItems($total_items)
[1]142    {
143        if (is_numeric($total_items) && $total_items > 0) {
[42]144            $this->total_items = $total_items;
[1]145        } else {
[42]146            $this->total_items = 0;
[1]147        }
148        $this->set_total_items_initialized = true;
149    }
[42]150
[1]151    /**
152     * After $total_items or other options are set, this function calculates
[42]153     * all the other numbers needed. If you set any variables manually,
[1]154     * for example if $page_number comes from
155     * some place other than the GET or POST array, you should call this
156     * function manually, otherwise it happens at object instantiation.
157     *
158     * @access public
159     */
[439]160    public function calculate()
[1]161    {
[136]162        $app =& App::getInstance();
163
[1]164        if (!$this->set_per_page_initialized) {
[136]165            $app->logMsg(sprintf('set_per_page not initialized'), LOG_ERR, __FILE__, __LINE__);
[1]166        }
167        if (!$this->set_page_number_initialized) {
[136]168            $app->logMsg(sprintf('set_page_number not initialized'), LOG_ERR, __FILE__, __LINE__);
[1]169        }
170        if (!$this->set_total_items_initialized) {
[136]171            $app->logMsg(sprintf('set_total_items not initialized'), LOG_ERR, __FILE__, __LINE__);
[1]172        }
[42]173
[334]174        // If the specified page exceeds total pages or is less than 1, set the page to 1.
[1]175        if ($this->_per_page * $this->current_page >= $this->total_items + $this->_per_page || $this->_per_page * $this->current_page < 1) {
176            $this->current_page = 1;
177        }
[42]178
[1]179        // The first item to be shown on this page.
180        $this->first_item = ($this->current_page - 1) * $this->_per_page;
[42]181
[1]182        // The last item to be shown on this page.
183        if ($this->total_items < $this->current_page * $this->_per_page) {
184            $this->last_item = $this->total_items - 1;
185        } else {
186            $this->last_item = $this->current_page * $this->_per_page - 1;
187        }
[42]188
[1]189        // Zeroing. Just in case. Paranoia. Yeah, negative numbers perturb me.
190        if ($this->first_item < 1) {
191            $this->first_item = 0;
192        }
193        if ($this->last_item < 1) {
194            $this->last_item = 0;
195        }
196        if ($this->total_items < 1) {
197            $this->total_items = 0;
198        }
[42]199
[1]200        // The total number of pages.
201        $this->total_pages = ceil($this->total_items / $this->_per_page);
[42]202
[1]203        // Figure out how many page number links to print.
204        if ($this->total_pages >= $this->max_num_links) {
205            $this->_num_links = $this->max_num_links;
206        } else {
207            $this->_num_links = $this->total_pages;
208        }
209    }
[42]210
[1]211    /**
212     * Returns the SQL code to limit query to items that are on current page.
213     */
[439]214    public function getLimitSQL()
[1]215    {
[136]216        $app =& App::getInstance();
217        $db =& DB::getInstance();
218
[1]219        if (is_numeric($this->first_item) && is_numeric($this->_per_page)) {
[136]220            return ' LIMIT ' . $db->escapeString($this->first_item) . ', ' . $db->escapeString($this->_per_page) . ' ';
[1]221        } else {
[136]222            $app->logMsg(sprintf('Could not find SQL to LIMIT by %s %s.', $this->first_item, $this->_per_page), LOG_WARNING, __FILE__, __LINE__);
[1]223            return '';
224        }
[42]225    }
[1]226
227    /**
228     * Prints links to change the number of items shown per page.
229     *
230     * @access public
231     */
[439]232    public function printPerPageLinks($query_key='per_page')
[1]233    {
[136]234        $app =& App::getInstance();
235
[1]236        $sp = '';
237        for ($i=0; $i<sizeof($this->per_page_options); $i++) {
238            if ($this->_per_page != $this->per_page_options[$i]) {
239                printf('%s<a href="%s">%s</a>',
240                    $sp,
[136]241                    $app->oHREF($_SERVER['PHP_SELF'] . '?' . $query_key . '=' . $this->per_page_options[$i]),
[1]242                    $this->per_page_options[$i]
243                );
244            } else {
245                echo $sp . '<strong>' . $this->per_page_options[$i] . '</strong>';
246            }
247            $sp = '&nbsp;';
248        }
249    }
250
251    /**
[136]252     * Outputs an $app->oHREF compatible url that goes to the page $page_number.
[42]253     * Depends on $this->base_url to build the url onto. This is used in the
[1]254     * page_number.ihtml template.
255     *
256     * @param  int   $page_number    The page number this page will go to.
257     *
258     * @return string                The URL.
259     *
260     * @access public
261     */
[439]262    public function getPageNumURL($page_number, $carry_args=null)
[1]263    {
[136]264        $app =& App::getInstance();
265
266        return $app->oHREF($this->url_base . $page_number, $carry_args);
[1]267    }
[439]268    public function printPageNumURL($page_number, $carry_args=null)
[1]269    {
270        echo $this->getPageNumURL($page_number, $carry_args);
271    }
272
273    /**
274     * Returns an array of page number links.
275     *
276     * @access public
277     */
[439]278    public function getPageNumbersArray($carry_args=null)
[1]279    {
280        $page_numbers = array();
[42]281
[53]282        for ($i = 1; $i <= $this->total_pages; $i++) {
[1]283            $page_numbers[] = array(
284                'number' => $i,
285                'url' => $this->getPageNumURL($i, $carry_args),
286                'current' => ($this->current_page == $i)
287            );
288        }
[42]289
[1]290        return $page_numbers;
291    }
292
293    /**
294     * Returns a string containing the page number links.
295     *
296     * @access public
297     */
[439]298    public function getPageNumbers($carry_args=null)
[1]299    {
300        $page_numbers_string = '';
[42]301
[1]302        if ($this->current_page > $this->total_pages - floor($this->_num_links / 2)) {
303            $high_num = $this->total_pages;
304            $low_num = $high_num - $this->_num_links + 1;
305        } else {
306            $low_num = $this->current_page - floor($this->_num_links / 2);
307            if ($low_num < 1) {
308                $low_num = 1;
309            }
310            $high_num = $low_num + $this->_num_links - 1;
311        }
[42]312
[1]313        if ($this->current_page != 1) {
314            // Print "first" and "previous" page links.
315            if ($this->left_dbl_arrow) {
316                $page_numbers_string .= sprintf('<a href="%s" title="%s">%s</a>&nbsp;', $this->getPageNumURL(1, $carry_args), _("Go to the first page"), $this->left_dbl_arrow);
317            }
318            if ($this->left_arrow) {
319                $page_numbers_string .= sprintf('<a href="%s" title="%s">%s</a>&nbsp;&nbsp;', $this->getPageNumURL($this->current_page - 1, $carry_args), _("Go back one page"), $this->left_arrow);
320            }
321            // Print links to specific page numbers before the current page.
322            for ($i = $low_num; $i < $this->current_page; $i++) {
323                $page_numbers_string .= sprintf('<a href="%s">%s</a>&nbsp;', $this->getPageNumURL($i, $carry_args), $i);
324            }
325        } else {
326            if ($this->left_dbl_arrow) {
327                $page_numbers_string .= $this->left_dbl_arrow_disabled . '&nbsp;';
328            }
329            if ($this->left_arrow) {
330                $page_numbers_string .= $this->left_arrow_disabled . '&nbsp;';
331            }
332        }
[42]333
[1]334        if ($this->_num_links > 0) {
335            // Print the current page number.
336            $page_numbers_string .= sprintf('<strong>%s</strong>&nbsp;', $this->current_page);
337        }
[42]338
[1]339        if ($this->current_page < $this->total_pages) {
340            // Print links to specific page numbers after the current page.
341            for ($i = $this->current_page + 1; $i <= $high_num; $i++) {
342                $page_numbers_string .= sprintf('<a href="%s">%s</a>&nbsp;', $this->getPageNumURL($i, $carry_args), $i);
343            }
344            // Print "last" and "next" page links.
345            if ($this->right_arrow) {
346                $page_numbers_string .= sprintf('<a href="%s" title="%s">%s</a>&nbsp;&nbsp;', $this->getPageNumURL($this->current_page + 1, $carry_args), _("Go forward one page"), $this->right_arrow);
347            }
348            if ($this->right_dbl_arrow) {
349                $page_numbers_string .= sprintf('<a href="%s" title="%s">%s</a>&nbsp;&nbsp;', $this->getPageNumURL($this->total_pages, $carry_args), _("Go to the last page"), $this->right_dbl_arrow);
350            }
351        } else {
352            if ($this->right_arrow_disabled) {
353                $page_numbers_string .= $this->right_arrow_disabled . '&nbsp;';
354            }
355            if ($this->right_dbl_arrow_disabled) {
356                $page_numbers_string .= $this->right_dbl_arrow_disabled;
357            }
358        }
[42]359
[1]360        return $page_numbers_string;
361    }
[42]362
[439]363    public function printPageNumbers($carry_args=null)
[1]364    {
365        echo $this->getPageNumbers($carry_args);
366    }
[42]367
[1]368}
369
Note: See TracBrowser for help on using the repository browser.