Initial Kohana install
[speedfreak] / Server / system / libraries / Pagination.php
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3  * Pagination library.
4  *
5  * $Id: Pagination.php 3769 2008-12-15 00:48:56Z zombor $
6  *
7  * @package    Core
8  * @author     Kohana Team
9  * @copyright  (c) 2007-2008 Kohana Team
10  * @license    http://kohanaphp.com/license.html
11  */
12 class Pagination_Core {
13
14         // Config values
15         protected $base_url       = '';
16         protected $directory      = 'pagination';
17         protected $style          = 'classic';
18         protected $uri_segment    = 3;
19         protected $query_string   = '';
20         protected $items_per_page = 20;
21         protected $total_items    = 0;
22         protected $auto_hide      = FALSE;
23
24         // Autogenerated values
25         protected $url;
26         protected $current_page;
27         protected $total_pages;
28         protected $current_first_item;
29         protected $current_last_item;
30         protected $first_page;
31         protected $last_page;
32         protected $previous_page;
33         protected $next_page;
34         protected $sql_offset;
35         protected $sql_limit;
36
37         /**
38          * Constructs and returns a new Pagination object.
39          *
40          * @param   array   configuration settings
41          * @return  object
42          */
43         public function factory($config = array())
44         {
45                 return new Pagination($config);
46         }
47
48         /**
49          * Constructs a new Pagination object.
50          *
51          * @param   array  configuration settings
52          * @return  void
53          */
54         public function __construct($config = array())
55         {
56                 // No custom group name given
57                 if ( ! isset($config['group']))
58                 {
59                         $config['group'] = 'default';
60                 }
61
62                 // Pagination setup
63                 $this->initialize($config);
64
65                 Kohana::log('debug', 'Pagination Library initialized');
66         }
67
68         /**
69          * Sets config values.
70          *
71          * @throws  Kohana_Exception
72          * @param   array  configuration settings
73          * @return  void
74          */
75         public function initialize($config = array())
76         {
77                 // Load config group
78                 if (isset($config['group']))
79                 {
80                         // Load and validate config group
81                         if ( ! is_array($group_config = Kohana::config('pagination.'.$config['group'])))
82                                 throw new Kohana_Exception('pagination.undefined_group', $config['group']);
83
84                         // All pagination config groups inherit default config group
85                         if ($config['group'] !== 'default')
86                         {
87                                 // Load and validate default config group
88                                 if ( ! is_array($default_config = Kohana::config('pagination.default')))
89                                         throw new Kohana_Exception('pagination.undefined_group', 'default');
90
91                                 // Merge config group with default config group
92                                 $group_config += $default_config;
93                         }
94
95                         // Merge custom config items with config group
96                         $config += $group_config;
97                 }
98
99                 // Assign config values to the object
100                 foreach ($config as $key => $value)
101                 {
102                         if (property_exists($this, $key))
103                         {
104                                 $this->$key = $value;
105                         }
106                 }
107
108                 // Clean view directory
109                 $this->directory = trim($this->directory, '/').'/';
110
111                 // Build generic URL with page in query string
112                 if ($this->query_string !== '')
113                 {
114                         // Extract current page
115                         $this->current_page = isset($_GET[$this->query_string]) ? (int) $_GET[$this->query_string] : 1;
116
117                         // Insert {page} placeholder
118                         $_GET[$this->query_string] = '{page}';
119
120                         // Create full URL
121                         $base_url = ($this->base_url === '') ? Router::$current_uri : $this->base_url;
122                         $this->url = url::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET));
123
124                         // Reset page number
125                         $_GET[$this->query_string] = $this->current_page;
126                 }
127
128                 // Build generic URL with page as URI segment
129                 else
130                 {
131                         // Use current URI if no base_url set
132                         $this->url = ($this->base_url === '') ? Router::$segments : explode('/', trim($this->base_url, '/'));
133
134                         // Convert uri 'label' to corresponding integer if needed
135                         if (is_string($this->uri_segment))
136                         {
137                                 if (($key = array_search($this->uri_segment, $this->url)) === FALSE)
138                                 {
139                                         // If uri 'label' is not found, auto add it to base_url
140                                         $this->url[] = $this->uri_segment;
141                                         $this->uri_segment = count($this->url) + 1;
142                                 }
143                                 else
144                                 {
145                                         $this->uri_segment = $key + 2;
146                                 }
147                         }
148
149                         // Insert {page} placeholder
150                         $this->url[$this->uri_segment - 1] = '{page}';
151
152                         // Create full URL
153                         $this->url = url::site(implode('/', $this->url)).Router::$query_string;
154
155                         // Extract current page
156                         $this->current_page = URI::instance()->segment($this->uri_segment);
157                 }
158
159                 // Core pagination values
160                 $this->total_items        = (int) max(0, $this->total_items);
161                 $this->items_per_page     = (int) max(1, $this->items_per_page);
162                 $this->total_pages        = (int) ceil($this->total_items / $this->items_per_page);
163                 $this->current_page       = (int) min(max(1, $this->current_page), max(1, $this->total_pages));
164                 $this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items);
165                 $this->current_last_item  = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items);
166
167                 // If there is no first/last/previous/next page, relative to the
168                 // current page, value is set to FALSE. Valid page number otherwise.
169                 $this->first_page         = ($this->current_page === 1) ? FALSE : 1;
170                 $this->last_page          = ($this->current_page >= $this->total_pages) ? FALSE : $this->total_pages;
171                 $this->previous_page      = ($this->current_page > 1) ? $this->current_page - 1 : FALSE;
172                 $this->next_page          = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : FALSE;
173
174                 // SQL values
175                 $this->sql_offset         = (int) ($this->current_page - 1) * $this->items_per_page;
176                 $this->sql_limit          = sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page, $this->sql_offset);
177         }
178
179         /**
180          * Generates the HTML for the chosen pagination style.
181          *
182          * @param   string  pagination style
183          * @return  string  pagination html
184          */
185         public function render($style = NULL)
186         {
187                 // Hide single page pagination
188                 if ($this->auto_hide === TRUE AND $this->total_pages <= 1)
189                         return '';
190
191                 if ($style === NULL)
192                 {
193                         // Use default style
194                         $style = $this->style;
195                 }
196
197                 // Return rendered pagination view
198                 return View::factory($this->directory.$style, get_object_vars($this))->render();
199         }
200
201         /**
202          * Magically converts Pagination object to string.
203          *
204          * @return  string  pagination html
205          */
206         public function __toString()
207         {
208                 return $this->render();
209         }
210
211         /**
212          * Magically gets a pagination variable.
213          *
214          * @param   string  variable key
215          * @return  mixed   variable value if the key is found
216          * @return  void    if the key is not found
217          */
218         public function __get($key)
219         {
220                 if (isset($this->$key))
221                         return $this->$key;
222         }
223
224         /**
225          * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages().
226          * Note that $pagination->total_pages is the recommended way to access properties.
227          *
228          * @param   string  function name
229          * @return  string
230          */
231         public function __call($func, $args = NULL)
232         {
233                 return $this->__get($func);
234         }
235
236 } // End Pagination Class