source: tags/1.0.0/lib/PageNumbers.inc.php @ 1

Last change on this file since 1 was 1, checked in by scdev, 19 years ago

Initial import.

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