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 namespace Myth\Api\Server; |
||
2 | /** |
||
3 | * Sprint |
||
4 | * |
||
5 | * A set of power tools to enhance the CodeIgniter framework and provide consistent workflow. |
||
6 | * |
||
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
||
8 | * of this software and associated documentation files (the "Software"), to deal |
||
9 | * in the Software without restriction, including without limitation the rights |
||
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||
11 | * copies of the Software, and to permit persons to whom the Software is |
||
12 | * furnished to do so, subject to the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included in |
||
15 | * all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||
23 | * THE SOFTWARE. |
||
24 | * |
||
25 | * @package Sprint |
||
26 | * @author Lonnie Ezell |
||
27 | * @copyright Copyright 2014-2015, New Myth Media, LLC (http://newmythmedia.com) |
||
28 | * @license http://opensource.org/licenses/MIT (MIT) |
||
29 | * @link http://sprintphp.com |
||
30 | * @since Version 1.0 |
||
31 | */ |
||
32 | |||
33 | use Myth\Auth\AuthTrait; |
||
34 | use Myth\Controllers\BaseController; |
||
35 | |||
36 | /** |
||
37 | * Class ApiController |
||
38 | * |
||
39 | * Provides a basic set of functionality to all API Controllers. Includes |
||
40 | * helper methods for responding and failing. |
||
41 | * |
||
42 | * @package Myth\Api\Server |
||
43 | */ |
||
44 | class ApiController extends BaseController { |
||
45 | |||
46 | use AuthTrait; |
||
47 | |||
48 | protected $language_file = 'api'; |
||
49 | |||
50 | protected $ajax_notices = false; |
||
51 | |||
52 | /** |
||
53 | * Holds all request parameters. |
||
54 | * @var array |
||
55 | */ |
||
56 | protected $vars = []; |
||
57 | |||
58 | |||
59 | protected $request; |
||
60 | |||
61 | protected $allowed_http_methods = [ |
||
62 | 'get', |
||
63 | 'put', |
||
64 | 'post', |
||
65 | 'delete', |
||
66 | 'options', |
||
67 | 'patch', |
||
68 | 'head' |
||
69 | ]; |
||
70 | |||
71 | /** |
||
72 | * Turns off authorization checks. |
||
73 | * Only intended for temp use in |
||
74 | * development environments. |
||
75 | * @var bool |
||
76 | */ |
||
77 | protected $do_auth_check = true; |
||
78 | |||
79 | /** |
||
80 | * The current page of results being requested. |
||
81 | * @var int |
||
82 | */ |
||
83 | protected $page = 0; |
||
84 | |||
85 | /** |
||
86 | * The number of results to return per page |
||
87 | * of results, by default. |
||
88 | * @var int |
||
89 | */ |
||
90 | protected $per_page = 20; |
||
91 | |||
92 | /** |
||
93 | * Based on the current page, |
||
94 | * used for LIMITing data requests |
||
95 | * from database. |
||
96 | * |
||
97 | * @var int |
||
98 | */ |
||
99 | protected $offset = 0; |
||
100 | |||
101 | /** |
||
102 | * Stores any select values passed to any methods |
||
103 | * via the $_GET var ?fields=x,y,z. |
||
104 | * |
||
105 | * @var null |
||
106 | */ |
||
107 | protected $selects = null; |
||
108 | |||
109 | /** |
||
110 | * The time in microseconds that the request started. |
||
111 | * |
||
112 | * @var null |
||
113 | */ |
||
114 | protected $start_time = null; |
||
115 | |||
116 | /** |
||
117 | * Specifies whether this request should be logged. |
||
118 | * |
||
119 | * @var bool |
||
120 | */ |
||
121 | protected $enable_logging; |
||
122 | |||
123 | /** |
||
124 | * Whether rate limiting is enabled. |
||
125 | * |
||
126 | * @var bool |
||
127 | */ |
||
128 | protected $enable_rate_limits; |
||
129 | |||
130 | /** |
||
131 | * The number of requests allowed per user/hour |
||
132 | * |
||
133 | * @var int |
||
134 | */ |
||
135 | protected $rate_limits = 0; |
||
136 | |||
137 | /** |
||
138 | * Status strings/codes allowed when using |
||
139 | * the generic 'fail' method. |
||
140 | * |
||
141 | * @var array |
||
142 | */ |
||
143 | protected $codes = array( |
||
144 | 'created' => 201, |
||
145 | 'deleted' => 200, |
||
146 | 'invalid_request' => 400, |
||
147 | 'unsupported_response_type' => 400, |
||
148 | 'invalid_scope' => 400, |
||
149 | 'temporarily_unavailable' => 400, |
||
150 | 'invalid_grant' => 400, |
||
151 | 'invalid_credentials' => 400, |
||
152 | 'invalid_refresh' => 400, |
||
153 | 'no_data' => 400, |
||
154 | 'invalid_data' => 400, |
||
155 | 'access_denied' => 401, |
||
156 | 'unauthorized' => 401, |
||
157 | 'invalid_client' => 401, |
||
158 | 'forbidden' => 403, |
||
159 | 'resource_not_found' => 404, |
||
160 | 'not_acceptable' => 406, |
||
161 | 'resource_exists' => 409, |
||
162 | 'resource_gone' => 410, |
||
163 | 'too_many_requests' => 429, |
||
164 | 'server_error' => 500, |
||
165 | 'unsupported_grant_type' => 501, |
||
166 | 'not_implemented' => 501 |
||
167 | ); |
||
168 | |||
169 | /** |
||
170 | * Convert common browser-sent langauge |
||
171 | * strings to a folder name in the languages folder |
||
172 | * that we want to use. |
||
173 | * |
||
174 | * Primarily used for converting to english when |
||
175 | * viewing the API in a browser. |
||
176 | * |
||
177 | * @var array |
||
178 | */ |
||
179 | protected $lang_map = [ |
||
180 | 'en-us' => 'english', |
||
181 | 'en' => 'english', |
||
182 | 'eng' => 'english', |
||
183 | 'en-au' => 'english', |
||
184 | 'en-nz' => 'english', |
||
185 | 'en-za' => 'english', |
||
186 | 'en-tt' => 'english', |
||
187 | 'en-gb' => 'english', |
||
188 | 'en-ca' => 'english', |
||
189 | 'en-ie' => 'english', |
||
190 | 'en-jm' => 'english', |
||
191 | 'en-bz' => 'english', |
||
192 | ]; |
||
193 | |||
194 | /** |
||
195 | * If you wish to override the default authentication |
||
196 | * library used for authentication, set this to the |
||
197 | * fully namespaced class name. |
||
198 | * |
||
199 | * @var string |
||
200 | */ |
||
201 | protected $authenticate_class = '\Myth\Api\Auth\APIAuthentication'; |
||
202 | |||
203 | /** |
||
204 | * The idiom that should be used for the language if |
||
205 | * no specific language is requested in Accept-Language header. |
||
206 | * |
||
207 | * @var string |
||
208 | */ |
||
209 | protected $default_language = 'english'; |
||
210 | |||
211 | //-------------------------------------------------------------------- |
||
212 | |||
213 | public function __construct() |
||
214 | { |
||
215 | parent::__construct(); |
||
216 | |||
217 | $this->start_time = microtime(true); |
||
218 | |||
219 | $this->request = new \stdClass(); |
||
220 | $this->request->ssl = is_https(); |
||
221 | $this->request->method = $this->detectMethod(); |
||
222 | $this->request->lang = $this->detectLanguage(); |
||
223 | |||
224 | // Load our language, requested. |
||
225 | if (! empty($this->request->lang)) |
||
226 | { |
||
227 | $file = ! empty($this->language_file) ? $this->language_file : 'application'; |
||
228 | |||
229 | if (is_array($this->request->lang)) |
||
230 | { |
||
231 | $this->load->language($file, $this->request->lang[0]); |
||
0 ignored issues
–
show
|
|||
232 | } |
||
233 | else |
||
234 | { |
||
235 | $this->load->language($file, $this->request->lang); |
||
236 | } |
||
237 | |||
238 | unset($file); |
||
239 | } |
||
240 | |||
241 | $this->config->load('api'); |
||
0 ignored issues
–
show
The property
config does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
242 | |||
243 | // Gather config defaults when a value isn't set for this controller |
||
244 | if ( empty($this->enable_logging) ) $this->enable_logging = config_item('api.enable_logging'); |
||
245 | if ( empty($this->enable_rate_limits) ) $this->enable_rate_limits = config_item('api.enable_rate_limits'); |
||
246 | if ( empty($this->rate_limits) ) $this->rate_limits = config_item('api.rate_limits'); |
||
247 | |||
248 | // Should we restrict to SSL requests? |
||
249 | if (config_item('api.require_ssl') === true && ! $this->request->ssl) |
||
250 | { |
||
251 | $this->failForbidden( lang('api.ssl_required') ); |
||
252 | } |
||
253 | |||
254 | // Should we restrict to only allow AJAX requests? |
||
255 | if (config_item('api.ajax_only') === true && ! $this->input->is_ajax_request() ) |
||
0 ignored issues
–
show
The property
input does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
256 | { |
||
257 | $this->failForbidden( lang('api.ajax_required') ); |
||
258 | } |
||
259 | |||
260 | $this->detectPage(); |
||
261 | |||
262 | if ($this->do_auth_check) |
||
263 | { |
||
264 | // Override the config setting for authentication |
||
265 | // so that we can have an application and API co-exist |
||
266 | // in a single codebase. |
||
267 | get_instance()->config->set_item('api.authenticate_lib', $this->authenticate_class); |
||
268 | |||
269 | if (! $this->restrict(null, true) ) |
||
270 | { |
||
271 | $this->logTime(); |
||
272 | $this->failUnauthorized( lang('api.unauthorized') ); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | // Has the user hit rate limits for this hour? |
||
277 | if ($this->enable_rate_limits && ! $this->isWithinLimits()) |
||
278 | { |
||
279 | $this->failTooManyRequests( sprintf( lang('api.too_many_requests'), $this->rate_limits) ); |
||
280 | } |
||
281 | |||
282 | // NEVER allow profiling via API. |
||
283 | $this->output->enable_profiler(false); |
||
0 ignored issues
–
show
The property
output does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
284 | |||
285 | // Set logging default value |
||
286 | $this->enable_logging = config_item('api.enable_logging'); |
||
287 | } |
||
288 | |||
289 | //-------------------------------------------------------------------- |
||
290 | |||
291 | /** |
||
292 | * Responsible for enforcing SSL restrictions. |
||
293 | * |
||
294 | * @param $method |
||
295 | * @param array $arguments |
||
296 | * |
||
297 | * @return mixed |
||
298 | */ |
||
299 | public function _remap($method, $arguments = []) |
||
300 | { |
||
301 | // Now, run the right thing! |
||
302 | if (method_exists($this, $method)) |
||
303 | { |
||
304 | call_user_func_array([$this, $method], $arguments); |
||
305 | |||
306 | if ($this->enable_logging === true) |
||
307 | { |
||
308 | $this->logTime(); |
||
309 | } |
||
310 | } |
||
311 | else |
||
312 | { |
||
313 | return $this->fail( lang('api.unknown_endpoint'), 'not_implemented'); |
||
314 | } |
||
315 | } |
||
316 | |||
317 | //-------------------------------------------------------------------- |
||
318 | |||
319 | //-------------------------------------------------------------------- |
||
320 | // Response Methods |
||
321 | //-------------------------------------------------------------------- |
||
322 | |||
323 | /** |
||
324 | * Provides a single, simple method to return an API response, formatted |
||
325 | * as json, with the proper content type and status code. |
||
326 | * |
||
327 | * // todo Allow responses in other formats, like jsonp, html and csv |
||
328 | * |
||
329 | * @param $data |
||
330 | * @param int $status_code |
||
331 | * |
||
332 | * @return mixed |
||
333 | */ |
||
334 | public function respond ($data = null, $status_code = 200) |
||
335 | { |
||
336 | // If data is null and not code provide, error and bail |
||
337 | if ($data === null && $status_code === null) |
||
338 | { |
||
339 | $status_code = 404; |
||
340 | |||
341 | // create the output variable here in the case of $this->response(array()); |
||
342 | $output = null; |
||
343 | } |
||
344 | |||
345 | // If data is null but http code provided, keep the output empty |
||
346 | else if ($data === null && is_numeric($status_code)) |
||
347 | { |
||
348 | $output = null; |
||
349 | } |
||
350 | |||
351 | else |
||
352 | { |
||
353 | header('Content-Type: application/json'); |
||
354 | |||
355 | $output = json_encode($data); |
||
356 | } |
||
357 | |||
358 | set_status_header($status_code); |
||
359 | |||
360 | header('Content-Length: ' . strlen($output)); |
||
361 | |||
362 | exit($output); |
||
363 | } |
||
364 | |||
365 | //-------------------------------------------------------------------- |
||
366 | |||
367 | /** |
||
368 | * Returns a failure code to the end user. Mainly so that we have a simple |
||
369 | * way to return a consistent response format. |
||
370 | * |
||
371 | * @param $description |
||
372 | * @param $status_code |
||
373 | * @param string $error_code |
||
374 | * |
||
375 | * @return mixed |
||
376 | */ |
||
377 | protected function fail ($description, $status_code, $error_code = 'invalid_request') |
||
378 | { |
||
379 | if (is_string($status_code)) |
||
380 | { |
||
381 | $error_code = $status_code; |
||
382 | $status_code = array_key_exists($status_code, $this->codes) ? $this->codes[$status_code] : 500; |
||
383 | } |
||
384 | |||
385 | $response = [ |
||
386 | 'error' => $error_code, |
||
387 | 'error_message' => $description |
||
388 | ]; |
||
389 | |||
390 | $this->respond($response, $status_code); |
||
391 | } |
||
392 | |||
393 | //-------------------------------------------------------------------- |
||
394 | |||
395 | //-------------------------------------------------------------------- |
||
396 | // Response Helpers |
||
397 | //-------------------------------------------------------------------- |
||
398 | |||
399 | /** |
||
400 | * Used after successfully creating a new resource. |
||
401 | * |
||
402 | * @param $data |
||
403 | * |
||
404 | * @return mixed |
||
405 | */ |
||
406 | protected function respondCreated($data) |
||
407 | { |
||
408 | return $this->respond($data, $this->codes['created'], 'created'); |
||
409 | } |
||
410 | |||
411 | //-------------------------------------------------------------------- |
||
412 | |||
413 | /** |
||
414 | * Used when a resource has been successfully deleted. |
||
415 | * |
||
416 | * @param $data |
||
417 | * |
||
418 | * @return mixed |
||
419 | */ |
||
420 | protected function respondDeleted($data) |
||
421 | { |
||
422 | return $this->respond($data, $this->codes['deleted'], 'deleted'); |
||
423 | } |
||
424 | |||
425 | //-------------------------------------------------------------------- |
||
426 | |||
427 | /** |
||
428 | * Used |
||
429 | * |
||
430 | * @param $description |
||
431 | * |
||
432 | * @return mixed |
||
433 | */ |
||
434 | protected function failUnauthorized($description) |
||
435 | { |
||
436 | return $this->fail($description, 'unauthorized'); |
||
437 | } |
||
438 | |||
439 | //-------------------------------------------------------------------- |
||
440 | |||
441 | /** |
||
442 | * Used when access to this resource is not allowed. Authorization |
||
443 | * will not help. |
||
444 | * |
||
445 | * @param $description |
||
446 | * |
||
447 | * @return mixed |
||
448 | */ |
||
449 | public function failForbidden($description) |
||
450 | { |
||
451 | return $this->fail($description, 'forbidden'); |
||
452 | } |
||
453 | |||
454 | //-------------------------------------------------------------------- |
||
455 | |||
456 | /** |
||
457 | * Used when the resource the request is for cannot be found. |
||
458 | * |
||
459 | * @param $description |
||
460 | * |
||
461 | * @return mixed |
||
462 | */ |
||
463 | protected function failNotFound($description) |
||
464 | { |
||
465 | return $this->fail($description, 'resource_not_found'); |
||
466 | } |
||
467 | |||
468 | //-------------------------------------------------------------------- |
||
469 | |||
470 | /** |
||
471 | * Used for when invalid data is presented to the API. |
||
472 | * |
||
473 | * @param $description |
||
474 | * |
||
475 | * @return mixed |
||
476 | */ |
||
477 | protected function failBadRequest($description) |
||
478 | { |
||
479 | return $this->fail($description, 'invalid_request'); |
||
480 | } |
||
481 | |||
482 | //-------------------------------------------------------------------- |
||
483 | |||
484 | /** |
||
485 | * Used when the data does not validate. Separate for better |
||
486 | * readability and in case we ever change the response code |
||
487 | * in the future. |
||
488 | * |
||
489 | * @param $description |
||
490 | * |
||
491 | * @return mixed |
||
492 | */ |
||
493 | protected function failValidationError($description) |
||
494 | { |
||
495 | return $this->fail($description, 'invalid_request'); |
||
496 | } |
||
497 | |||
498 | //-------------------------------------------------------------------- |
||
499 | |||
500 | /** |
||
501 | * Used when trying to create a new resource and it already exists. |
||
502 | * |
||
503 | * @param $description |
||
504 | * |
||
505 | * @return mixed |
||
506 | */ |
||
507 | protected function failResourceExists($description) |
||
508 | { |
||
509 | return $this->fail($description, 'resource_exists'); |
||
510 | } |
||
511 | |||
512 | //-------------------------------------------------------------------- |
||
513 | |||
514 | /** |
||
515 | * Used when the resource has intentionally been removed already and will not |
||
516 | * be available again. Like when its already been deleted. |
||
517 | * |
||
518 | * @param $description |
||
519 | * |
||
520 | * @return mixed |
||
521 | */ |
||
522 | protected function failResourceGone($description) |
||
523 | { |
||
524 | return $this->fail($description, 'resource_gone'); |
||
525 | } |
||
526 | |||
527 | //-------------------------------------------------------------------- |
||
528 | |||
529 | /** |
||
530 | * Used when the user has made too many requests against the within |
||
531 | * the last hour. |
||
532 | * |
||
533 | * @param $description |
||
534 | * |
||
535 | * @return mixed |
||
536 | */ |
||
537 | protected function failTooManyRequests($description) |
||
538 | { |
||
539 | return $this->fail($description, 'too_many_requests'); |
||
540 | } |
||
541 | |||
542 | //-------------------------------------------------------------------- |
||
543 | |||
544 | //-------------------------------------------------------------------- |
||
545 | // Utility Methods |
||
546 | //-------------------------------------------------------------------- |
||
547 | |||
548 | /** |
||
549 | * @param $name |
||
550 | * |
||
551 | * @return bool |
||
552 | */ |
||
553 | public function grabVar($name) |
||
554 | { |
||
555 | return array_key_exists($name, $this->vars) ? $this->vars[$name] : false; |
||
556 | } |
||
557 | |||
558 | //-------------------------------------------------------------------- |
||
559 | |||
560 | /** |
||
561 | * Creates the URL for the next set of results based on the |
||
562 | * 'page' value set in the calling URL. |
||
563 | * |
||
564 | * If $clean_get is TRUE will only include the ?page value on |
||
565 | * the URL, otherwise will include all $_GET values that were |
||
566 | * sent to the URL. |
||
567 | * |
||
568 | * Returns null if this request has had paging turned off, |
||
569 | * via ?page=0. |
||
570 | * |
||
571 | * @param $path |
||
572 | * @param $clean_get |
||
573 | * |
||
574 | * @return string |
||
575 | */ |
||
576 | View Code Duplication | public function nextURL($path, $clean_get = false) |
|
577 | { |
||
578 | // If paging is turned off, get out of here |
||
579 | if ($this->per_page == 0) |
||
580 | { |
||
581 | return null; |
||
582 | } |
||
583 | |||
584 | $params = []; |
||
585 | |||
586 | $params['page'] = ($this->page > 1 ? $this->page + 1 : 2); |
||
587 | |||
588 | if (! $clean_get) |
||
589 | { |
||
590 | if ( ! isset($_GET) || ! is_array($_GET) ) |
||
591 | { |
||
592 | $_GET = []; |
||
593 | } |
||
594 | |||
595 | foreach ( $_GET as $key => $value ) |
||
596 | { |
||
597 | $params[ $key ] = $value; |
||
598 | } |
||
599 | |||
600 | // Ensure we get a correct per_page value |
||
601 | if (! array_key_exists('per_page', $params)) |
||
602 | { |
||
603 | $params['per_page'] = $this->per_page; |
||
604 | } |
||
605 | } |
||
606 | |||
607 | return site_url($path) .'?'. http_build_query($params); |
||
608 | } |
||
609 | |||
610 | //-------------------------------------------------------------------- |
||
611 | |||
612 | /** |
||
613 | * Creates the URL for the prev set of results based on the |
||
614 | * 'page' value set in the calling URL. |
||
615 | * |
||
616 | * If $clean_get is TRUE will only include the ?page value on |
||
617 | * the URL, otherwise will include all $_GET values that were |
||
618 | * sent to the URL. |
||
619 | * |
||
620 | * Returns null if this request has had paging turned off, |
||
621 | * via ?page=0. |
||
622 | * |
||
623 | * @param $path |
||
624 | * @param bool $clean_get |
||
625 | * |
||
626 | * @return string |
||
627 | */ |
||
628 | View Code Duplication | public function prevURL ($path, $clean_get = false) |
|
629 | { |
||
630 | // If paging is turned off, get out of here |
||
631 | if ($this->per_page == 0) |
||
632 | { |
||
633 | return null; |
||
634 | } |
||
635 | |||
636 | $params = []; |
||
637 | |||
638 | $params['page'] = ($this->page > 1 ? $this->page - 1 : 1); |
||
639 | |||
640 | if (! $clean_get) |
||
641 | { |
||
642 | if ( ! isset($_GET) || ! is_array($_GET) ) |
||
643 | { |
||
644 | $_GET = []; |
||
645 | } |
||
646 | |||
647 | foreach ( $_GET as $key => $value ) |
||
648 | { |
||
649 | $params[$key] = $value; |
||
650 | } |
||
651 | |||
652 | // Ensure we get a correct per_page value |
||
653 | if (! array_key_exists('per_page', $params)) |
||
654 | { |
||
655 | $params['per_page'] = $this->per_page; |
||
656 | } |
||
657 | } |
||
658 | |||
659 | return site_url($path) .'?'. http_build_query($params); |
||
660 | } |
||
661 | |||
662 | //-------------------------------------------------------------------- |
||
663 | |||
664 | //-------------------------------------------------------------------- |
||
665 | // Internal Methods |
||
666 | //-------------------------------------------------------------------- |
||
667 | |||
668 | /** |
||
669 | * Determines the current page and offset based upon a ?page $_GET var. |
||
670 | * |
||
671 | * The offset value is based on the current $this->per_page value. |
||
672 | * |
||
673 | * A request can set ?page=0 to turn off paging altogether. |
||
674 | */ |
||
675 | protected function detectPage( ) |
||
676 | { |
||
677 | // Is a per-page limit being set? |
||
678 | $this->per_page = isset($_GET['per_page']) ? (int)$_GET['per_page'] : $this->per_page; |
||
679 | |||
680 | $page = (int)$this->input->get('page'); |
||
681 | |||
682 | if (! $page || $page == 1) |
||
683 | { |
||
684 | $offset = 0; |
||
685 | } |
||
686 | else |
||
687 | { |
||
688 | $offset = (($page - 1) * $this->per_page) + 1; |
||
689 | } |
||
690 | |||
691 | $this->page = $page; |
||
692 | $this->offset = $offset; |
||
693 | |||
694 | // If they've specifically passed in page=0, then we need |
||
695 | // to ignore paging... |
||
696 | if ((int)$this->input->get('page') === 0 && ! is_null($this->input->get('page')) ) |
||
697 | { |
||
698 | $this->per_page = 0; |
||
699 | } |
||
700 | } |
||
701 | |||
702 | //-------------------------------------------------------------------- |
||
703 | |||
704 | /** |
||
705 | * Detects the request method and populates the $vars array based on |
||
706 | * the method found. |
||
707 | * |
||
708 | * NOTE that any $_GET vars will have to be accessed by the standard |
||
709 | * methods when the method isn't a GET request. |
||
710 | * |
||
711 | * @return string |
||
712 | */ |
||
713 | protected function detectMethod() |
||
714 | { |
||
715 | $method = strtolower($this->input->server('REQUEST_METHOD')); |
||
716 | |||
717 | // If it's not an allowed method, let's default to a GET |
||
718 | if (! in_array($method, $this->allowed_http_methods)) |
||
719 | { |
||
720 | $method = 'get'; |
||
721 | } |
||
722 | |||
723 | // Populate our $vars based on the input type. |
||
724 | switch ($method) |
||
725 | { |
||
726 | case 'get': |
||
727 | $this->vars = $_GET; |
||
728 | break; |
||
729 | case 'post': |
||
730 | $this->vars = $_POST; |
||
731 | break; |
||
732 | default: |
||
733 | $this->vars = $this->getJSON('array'); |
||
734 | break; |
||
735 | } |
||
736 | |||
737 | return $method; |
||
738 | } |
||
739 | |||
740 | //-------------------------------------------------------------------- |
||
741 | |||
742 | /** |
||
743 | * Detects one or more languages that should the request should be |
||
744 | * returned as. If more than 1 exists, just load the first language |
||
745 | * file. |
||
746 | * |
||
747 | * @return array|mixed|null |
||
748 | */ |
||
749 | protected function detectLanguage() |
||
750 | { |
||
751 | if ( ! $lang = $this->input->get_request_header('Accept-Language')) |
||
752 | { |
||
753 | return $this->default_language; |
||
754 | } |
||
755 | |||
756 | // They might have sent a few, make it an array |
||
757 | if (strpos($lang, ',') !== false) |
||
758 | { |
||
759 | $langs = explode(',', $lang); |
||
760 | |||
761 | $return_langs = array(); |
||
762 | |||
763 | foreach ($langs as $lang) |
||
764 | { |
||
765 | // Remove weight and strip space |
||
766 | list($lang) = explode(';', $lang); |
||
767 | |||
768 | $lang = strtolower(trim($lang)); |
||
769 | |||
770 | if (array_key_exists($lang, $this->lang_map)) |
||
771 | { |
||
772 | $lang = $this->lang_map[$lang]; |
||
773 | } |
||
774 | |||
775 | // We must check to see if the folder exists |
||
776 | // here since CI's lang->load will throw |
||
777 | // an error if the language doesn't exist. |
||
778 | if (is_dir(APPPATH .'language/'. $lang)) |
||
779 | { |
||
780 | $return_langs[] = $lang; |
||
781 | } |
||
782 | } |
||
783 | |||
784 | // If no languages were added, let the script |
||
785 | // send the default language back instead. |
||
786 | if (! empty($return_langs)) |
||
787 | { |
||
788 | return $return_langs; |
||
789 | } |
||
790 | } |
||
791 | |||
792 | // Nope, just return the string |
||
793 | return empty($lang) ? $this->default_language : $lang; |
||
794 | } |
||
795 | |||
796 | //-------------------------------------------------------------------- |
||
797 | |||
798 | /** |
||
799 | * Checks for the $_GET key of 'fields' and will store that |
||
800 | * value automatically in $this->selects for use in your own queries. |
||
801 | */ |
||
802 | public function detectFields() |
||
803 | { |
||
804 | if (! array_key_exists('fields', $_GET)) |
||
805 | { |
||
806 | return; |
||
807 | } |
||
808 | |||
809 | $fields = explode(',', $_GET['fields']); |
||
810 | |||
811 | if (! is_array($fields)) |
||
812 | { |
||
813 | return; |
||
814 | } |
||
815 | |||
816 | array_walk($fields, function(&$item, $key) { |
||
817 | $item = trim($item); |
||
818 | }); |
||
819 | |||
820 | $this->selects = $fields; |
||
821 | } |
||
822 | |||
823 | //-------------------------------------------------------------------- |
||
824 | |||
825 | |||
826 | /** |
||
827 | * Takes care of logging the request information to the database. |
||
828 | */ |
||
829 | public function logTime() |
||
830 | { |
||
831 | if (! $this->enable_logging) |
||
832 | { |
||
833 | return; |
||
834 | } |
||
835 | |||
836 | $model = new LogModel(); |
||
837 | |||
838 | $data = [ |
||
839 | 'duration' => microtime(true) - $this->start_time, |
||
840 | 'user_id' => $this->authenticate->id(), |
||
841 | 'ip_address' => $this->input->ip_address(), |
||
842 | 'request' => $this->uri->uri_string() .'?'. $_SERVER['QUERY_STRING'], |
||
0 ignored issues
–
show
The property
uri does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
843 | 'method' => $this->request->method |
||
844 | ]; |
||
845 | |||
846 | $model->insert($data); |
||
847 | } |
||
848 | |||
849 | //-------------------------------------------------------------------- |
||
850 | |||
851 | /** |
||
852 | * Checks the user's number of requests within the current hour. |
||
853 | * Returns true if they are within their limits and can make additional |
||
854 | * requests. Returns false if they have exceeded the number of requests |
||
855 | * for this hour. |
||
856 | * |
||
857 | * @return bool |
||
858 | */ |
||
859 | private function isWithinLimits() |
||
860 | { |
||
861 | $model = new LogModel(); |
||
862 | |||
863 | if ($model->requestsThisHourForUser( $this->authenticate->id() ) > $this->rate_limits) |
||
864 | { |
||
865 | return false; |
||
866 | } |
||
867 | |||
868 | return true; |
||
869 | } |
||
870 | |||
871 | //-------------------------------------------------------------------- |
||
872 | |||
873 | } |
||
874 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: