This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 | |||
15 | // Config values |
||
16 | protected $base_url = ''; |
||
17 | protected $directory = 'pagination'; |
||
18 | protected $style = 'classic'; |
||
19 | protected $uri_segment = 3; |
||
20 | protected $query_string = ''; |
||
21 | protected $items_per_page = 20; |
||
22 | protected $total_items = 0; |
||
23 | protected $auto_hide = false; |
||
24 | |||
25 | // Autogenerated values |
||
26 | protected $url; |
||
27 | protected $current_page; |
||
28 | protected $total_pages; |
||
29 | protected $current_first_item; |
||
30 | protected $current_last_item; |
||
31 | protected $first_page; |
||
32 | protected $last_page; |
||
33 | protected $previous_page; |
||
34 | protected $next_page; |
||
35 | protected $sql_offset; |
||
36 | protected $sql_limit; |
||
37 | |||
38 | /** |
||
39 | * Constructs and returns a new Pagination object. |
||
40 | * |
||
41 | * @param array configuration settings |
||
42 | * @return object |
||
0 ignored issues
–
show
|
|||
43 | */ |
||
44 | public function factory($config = array()) |
||
45 | { |
||
46 | return new Pagination($config); |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * Constructs a new Pagination object. |
||
51 | * |
||
52 | * @param array configuration settings |
||
53 | * @return void |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Adding a
@return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.
Adding a Please refer to the PHP core documentation on constructors. ![]() |
|||
54 | */ |
||
55 | public function __construct($config = array()) |
||
56 | { |
||
57 | // No custom group name given |
||
58 | if (! isset($config['group'])) { |
||
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()) |
||
0 ignored issues
–
show
initialize uses the super-global variable $_GET which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
76 | { |
||
77 | // Load config group |
||
78 | if (isset($config['group'])) { |
||
79 | // Load and validate config group |
||
80 | View Code Duplication | if (! is_array($group_config = Kohana::config('pagination.'.$config['group']))) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
81 | throw new Kohana_Exception('pagination.undefined_group', $config['group']); |
||
82 | } |
||
83 | |||
84 | // All pagination config groups inherit default config group |
||
85 | View Code Duplication | if ($config['group'] !== 'default') { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
86 | // Load and validate default config group |
||
87 | if (! is_array($default_config = Kohana::config('pagination.default'))) { |
||
88 | throw new Kohana_Exception('pagination.undefined_group', 'default'); |
||
89 | } |
||
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 | if (property_exists($this, $key)) { |
||
102 | $this->$key = $value; |
||
103 | } |
||
104 | } |
||
105 | |||
106 | // Clean view directory |
||
107 | $this->directory = trim($this->directory, '/').'/'; |
||
108 | |||
109 | // Build generic URL with page in query string |
||
110 | if ($this->query_string !== '') { |
||
111 | // Extract current page |
||
112 | $this->current_page = isset($_GET[$this->query_string]) ? (int) $_GET[$this->query_string] : 1; |
||
113 | |||
114 | // Insert {page} placeholder |
||
115 | $_GET[$this->query_string] = '{page}'; |
||
116 | |||
117 | // Create full URL |
||
118 | $base_url = ($this->base_url === '') ? Router::$current_uri : $this->base_url; |
||
119 | $this->url = url::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET)); |
||
120 | |||
121 | // Reset page number |
||
122 | $_GET[$this->query_string] = $this->current_page; |
||
123 | } |
||
124 | |||
125 | // Build generic URL with page as URI segment |
||
126 | else { |
||
127 | // Use current URI if no base_url set |
||
128 | $this->url = ($this->base_url === '') ? Router::$segments : explode('/', trim($this->base_url, '/')); |
||
129 | |||
130 | // Convert uri 'label' to corresponding integer if needed |
||
131 | if (is_string($this->uri_segment)) { |
||
132 | if (($key = array_search($this->uri_segment, $this->url)) === false) { |
||
133 | // If uri 'label' is not found, auto add it to base_url |
||
134 | $this->url[] = $this->uri_segment; |
||
135 | $this->uri_segment = count($this->url) + 1; |
||
136 | } else { |
||
137 | $this->uri_segment = $key + 2; |
||
138 | } |
||
139 | } |
||
140 | |||
141 | // Insert {page} placeholder |
||
142 | $this->url[$this->uri_segment - 1] = '{page}'; |
||
143 | |||
144 | // Create full URL |
||
145 | $this->url = url::site(implode('/', $this->url)).Router::$query_string; |
||
146 | |||
147 | // Extract current page |
||
148 | $this->current_page = URI::instance()->segment($this->uri_segment); |
||
149 | } |
||
150 | |||
151 | // Core pagination values |
||
152 | $this->total_items = (int) max(0, $this->total_items); |
||
153 | $this->items_per_page = (int) max(1, $this->items_per_page); |
||
154 | $this->total_pages = (int) ceil($this->total_items / $this->items_per_page); |
||
155 | $this->current_page = (int) min(max(1, $this->current_page), max(1, $this->total_pages)); |
||
156 | $this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items); |
||
157 | $this->current_last_item = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items); |
||
158 | |||
159 | // If there is no first/last/previous/next page, relative to the |
||
160 | // current page, value is set to FALSE. Valid page number otherwise. |
||
161 | $this->first_page = ($this->current_page === 1) ? false : 1; |
||
162 | $this->last_page = ($this->current_page >= $this->total_pages) ? false : $this->total_pages; |
||
163 | $this->previous_page = ($this->current_page > 1) ? $this->current_page - 1 : false; |
||
164 | $this->next_page = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : false; |
||
165 | |||
166 | // SQL values |
||
167 | $this->sql_offset = (int) ($this->current_page - 1) * $this->items_per_page; |
||
168 | $this->sql_limit = sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page, $this->sql_offset); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Generates the HTML for the chosen pagination style. |
||
173 | * |
||
174 | * @param string pagination style |
||
175 | * @return string pagination html |
||
176 | */ |
||
177 | public function render($style = null) |
||
178 | { |
||
179 | // Hide single page pagination |
||
180 | if ($this->auto_hide === true and $this->total_pages <= 1) { |
||
181 | return ''; |
||
182 | } |
||
183 | |||
184 | if ($style === null) { |
||
185 | // Use default style |
||
186 | $style = $this->style; |
||
187 | } |
||
188 | |||
189 | // Return rendered pagination view |
||
190 | return View::factory($this->directory.$style, get_object_vars($this))->render(); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Magically converts Pagination object to string. |
||
195 | * |
||
196 | * @return string pagination html |
||
197 | */ |
||
198 | public function __toString() |
||
199 | { |
||
200 | return $this->render(); |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Magically gets a pagination variable. |
||
205 | * |
||
206 | * @param string variable key |
||
207 | * @return mixed variable value if the key is found |
||
208 | * @return void if the key is not found |
||
209 | */ |
||
210 | public function __get($key) |
||
211 | { |
||
212 | if (isset($this->$key)) { |
||
213 | return $this->$key; |
||
214 | } |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages(). |
||
219 | * Note that $pagination->total_pages is the recommended way to access properties. |
||
220 | * |
||
221 | * @param string function name |
||
222 | * @return string |
||
223 | */ |
||
224 | public function __call($func, $args = null) |
||
225 | { |
||
226 | return $this->__get($func); |
||
227 | } |
||
228 | } // End Pagination Class |
||
229 |
This check looks for the generic type
array
as a return type and suggests a more specific type. This type is inferred from the actual code.