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
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
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/**
24 * PageNumbers.inc.php
25 *
26 * The PageNumbers class provides a common abstracted interface to the
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 */
36
37require_once dirname(__FILE__) . '/Prefs.inc.php';
38
39class PageNumbers {
40
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.
49
50    // Flags to ensure all necessary values have been set before calling calculate().
51    public $set_per_page_initialized = false;
52    public $set_page_number_initialized = false;
53    public $set_total_items_initialized = false;
54
55    // These are initialized in the constructor.
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;
65
66    /**
67     * PageNumbers constructor. All arguments are depreciated. Use set* functions instead.
68     */
69    public function __construct()
70    {
71        // Default options for the quantity per page links.
72        $this->per_page_options = array(25, 50, 100, 200);
73
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>';
83
84        // Default url base. This will be set manually after instantiation
85        // in special cases like using a /my/page/# scheme.
86        $this->url_base = $_SERVER['PHP_SELF'] . '?page_number=';
87       
88        $this->prefs = new Prefs($_SERVER['PHP_SELF']);
89        $this->prefs->setParam(array('persistent' => false));
90    }
91
92    /**
93     * Set the number of items per page.
94     */
95    public function setPerPage($per_page, $default=25, $save_value=true)
96    {
97        // (1) By provided argument, if valid.
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) {
104                $this->prefs->set('items_per_page', $this->_per_page);
105            }
106        } else if ($save_value && $this->prefs->exists('items_per_page')) {
107            $this->_per_page = (int)$this->prefs->get('items_per_page');
108        } else if (is_numeric($default) && $default > 0) {
109            $this->_per_page = $default;
110        }
111        $this->set_per_page_initialized = true;
112    }
113
114    /**
115     * Set the current page number.
116     */
117    public function setPageNumber($page_number, $save_value=true)
118    {
119        // (1) By provided argument, if valid.
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) {
130                $this->prefs->set('page_number', $this->current_page);
131            }
132        } else if ($save_value && $this->prefs->exists('page_number')) {
133            $this->current_page = (int)$this->prefs->get('page_number');
134        }
135        $this->set_page_number_initialized = true;
136    }
137
138    /**
139     * Set the total number of items.
140     */
141    public function setTotalItems($total_items)
142    {
143        if (is_numeric($total_items) && $total_items > 0) {
144            $this->total_items = $total_items;
145        } else {
146            $this->total_items = 0;
147        }
148        $this->set_total_items_initialized = true;
149    }
150
151    /**
152     * After $total_items or other options are set, this function calculates
153     * all the other numbers needed. If you set any variables manually,
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     */
160    public function calculate()
161    {
162        $app =& App::getInstance();
163
164        if (!$this->set_per_page_initialized) {
165            $app->logMsg(sprintf('set_per_page not initialized'), LOG_ERR, __FILE__, __LINE__);
166        }
167        if (!$this->set_page_number_initialized) {
168            $app->logMsg(sprintf('set_page_number not initialized'), LOG_ERR, __FILE__, __LINE__);
169        }
170        if (!$this->set_total_items_initialized) {
171            $app->logMsg(sprintf('set_total_items not initialized'), LOG_ERR, __FILE__, __LINE__);
172        }
173
174        // If the specified page exceeds total pages or is less than 1, set the page to 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        }
178
179        // The first item to be shown on this page.
180        $this->first_item = ($this->current_page - 1) * $this->_per_page;
181
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        }
188
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        }
199
200        // The total number of pages.
201        $this->total_pages = ceil($this->total_items / $this->_per_page);
202
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    }
210
211    /**
212     * Returns the SQL code to limit query to items that are on current page.
213     */
214    public function getLimitSQL()
215    {
216        $app =& App::getInstance();
217        $db =& DB::getInstance();
218
219        if (is_numeric($this->first_item) && is_numeric($this->_per_page)) {
220            return ' LIMIT ' . $db->escapeString($this->first_item) . ', ' . $db->escapeString($this->_per_page) . ' ';
221        } else {
222            $app->logMsg(sprintf('Could not find SQL to LIMIT by %s %s.', $this->first_item, $this->_per_page), LOG_WARNING, __FILE__, __LINE__);
223            return '';
224        }
225    }
226
227    /**
228     * Prints links to change the number of items shown per page.
229     *
230     * @access public
231     */
232    public function printPerPageLinks($query_key='per_page')
233    {
234        $app =& App::getInstance();
235
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,
241                    $app->oHREF($_SERVER['PHP_SELF'] . '?' . $query_key . '=' . $this->per_page_options[$i]),
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    /**
252     * Outputs an $app->oHREF compatible url that goes to the page $page_number.
253     * Depends on $this->base_url to build the url onto. This is used in the
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     */
262    public function getPageNumURL($page_number, $carry_args=null)
263    {
264        $app =& App::getInstance();
265
266        return $app->oHREF($this->url_base . $page_number, $carry_args);
267    }
268    public function printPageNumURL($page_number, $carry_args=null)
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     */
278    public function getPageNumbersArray($carry_args=null)
279    {
280        $page_numbers = array();
281
282        for ($i = 1; $i <= $this->total_pages; $i++) {
283            $page_numbers[] = array(
284                'number' => $i,
285                'url' => $this->getPageNumURL($i, $carry_args),
286                'current' => ($this->current_page == $i)
287            );
288        }
289
290        return $page_numbers;
291    }
292
293    /**
294     * Returns a string containing the page number links.
295     *
296     * @access public
297     */
298    public function getPageNumbers($carry_args=null)
299    {
300        $page_numbers_string = '';
301
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        }
312
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        }
333
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        }
338
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        }
359
360        return $page_numbers_string;
361    }
362
363    public function printPageNumbers($carry_args=null)
364    {
365        echo $this->getPageNumbers($carry_args);
366    }
367
368}
369
Note: See TracBrowser for help on using the repository browser.