1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
5 * $Id: Pagination.php 3917 2009-01-21 03:06:22Z zombor $
9 * @copyright (c) 2007-2008 Kohana Team
10 * @license http://kohanaphp.com/license.html
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;
24 // Pre-render specific variables
25 public $hide_next = false;
27 // Autogenerated values
29 protected $current_page;
30 protected $total_pages;
31 protected $current_first_item;
32 protected $current_last_item;
33 protected $first_page;
35 protected $previous_page;
36 protected $sql_offset;
41 * Constructs and returns a new Pagination object.
43 * @param array configuration settings
46 public function factory($config = array())
48 return new Pagination($config);
52 * Constructs a new Pagination object.
54 * @param array configuration settings
57 public function __construct($config = array())
59 // No custom group name given
60 if ( ! isset($config['group']))
62 $config['group'] = 'default';
66 $this->initialize($config);
68 Kohana
::log('debug', 'Pagination Library initialized');
74 * @throws Kohana_Exception
75 * @param array configuration settings
78 public function initialize($config = array())
81 if (isset($config['group']))
83 // Load and validate config group
84 if ( ! is_array($group_config = Kohana
::config('pagination.'.$config['group'])))
85 throw new Kohana_Exception('pagination.undefined_group', $config['group']);
87 // All pagination config groups inherit default config group
88 if ($config['group'] !== 'default')
90 // Load and validate default config group
91 if ( ! is_array($default_config = Kohana
::config('pagination.default')))
92 throw new Kohana_Exception('pagination.undefined_group', 'default');
94 // Merge config group with default config group
95 $group_config +
= $default_config;
98 // Merge custom config items with config group
99 $config +
= $group_config;
102 // Assign config values to the object
103 foreach ($config as $key => $value)
105 if (property_exists($this, $key))
107 $this->$key = $value;
111 // Clean view directory
112 $this->directory
= trim($this->directory
, '/').'/';
114 // Build generic URL with page in query string
115 if ($this->query_string
!== '')
117 // Extract current page
118 $this->current_page
= isset($_GET[$this->query_string
]) ?
(int) $_GET[$this->query_string
] : 1;
120 // Insert {page} placeholder
121 $_GET[$this->query_string
] = '{page}';
124 $base_url = ($this->base_url
=== '') ? Router
::$current_uri : $this->base_url
;
125 $this->url
= url
::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET));
128 $_GET[$this->query_string
] = $this->current_page
;
131 // Build generic URL with page as URI segment
134 // Use current URI if no base_url set
135 $this->url
= ($this->base_url
=== '') ? Router
::$segments : explode('/', trim($this->base_url
, '/'));
137 // Convert uri 'label' to corresponding integer if needed
138 if (is_string($this->uri_segment
))
140 if (($key = array_search($this->uri_segment
, $this->url
)) === FALSE)
142 // If uri 'label' is not found, auto add it to base_url
143 $this->url
[] = $this->uri_segment
;
144 $this->uri_segment
= count($this->url
) +
1;
148 $this->uri_segment
= $key +
2;
152 // Insert {page} placeholder
153 $this->url
[$this->uri_segment
- 1] = '{page}';
156 $this->url
= url
::site(implode('/', $this->url
)).Router
::$query_string;
158 // Extract current page
159 $this->current_page
= URI
::instance()->segment($this->uri_segment
);
162 // Core pagination values
163 $this->total_items
= (int) max(0, $this->total_items
);
164 $this->items_per_page
= (int) max(1, $this->items_per_page
);
165 $this->total_pages
= (int) ceil($this->total_items
/ $this->items_per_page
);
166 $this->current_page
= (int) min(max(1, $this->current_page
), max(1, $this->total_pages
));
167 $this->current_first_item
= (int) min((($this->current_page
- 1) * $this->items_per_page
) +
1, $this->total_items
);
168 $this->current_last_item
= (int) min($this->current_first_item +
$this->items_per_page
- 1, $this->total_items
);
170 // If there is no first/last/previous/next page, relative to the
171 // current page, value is set to FALSE. Valid page number otherwise.
172 $this->first_page
= ($this->current_page
=== 1) ?
FALSE : 1;
173 $this->last_page
= ($this->current_page
>= $this->total_pages
) ?
FALSE : $this->total_pages
;
174 $this->previous_page
= ($this->current_page
> 1) ?
$this->current_page
- 1 : FALSE;
175 $this->next_page
= ($this->current_page
< $this->total_pages
) ?
$this->current_page +
1 : FALSE;
178 $this->sql_offset
= (int) ($this->current_page
- 1) * $this->items_per_page
;
179 $this->sql_limit
= sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page
, $this->sql_offset
);
183 * Generates the HTML for the chosen pagination style.
185 * @param string pagination style
186 * @return string pagination html
188 public function render($style = NULL)
190 // Hide single page pagination
191 if ($this->auto_hide
=== TRUE AND $this->total_pages
<= 1)
195 $this->next_page
= false;
200 $style = $this->style
;
203 // Return rendered pagination view
204 return View
::factory($this->directory
.$style, get_object_vars($this))->render();
208 * Magically converts Pagination object to string.
210 * @return string pagination html
212 public function __toString()
214 return $this->render();
218 * Magically gets a pagination variable.
220 * @param string variable key
221 * @return mixed variable value if the key is found
222 * @return void if the key is not found
224 public function __get($key)
226 if (isset($this->$key))
231 * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages().
232 * Note that $pagination->total_pages is the recommended way to access properties.
234 * @param string function name
237 public function __call($func, $args = NULL)
239 return $this->__get($func);
242 } // End Pagination Class