source: trunk/lib/PageNumbers.inc.php @ 141

Last change on this file since 141 was 136, checked in by scdev, 18 years ago

Q - Merged branches/2.0singleton into trunk. Completed updating classes to use singleton methods. Implemented tests. Fixed some bugs. Changed some interfaces.

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