1 | <?php |
||||
2 | |||||
3 | namespace MVC; |
||||
4 | |||||
5 | setlocale(LC_ALL, 'en_US.UTF-8'); |
||||
6 | if (!defined('ROOT')) { |
||||
7 | define('ROOT', realpath(__DIR__ . '/../../')); |
||||
8 | } |
||||
9 | |||||
10 | class helper |
||||
11 | { |
||||
12 | public static $key = 'AUX'; |
||||
13 | public static $expire = 10; |
||||
14 | public static $router; |
||||
15 | /** |
||||
16 | * Class architecture database. |
||||
17 | * |
||||
18 | * @var array |
||||
19 | */ |
||||
20 | public static $arch = []; |
||||
21 | |||||
22 | public function __construct() |
||||
23 | { |
||||
24 | if (!isset($_SERVER['HTTP_USER_AGENT']) || false !== stripos(strtolower($_SERVER['HTTP_USER_AGENT']), 'curl')) { |
||||
25 | http_response_code(403); |
||||
26 | if (ob_get_level()) { |
||||
27 | ob_end_clean(); |
||||
28 | } |
||||
29 | include __DIR__ . '/themes/robot/index.php'; |
||||
30 | exit; |
||||
0 ignored issues
–
show
|
|||||
31 | } |
||||
32 | if (isset($_REQUEST['cache'])) { |
||||
33 | self::$key .= $_REQUEST['cache']; |
||||
34 | } |
||||
35 | if (!self::$router) { |
||||
36 | self::$router = new router(); |
||||
37 | } |
||||
38 | } |
||||
39 | |||||
40 | /** |
||||
41 | * ```php |
||||
42 | * if (env('dev')) return boolean; //is development environtment or not |
||||
43 | * ``` |
||||
44 | * Get environtment framework. |
||||
45 | * |
||||
46 | * @param string $for dev or prod |
||||
47 | * |
||||
48 | * @return string|bool |
||||
49 | */ |
||||
50 | public static function env($for) |
||||
51 | { |
||||
52 | if (!self::$router) { |
||||
53 | self::$router = new router(); |
||||
54 | } |
||||
55 | |||||
56 | if ('dev' == $for || 'development' == $for) { |
||||
57 | return 'development' == self::$router->get_env(); |
||||
58 | } elseif ('prod' == $for || 'production' == $for) { |
||||
59 | return 'production' == self::$router->get_env(); |
||||
60 | } else { |
||||
61 | return self::$router->get_env(); |
||||
62 | } |
||||
63 | } |
||||
64 | |||||
65 | public static function config() |
||||
66 | { |
||||
67 | return \Filemanager\file::get(ROOT . '/config.json', true); |
||||
68 | } |
||||
69 | |||||
70 | /** |
||||
71 | * Get Header Request Accept. |
||||
72 | * |
||||
73 | * @return void |
||||
74 | */ |
||||
75 | public static function HeaderAccept() |
||||
76 | { |
||||
77 | if (isset($_SERVER['HTTP_ACCEPT']) && $accept = $_SERVER['HTTP_ACCEPT']) { |
||||
78 | switch ($accept) { |
||||
79 | case '*/*': |
||||
80 | return 'any'; |
||||
0 ignored issues
–
show
|
|||||
81 | break; |
||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||
82 | case 'application/javascript': |
||||
83 | return 'javascript'; |
||||
0 ignored issues
–
show
|
|||||
84 | break; |
||||
85 | case 'application/json': |
||||
86 | return 'json'; |
||||
0 ignored issues
–
show
|
|||||
87 | break; |
||||
88 | /*case strpos($accept, 'application/json') >= 0: |
||||
89 | return 'has_json'; |
||||
90 | break; |
||||
91 | case strpos($accept, 'application/javascript') >= 0: |
||||
92 | return 'has_javascript'; |
||||
93 | break;*/ |
||||
94 | default: |
||||
95 | return $accept; |
||||
96 | break; |
||||
97 | } |
||||
98 | } |
||||
99 | } |
||||
100 | |||||
101 | /** |
||||
102 | * Clean output buffers. |
||||
103 | * |
||||
104 | * @return void |
||||
105 | */ |
||||
106 | public static function cleanBuffer() |
||||
107 | { |
||||
108 | if (ob_get_level()) { |
||||
109 | ob_end_clean(); |
||||
110 | ob_start(); |
||||
111 | } |
||||
112 | } |
||||
113 | |||||
114 | public static function require_method(string $method) |
||||
115 | { |
||||
116 | $method = strtoupper($method); |
||||
117 | if ($method != $_SERVER['REQUEST_METHOD']) { |
||||
118 | throw new Exception("Request only accept $method request", 1); |
||||
119 | } |
||||
120 | } |
||||
121 | |||||
122 | /** |
||||
123 | * is url ? |
||||
124 | * |
||||
125 | * @param string $url |
||||
126 | * |
||||
127 | * @return bool |
||||
128 | */ |
||||
129 | public static function is_url($url) |
||||
130 | { |
||||
131 | return filter_var($url, FILTER_VALIDATE_URL); |
||||
132 | } |
||||
133 | |||||
134 | /** |
||||
135 | * transfor url to host (domain only). |
||||
136 | * |
||||
137 | * @param mixed $fallback if url is not valid return $fallback value |
||||
138 | * |
||||
139 | * @return string|null |
||||
140 | */ |
||||
141 | public static function url2host(string $url, $fallback = null) |
||||
142 | { |
||||
143 | if ( |
||||
144 | isset(self::$arch[__FUNCTION__][md5($url)]) && |
||||
145 | !empty(self::$arch[__FUNCTION__][md5($url)]) |
||||
146 | ) { |
||||
147 | return self::$arch[__FUNCTION__][md5($url)]; |
||||
148 | } |
||||
149 | if (self::is_url($url)) { |
||||
150 | $parse = self::parse_url2($url); |
||||
151 | if (isset($parse['host'])) { |
||||
152 | self::$arch[__FUNCTION__][md5($url)] = $parse['host']; |
||||
153 | |||||
154 | return $parse['host']; |
||||
155 | } |
||||
156 | } |
||||
157 | |||||
158 | return $fallback; |
||||
159 | } |
||||
160 | |||||
161 | public static function include_asset($fn, $fn2 = null, $callback = null) |
||||
162 | { |
||||
163 | if (file_exists($fn)) { |
||||
164 | include $fn; |
||||
165 | } elseif ($fn2 && file_exists($fn2)) { |
||||
166 | include $fn2; |
||||
167 | } elseif (is_callable($callback)) { |
||||
168 | call_user_func($callback, $fn); |
||||
169 | } |
||||
170 | } |
||||
171 | |||||
172 | public static function asset_find(array $fn = []) |
||||
173 | { |
||||
174 | $source = null; |
||||
175 | foreach ($fn as $src) { |
||||
176 | if ($src && !empty($src)) { |
||||
177 | if (file_exists($src) && is_file($src) && $src = realpath($src)) { |
||||
178 | $source = $src; |
||||
179 | break; |
||||
180 | } |
||||
181 | } |
||||
182 | } |
||||
183 | |||||
184 | return $source; |
||||
185 | } |
||||
186 | |||||
187 | /** |
||||
188 | * Sass Compiler. |
||||
189 | * |
||||
190 | * @requires shell_exec |
||||
191 | */ |
||||
192 | public static function sass(string $path) |
||||
193 | { |
||||
194 | \Cookie\helper::one('sass' . self::$key, 'compiler', 1, function () use ($path) { |
||||
195 | if (is_file($path)) { |
||||
196 | if (self::is_windows()) { |
||||
197 | $path = self::fixSlash($path); |
||||
198 | } |
||||
199 | $exec = shell_exec('sass ' . $path); |
||||
200 | if (!empty($exec)) { |
||||
201 | //echo $exec; |
||||
202 | $save = preg_replace('/\.scss/s', '.css', $path); |
||||
203 | \Filemanager\file::file($save, $exec, true); |
||||
0 ignored issues
–
show
$exec of type null|string is incompatible with the type boolean expected by parameter $create of Filemanager\file::file() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
204 | } |
||||
205 | } |
||||
206 | }); |
||||
207 | } |
||||
208 | |||||
209 | /** |
||||
210 | * GET PHP ERROR LOG. |
||||
211 | * |
||||
212 | * @return string|null |
||||
213 | */ |
||||
214 | public static function php_error_log(bool $onlypath = false) |
||||
215 | { |
||||
216 | $log = PHP_ERROR_FILE; |
||||
217 | if ($log = realpath($log)) { |
||||
218 | if ('DELETE' == $_SERVER['REQUEST_METHOD']) { |
||||
219 | if ('php' == self::is_header('Log')) { |
||||
220 | unlink($log); |
||||
221 | } |
||||
222 | } |
||||
223 | if (!$onlypath) { |
||||
224 | return read_file($log); |
||||
225 | } else { |
||||
226 | return $log; |
||||
227 | } |
||||
228 | } |
||||
229 | } |
||||
230 | |||||
231 | /** |
||||
232 | * Check if header request has $any. |
||||
233 | * |
||||
234 | * @return string|null |
||||
235 | */ |
||||
236 | public static function is_header(string $any) |
||||
237 | { |
||||
238 | $allHeaders = getallheaders(); |
||||
239 | |||||
240 | return array_key_exists($any, $allHeaders) ? $allHeaders[$any] : null; |
||||
0 ignored issues
–
show
It seems like
$allHeaders can also be of type true ; however, parameter $array of array_key_exists() does only seem to accept ArrayObject|array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
241 | } |
||||
242 | |||||
243 | public static function babel(string $path) |
||||
244 | { |
||||
245 | \Cookie\helper::one('babel' . self::$key, 'compiler', 1, function () use ($path) { |
||||
246 | if (is_file($path)) { |
||||
247 | if (self::is_windows()) { |
||||
248 | $path = self::fixSlash($path); |
||||
249 | } |
||||
250 | $exec = shell_exec('npx babel ' . $path); |
||||
251 | $save = \Filemanager\file::tmp() . '/js/babel/' . basename($path); |
||||
252 | if (!empty($exec)) { |
||||
253 | \Filemanager\file::file($save, $exec, true); |
||||
0 ignored issues
–
show
$exec of type null|string is incompatible with the type boolean expected by parameter $create of Filemanager\file::file() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
254 | $min = shell_exec('terser ' . self::fixSlash($save)); |
||||
255 | /*if (!empty($min)) { |
||||
256 | echo $min; |
||||
257 | } else { |
||||
258 | echo $save; |
||||
259 | }*/ |
||||
260 | if (!empty($min)) { |
||||
261 | $minjs = preg_replace('/\.babel\.js/s', '.min.js', $path); |
||||
262 | \Filemanager\file::file($minjs, $min, true); |
||||
263 | } else { |
||||
264 | $js = preg_replace('/\.babel\.js/s', '.js', $path); |
||||
265 | \Filemanager\file::file($js, $exec, true); |
||||
266 | } |
||||
267 | } |
||||
268 | } |
||||
269 | }); |
||||
270 | } |
||||
271 | |||||
272 | /** |
||||
273 | * Clean special characters from string. |
||||
274 | * |
||||
275 | * @param string $replace |
||||
276 | * |
||||
277 | * @return string |
||||
278 | */ |
||||
279 | public static function clean_special_characters(string $string, $replace = '') |
||||
280 | { |
||||
281 | //$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. |
||||
282 | $string = self::clean_multiple_hypens($string); |
||||
283 | |||||
284 | return preg_replace('/[^A-Za-z0-9\-]/', $replace, $string); // Removes special chars. |
||||
285 | } |
||||
286 | |||||
287 | public static function clean_multiple_hypens($string) |
||||
288 | { |
||||
289 | $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. |
||||
290 | $string = preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. |
||||
291 | |||||
292 | return preg_replace('/-+/', '-', $string); // Replaces multiple hyphens with single one. |
||||
293 | } |
||||
294 | |||||
295 | public static function clean_whitespace(string $str) |
||||
296 | { |
||||
297 | return preg_replace('/\s{1,99}/s', '', $str); |
||||
298 | } |
||||
299 | |||||
300 | public static function webkit_asset(string $path, string $alternative = null) |
||||
301 | { |
||||
302 | $path = realpath($path); |
||||
303 | if (!$path && $alternative) { |
||||
304 | $path = realpath($alternative); |
||||
305 | } |
||||
306 | if ($path) { |
||||
307 | $root = realpath(ROOT); |
||||
308 | $pathNoRoot = helper::fixSlash(str_replace($root, '', $path)); |
||||
309 | |||||
310 | return self::base_url("/load-asset?src=$pathNoRoot"); |
||||
311 | } |
||||
312 | } |
||||
313 | |||||
314 | public static function load_asset($path) |
||||
315 | { |
||||
316 | $root = realpath(ROOT); |
||||
317 | if ($path = realpath($root . $path)) { |
||||
318 | $ext = pathinfo($path, PATHINFO_EXTENSION); |
||||
319 | //var_dump($path, $ext); |
||||
320 | if (self::headerExt($ext)) { |
||||
321 | http_response_code(200); |
||||
322 | include $path; |
||||
323 | } |
||||
324 | } |
||||
325 | } |
||||
326 | |||||
327 | public static function headerExt($ext) |
||||
328 | { |
||||
329 | $mimes = include __DIR__ . '/mimes.php'; |
||||
330 | if (isset($mimes[$ext][0])) { |
||||
331 | if (!headers_sent()) { |
||||
332 | header("Content-Type: {$mimes[$ext][0]}"); |
||||
333 | |||||
334 | return true; |
||||
335 | } |
||||
336 | } |
||||
337 | |||||
338 | return false; |
||||
339 | } |
||||
340 | |||||
341 | /** |
||||
342 | * Parse URL deeper. |
||||
343 | * |
||||
344 | * @param string $url |
||||
345 | * @param bool $encoded |
||||
346 | * |
||||
347 | * @return parse_url |
||||
0 ignored issues
–
show
The type
MVC\parse_url was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
348 | */ |
||||
349 | public static function parse_url2($url, $encoded = false) |
||||
350 | { |
||||
351 | if ($encoded) { |
||||
352 | $url = urldecode($url); |
||||
353 | } |
||||
354 | $url = html_entity_decode($url); |
||||
355 | $parts = parse_url($url); |
||||
356 | if (!isset($parts['path'])) { |
||||
357 | $parts['path'] = ''; |
||||
358 | } |
||||
359 | if (isset($parts['query'])) { |
||||
360 | parse_str($parts['query'], $query); |
||||
361 | $parts['original_query'] = $parts['query']; |
||||
362 | $parts['query'] = $query; |
||||
363 | } |
||||
364 | |||||
365 | return array_merge($parts); |
||||
0 ignored issues
–
show
|
|||||
366 | } |
||||
367 | |||||
368 | /** |
||||
369 | * Fix path string `default OS` separate slash and replaced by `/` |
||||
370 | * * WIN (\\) |
||||
371 | * * LINUX (/). |
||||
372 | * |
||||
373 | * @return string |
||||
374 | */ |
||||
375 | public static function fixSlash(string $path, int $maxlength = 10) |
||||
376 | { |
||||
377 | $re = '/\\' . DIRECTORY_SEPARATOR . '{1,' . $maxlength . '}/s'; |
||||
378 | //var_dump($re); |
||||
379 | return preg_replace($re, '/', $path); |
||||
380 | } |
||||
381 | |||||
382 | /** |
||||
383 | * Get path base URL |
||||
384 | * * example (/cookie/file.html) -> (https://httpbin.org/cookie/file.html). |
||||
385 | * |
||||
386 | * @param string $path pathname from base url |
||||
387 | * @param bool $forceSSL force https protocol returned |
||||
388 | * * true or false or null |
||||
389 | * |
||||
390 | * @return string protocol://origin/pathname |
||||
391 | */ |
||||
392 | public static function base_url(string $path, bool $forceSSL = false) |
||||
393 | { |
||||
394 | $protocol = isset($_SERVER['HTTPS']) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http'; |
||||
395 | if ($forceSSL) { |
||||
396 | $protocol = 'https'; |
||||
397 | } |
||||
398 | |||||
399 | return $protocol . "://{$_SERVER['HTTP_HOST']}{$path}"; |
||||
400 | } |
||||
401 | |||||
402 | /** |
||||
403 | * Get current URL. |
||||
404 | * |
||||
405 | * @param bool $forceSSL force https protocol returned |
||||
406 | * * true or false or null |
||||
407 | * |
||||
408 | * @return string protocol://origin/pathname |
||||
409 | */ |
||||
410 | public static function geturl(bool $forceSSL = false) |
||||
411 | { |
||||
412 | $protocol = isset($_SERVER['HTTPS']) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http'; |
||||
413 | if ($forceSSL) { |
||||
414 | $protocol = 'https'; |
||||
415 | } |
||||
416 | |||||
417 | return $protocol . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; |
||||
418 | } |
||||
419 | |||||
420 | private static $origin = null; |
||||
421 | |||||
422 | public static function getOrigin() |
||||
423 | { |
||||
424 | if (!self::$origin) { |
||||
425 | $protocol = isset($_SERVER['HTTPS']) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http'; |
||||
426 | self::$origin = $protocol . "://$_SERVER[HTTP_HOST]"; |
||||
427 | } |
||||
428 | |||||
429 | return self::$origin; |
||||
430 | } |
||||
431 | |||||
432 | private static $canonical = []; |
||||
433 | /** |
||||
434 | * get canonical url |
||||
435 | * |
||||
436 | * @param string $url null for current page |
||||
437 | * @param boolean $whos include host or not (http://domain) |
||||
438 | * @return void |
||||
439 | */ |
||||
440 | public static function get_canonical(string $url = null, bool $whos = true) |
||||
441 | { |
||||
442 | if (null === $url) { |
||||
443 | $url = self::geturl(); |
||||
444 | } |
||||
445 | if (isset(self::$canonical[$url])) { |
||||
446 | return self::$canonical[$url]; |
||||
447 | } else { |
||||
448 | $url_parts = parse_url($url); |
||||
449 | if ($whos) { |
||||
450 | self::$canonical[$url] = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path']) ? $url_parts['path'] : ''); |
||||
451 | } else { |
||||
452 | self::$canonical[$url] = (isset($url_parts['path']) ? $url_parts['path'] : ''); |
||||
453 | } |
||||
454 | } |
||||
455 | |||||
456 | return self::$canonical[$url]; |
||||
457 | } |
||||
458 | |||||
459 | /** |
||||
460 | * Get `request uri` without parameter. |
||||
461 | * |
||||
462 | * @param string $url |
||||
463 | * |
||||
464 | * @return string |
||||
465 | */ |
||||
466 | public static function get_clean_uri(string $url = null) |
||||
467 | { |
||||
468 | if (null === $url) { |
||||
469 | $url = self::geturl(); |
||||
470 | } |
||||
471 | |||||
472 | return self::parse_url2($url)['path']; |
||||
473 | } |
||||
474 | |||||
475 | /** |
||||
476 | * Check if current is localhost. |
||||
477 | * |
||||
478 | * @param string $regex new regex |
||||
479 | * |
||||
480 | * @return bool |
||||
481 | */ |
||||
482 | public static function isLocal(string $regex = null) |
||||
483 | { |
||||
484 | $match = preg_match('/127\.0\.0\.0\.1|localhost|^192\.168/s', $_SERVER['HTTP_HOST']) ? true : false; |
||||
485 | |||||
486 | $whitelist = array( |
||||
487 | '127.0.0.1', |
||||
488 | '::1' |
||||
489 | ); |
||||
490 | |||||
491 | if (!in_array($_SERVER['REMOTE_ADDR'], $whitelist)) { |
||||
492 | $match = false; |
||||
493 | } else { |
||||
494 | if ($regex) { |
||||
495 | $match = $match || preg_match($regex, $_SERVER['HTTP_HOST']) ? true : false; |
||||
496 | } else { |
||||
497 | $match = true; |
||||
498 | } |
||||
499 | } |
||||
500 | |||||
501 | return $match; |
||||
502 | } |
||||
503 | |||||
504 | /** |
||||
505 | * Set cookie helper. |
||||
506 | * |
||||
507 | * @param mixed $value |
||||
508 | * @param int|float $day |
||||
509 | * @param string $path |
||||
510 | * @param string $domain |
||||
511 | * @param bool $secure |
||||
512 | * @param bool $httponly |
||||
513 | */ |
||||
514 | public static function setcookie(string $name, $value = true, $day, $path = '/', $domain = '', $secure = false, $httponly = false) |
||||
515 | { |
||||
516 | settype($day, 'integer'); |
||||
517 | if (empty($domain)) { |
||||
518 | $domain = $_SERVER['HTTP_HOST']; |
||||
519 | } |
||||
520 | if (empty($path)) { |
||||
521 | $path = '/'; |
||||
522 | } |
||||
523 | |||||
524 | return setcookie($name, $value, time() + 60 * 60 * 24 * $day, $path, $domain, $secure, $httponly); |
||||
0 ignored issues
–
show
It seems like
$value can also be of type true ; however, parameter $value of setcookie() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
525 | } |
||||
526 | |||||
527 | /** |
||||
528 | * Get Cookie By Name. |
||||
529 | */ |
||||
530 | public static function getcookie(string $name) |
||||
531 | { |
||||
532 | if (isset($_COOKIE[$name])) { |
||||
533 | return $_COOKIE[$name]; |
||||
534 | } |
||||
535 | |||||
536 | return null; |
||||
537 | } |
||||
538 | |||||
539 | public static function delcookie(string $name) |
||||
540 | { |
||||
541 | if (isset($_COOKIE[$name])) { |
||||
542 | unset($_COOKIE[$name]); |
||||
543 | setcookie($name, null, -1, '/'); |
||||
544 | |||||
545 | return true; |
||||
546 | } else { |
||||
547 | return false; |
||||
548 | } |
||||
549 | } |
||||
550 | |||||
551 | /** |
||||
552 | * Get request data |
||||
553 | * * $_GET[$name] |
||||
554 | * * $_REQUEST[$name] |
||||
555 | * * $_POST[$name]. |
||||
556 | * |
||||
557 | * @param string $type request method |
||||
558 | * * get = only accept get |
||||
559 | * * post = only accept post |
||||
560 | * * any = accept all request |
||||
561 | * @param mixed $name What data requests will you take? |
||||
562 | * |
||||
563 | * @return string|null |
||||
564 | */ |
||||
565 | public static function request_data(string $type = 'get', $name) |
||||
566 | { |
||||
567 | $method = $_SERVER['REQUEST_METHOD']; |
||||
568 | $allowed = $method == strtoupper($type) || 'any' == $type; |
||||
569 | //var_dump($allowed); |
||||
570 | if ($allowed) { |
||||
571 | if (isset($_REQUEST[$name])) { |
||||
572 | return $_REQUEST[$name]; |
||||
573 | } |
||||
574 | } |
||||
575 | } |
||||
576 | |||||
577 | /** |
||||
578 | * Detect current OS is Windows. |
||||
579 | * |
||||
580 | * @return bool |
||||
581 | */ |
||||
582 | public static function is_windows() |
||||
583 | { |
||||
584 | return 'WIN' === strtoupper(substr(PHP_OS, 0, 3)); |
||||
585 | } |
||||
586 | |||||
587 | public static function platformSlashes($path) |
||||
588 | { |
||||
589 | $path = str_replace('//', '/', $path); |
||||
590 | |||||
591 | return str_replace('/', DIRECTORY_SEPARATOR, $path); |
||||
592 | } |
||||
593 | |||||
594 | /** |
||||
595 | * Cors domain verify, detect AJAX, and validate AJAX CORS. |
||||
596 | * |
||||
597 | * @param bool $print_server Debug mode |
||||
598 | * |
||||
599 | * @todo only allow CORS request |
||||
600 | */ |
||||
601 | public static function cors($print_server = false) |
||||
602 | { |
||||
603 | $final = true; |
||||
604 | $xrequested = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? $_SERVER['HTTP_X_REQUESTED_WITH'] : false; |
||||
605 | |||||
606 | $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : false; |
||||
607 | |||||
608 | if (isset($_SERVER['HTTP_ACCEPT']) && preg_match('/^application\/json/s', $_SERVER['HTTP_ACCEPT'])) { |
||||
609 | header('Content-type: application/json; charset=utf-8'); |
||||
610 | } |
||||
611 | header('Access-Control-Allow-Origin: *'); //allow all AJAX REQUEST |
||||
612 | |||||
613 | if (false !== $xrequested) { |
||||
614 | if ('xmlhttprequest' != strtolower($xrequested)) { |
||||
615 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
616 | |||||
617 | if ($print_server) { |
||||
618 | return $_SERVER; |
||||
619 | } else { |
||||
620 | return false; |
||||
621 | } |
||||
622 | } else { |
||||
623 | if (isset($_SERVER['HTTP_SEC_FETCH_SITE'], $_SERVER['HTTP_SEC_FETCH_MODE'], $_SERVER['HTTP_REFERER'], $_SERVER['HTTP_ORIGIN'], $_SERVER['HTTP_USER_AGENT'])) { |
||||
624 | $parseRef = parse_url($_SERVER['HTTP_REFERER']); |
||||
625 | $parseOri = parse_url($_SERVER['HTTP_ORIGIN']); |
||||
626 | if (!isset($parseOri['host']) || !isset($parseRef['host'])) { |
||||
627 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
628 | |||||
629 | if ($print_server) { |
||||
630 | return $_SERVER; |
||||
631 | } else { |
||||
632 | return false; |
||||
633 | } |
||||
634 | } |
||||
635 | if ($parseOri['host'] != $parseRef['host']) { |
||||
636 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
637 | |||||
638 | if ($print_server) { |
||||
639 | return $_SERVER; |
||||
640 | } else { |
||||
641 | return false; |
||||
642 | } |
||||
643 | } |
||||
644 | if ('same-origin' == $_SERVER['HTTP_SEC_FETCH_SITE'] && 'cors' == $_SERVER['HTTP_SEC_FETCH_MODE']) { |
||||
645 | return $parseOri['host'] == $parseRef['host']; |
||||
646 | } else { |
||||
647 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
648 | if ($print_server) { |
||||
649 | return $_SERVER; |
||||
650 | } else { |
||||
651 | return false; |
||||
652 | } |
||||
653 | } |
||||
654 | } |
||||
655 | } |
||||
656 | } else { |
||||
657 | $final = false; |
||||
658 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
659 | } |
||||
660 | |||||
661 | if ($origin) { |
||||
662 | header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); |
||||
663 | header('Access-Control-Expose-Headers: date,content-type,transfer-encoding,connection,access-control-allow-origin,server,x-xss-protection,x-content-type-options,x-request-id,content-encoding,x-final-url'); |
||||
664 | header('Access-Control-Allow-Credentials: true'); |
||||
665 | header('Access-Control-Max-Age: 86400'); // cache for 1 day |
||||
666 | if (isset($_SERVER['HTTP_REFERER'])) { |
||||
667 | $parseRef = parse_url($_SERVER['HTTP_REFERER']); |
||||
668 | $parseOri = parse_url($_SERVER['HTTP_ORIGIN']); |
||||
669 | if (!isset($parseOri['host']) || !isset($parseRef['host'])) { |
||||
670 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
671 | if ($print_server) { |
||||
672 | return $_SERVER; |
||||
673 | } else { |
||||
674 | return false; |
||||
675 | } |
||||
676 | } |
||||
677 | if ($parseOri['host'] != $parseRef['host']) { |
||||
678 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
679 | if ($print_server) { |
||||
680 | return $_SERVER; |
||||
681 | } else { |
||||
682 | return false; |
||||
683 | } |
||||
684 | } |
||||
685 | } else { |
||||
686 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
687 | if ($print_server) { |
||||
688 | return $_SERVER; |
||||
689 | } else { |
||||
690 | return false; |
||||
691 | } |
||||
692 | } |
||||
693 | } |
||||
694 | |||||
695 | if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) { |
||||
696 | // may also be using PUT, PATCH, HEAD etc |
||||
697 | header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); |
||||
698 | } |
||||
699 | |||||
700 | if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) { |
||||
701 | header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); |
||||
702 | } else { |
||||
703 | header('Access-Control-Allow-Headers: X-Requested-With'); |
||||
704 | } |
||||
705 | |||||
706 | if (!isset($_SERVER['HTTP_ACCEPT'])) { |
||||
707 | $final = false; |
||||
708 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
709 | } |
||||
710 | /* |
||||
711 | * AJAX request absolutely send http-origin and x-requested-with |
||||
712 | */ |
||||
713 | if (!isset($_SERVER['HTTP_ORIGIN']) && !$xrequested) { |
||||
714 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
715 | $final = false; |
||||
716 | } |
||||
717 | if (!isset($_SERVER['HTTP_REFERER'])) { |
||||
718 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
719 | $final = false; |
||||
720 | } |
||||
721 | if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { |
||||
722 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
723 | $final = false; |
||||
724 | } |
||||
725 | |||||
726 | /* |
||||
727 | * disallow if request content-type is HTML |
||||
728 | */ |
||||
729 | if (isset($_SERVER['HTTP_CONTENT_TYPE']) && !preg_match('/^text\/html/s', $_SERVER['HTTP_CONTENT_TYPE'])) { |
||||
730 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
731 | $final = false; |
||||
732 | } |
||||
733 | if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { |
||||
734 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
735 | $final = false; |
||||
736 | } |
||||
737 | if (!isset($_SERVER['HTTP_USER_AGENT'])) { |
||||
738 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
739 | $final = false; |
||||
740 | } |
||||
741 | if (!self::isLocal()) { |
||||
742 | $_SERVER['PHP_LINE'] = __LINE__; |
||||
743 | $final = $final && isset($_SERVER['UNIQUE_ID']); |
||||
744 | } |
||||
745 | |||||
746 | //var_dump($final); |
||||
747 | //var_dump(isset($_SERVER['UNIQUE_ID'])); |
||||
748 | if (!$final && $print_server) { |
||||
749 | //$_SERVER['PHP_LINE'] = __LINE__; |
||||
750 | //var_dump($_SERVER['PHP_LINE'], $final); |
||||
751 | ksort($_SERVER); |
||||
752 | |||||
753 | return $_SERVER; |
||||
754 | } |
||||
755 | //var_dump($_SERVER['PHP_LINE']); |
||||
756 | if ($final) { |
||||
757 | return true; |
||||
758 | } |
||||
759 | |||||
760 | return false; |
||||
761 | } |
||||
762 | |||||
763 | /** |
||||
764 | * Check if a given ip is in a network. |
||||
765 | * |
||||
766 | * @see https://gist.github.com/ryanwinchester/578c5b50647df3541794 |
||||
767 | * |
||||
768 | * @param string $ip IP to check in IPV4 format eg. 127.0.0.1 |
||||
769 | * @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed |
||||
770 | * |
||||
771 | * @return bool true if the ip is in this range / false if not |
||||
772 | */ |
||||
773 | public static function ip_in_range(string $ip, $range) |
||||
774 | { |
||||
775 | if (false == strpos($range, '/')) { |
||||
0 ignored issues
–
show
|
|||||
776 | $range .= '/32'; |
||||
777 | } |
||||
778 | if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { |
||||
779 | return false; |
||||
780 | } |
||||
781 | |||||
782 | // $range is in IP/CIDR format eg 127.0.0.1/24 |
||||
783 | list($range, $netmask) = explode('/', trim($range), 2); |
||||
784 | //var_dump($netmask); |
||||
785 | |||||
786 | $ip_decimal = ip2long($ip); |
||||
787 | $range_decimal = ip2long($range); |
||||
788 | $wildcard_decimal = pow(2, (32 - $netmask)) - 1; |
||||
789 | $netmask_decimal = ~$wildcard_decimal; |
||||
790 | |||||
791 | return ($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal); |
||||
792 | } |
||||
793 | |||||
794 | public static function ip_in_multirange($ip, array $ranges) |
||||
795 | { |
||||
796 | $in_range = false; |
||||
797 | foreach ($ranges as $range) { |
||||
798 | if (self::ip_in_range($ip, $range)) { |
||||
799 | $in_range = true; |
||||
800 | break; |
||||
801 | } |
||||
802 | } |
||||
803 | |||||
804 | return $in_range; |
||||
805 | } |
||||
806 | |||||
807 | /** |
||||
808 | * Check if request is google. |
||||
809 | * |
||||
810 | * @return bool |
||||
811 | */ |
||||
812 | public static function is_google() |
||||
813 | { |
||||
814 | $file = file(__DIR__ . '/conf/google_ips.txt', FILE_SKIP_EMPTY_LINES); |
||||
815 | $ip = self::getRequestIP(); |
||||
816 | $result = false; |
||||
817 | foreach ($file as $range) { |
||||
818 | if (self::ip_in_range($ip, $range)) { |
||||
819 | $result = true; |
||||
820 | break; |
||||
821 | } |
||||
822 | } |
||||
823 | |||||
824 | return $result; |
||||
825 | } |
||||
826 | |||||
827 | public static function get_client_ip() |
||||
828 | { |
||||
829 | $ipaddress = null; |
||||
830 | if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { |
||||
831 | $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP']; |
||||
832 | } |
||||
833 | if (isset($_SERVER['HTTP_CLIENT_IP'])) { |
||||
834 | $ipaddress = $_SERVER['HTTP_CLIENT_IP']; |
||||
835 | } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { |
||||
836 | $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR']; |
||||
837 | } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) { |
||||
838 | $ipaddress = $_SERVER['HTTP_X_FORWARDED']; |
||||
839 | } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) { |
||||
840 | $ipaddress = $_SERVER['HTTP_FORWARDED_FOR']; |
||||
841 | } elseif (isset($_SERVER['HTTP_FORWARDED'])) { |
||||
842 | $ipaddress = $_SERVER['HTTP_FORWARDED']; |
||||
843 | } elseif (isset($_SERVER['REMOTE_ADDR'])) { |
||||
844 | $ipaddress = $_SERVER['REMOTE_ADDR']; |
||||
845 | } |
||||
846 | |||||
847 | return $ipaddress; |
||||
848 | } |
||||
849 | |||||
850 | public static function _cloudflare_CheckIP($ip) |
||||
851 | { |
||||
852 | $cf_ips = [ |
||||
853 | '199.27.128.0/21', |
||||
854 | '173.245.48.0/20', |
||||
855 | '103.21.244.0/22', |
||||
856 | '103.22.200.0/22', |
||||
857 | '103.31.4.0/22', |
||||
858 | '141.101.64.0/18', |
||||
859 | '108.162.192.0/18', |
||||
860 | '190.93.240.0/20', |
||||
861 | '188.114.96.0/20', |
||||
862 | '197.234.240.0/22', |
||||
863 | '198.41.128.0/17', |
||||
864 | '162.158.0.0/15', |
||||
865 | '104.16.0.0/12', |
||||
866 | ]; |
||||
867 | $is_cf_ip = false; |
||||
868 | foreach ($cf_ips as $cf_ip) { |
||||
869 | if (self::ip_in_range($ip, $cf_ip)) { |
||||
870 | $is_cf_ip = true; |
||||
871 | break; |
||||
872 | } |
||||
873 | } |
||||
874 | |||||
875 | return $is_cf_ip; |
||||
876 | } |
||||
877 | |||||
878 | public static function _cloudflare_Requests_Check() |
||||
879 | { |
||||
880 | $flag = true; |
||||
881 | |||||
882 | if (!isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { |
||||
883 | $flag = false; |
||||
884 | } |
||||
885 | if (!isset($_SERVER['HTTP_CF_IPCOUNTRY'])) { |
||||
886 | $flag = false; |
||||
887 | } |
||||
888 | if (!isset($_SERVER['HTTP_CF_RAY'])) { |
||||
889 | $flag = false; |
||||
890 | } |
||||
891 | if (!isset($_SERVER['HTTP_CF_VISITOR'])) { |
||||
892 | $flag = false; |
||||
893 | } |
||||
894 | |||||
895 | return $flag; |
||||
896 | } |
||||
897 | |||||
898 | public static function isCloudflare() |
||||
899 | { |
||||
900 | $ipCheck = self::_cloudflare_CheckIP($_SERVER['REMOTE_ADDR']); |
||||
901 | $requestCheck = self::_cloudflare_Requests_Check(); |
||||
902 | |||||
903 | return $ipCheck && $requestCheck; |
||||
904 | } |
||||
905 | |||||
906 | // Use when handling ip's |
||||
907 | public static function getRequestIP() |
||||
908 | { |
||||
909 | $check = self::isCloudflare(); |
||||
910 | |||||
911 | if ($check) { |
||||
912 | return $_SERVER['HTTP_CF_CONNECTING_IP']; |
||||
913 | } else { |
||||
914 | return self::get_client_ip(); |
||||
915 | } |
||||
916 | } |
||||
917 | |||||
918 | /** |
||||
919 | * Get Useragent. |
||||
920 | * |
||||
921 | * @return string |
||||
922 | */ |
||||
923 | public static function useragent() |
||||
924 | { |
||||
925 | return $_SERVER['HTTP_USER_AGENT']; |
||||
926 | } |
||||
927 | |||||
928 | public static function print_server() |
||||
929 | { |
||||
930 | return join(PHP_EOL, $_SERVER); |
||||
931 | } |
||||
932 | |||||
933 | /** |
||||
934 | * Get URL from local file |
||||
935 | * |
||||
936 | * @param string|array $path destinations |
||||
937 | * * `array` will be looped, which found first, return them |
||||
938 | * @param boolean $cache |
||||
939 | * @return string if empty == not found |
||||
940 | */ |
||||
941 | public static function get_url_path($path, bool $cache = null) |
||||
942 | { |
||||
943 | $load = function (string $path) use ($cache) { |
||||
944 | if ($realpath = realpath($path)) { |
||||
945 | $f = str_replace(realpath($_SERVER['DOCUMENT_ROOT']), '', $realpath); |
||||
946 | |||||
947 | $ret = self::fixSlash($f); |
||||
948 | if (true === $cache) { |
||||
949 | $ret .= '?cache=' . CONFIG['cache']['key']; |
||||
950 | } |
||||
951 | |||||
952 | return $ret; |
||||
953 | } |
||||
954 | }; |
||||
955 | if (is_string($path)) { |
||||
956 | if ($load($path)) { |
||||
957 | return $load($path); |
||||
958 | } |
||||
959 | } else if (is_array($path)) { |
||||
0 ignored issues
–
show
|
|||||
960 | foreach ($path as $dest) { |
||||
961 | if ($load($dest)) { |
||||
962 | return $load($dest); |
||||
963 | break; |
||||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other ![]() |
|||||
964 | } |
||||
965 | } |
||||
966 | } |
||||
967 | |||||
968 | return ''; |
||||
969 | } |
||||
970 | |||||
971 | public static function ddos_key() |
||||
972 | { |
||||
973 | $secure_cookie_label = 'DDOS'; |
||||
974 | if (!isset($_SERVER['HTTP_USER_AGENT'])) { |
||||
975 | exit(\JSON\json::json(['error' => true, 'message' => 'BOT Detected'])); |
||||
0 ignored issues
–
show
Are you sure the usage of
JSON\json::json(array('e...ge' => 'BOT Detected')) targeting JSON\json::json() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
976 | } |
||||
977 | //$secure_cookie_label .= date('Ymd'); |
||||
978 | $secure_cookie_label .= $_SERVER['HTTP_USER_AGENT']; |
||||
979 | $secure_cookie_label = md5($secure_cookie_label); |
||||
980 | |||||
981 | return $secure_cookie_label; |
||||
982 | } |
||||
983 | |||||
984 | /** |
||||
985 | * Minify HTML. |
||||
986 | * |
||||
987 | * @param string $buffer |
||||
988 | */ |
||||
989 | public static function sanitize_output($buffer) |
||||
990 | { |
||||
991 | if (!is_string($buffer)) { |
||||
0 ignored issues
–
show
|
|||||
992 | return $buffer; |
||||
993 | } |
||||
994 | $search = [ |
||||
995 | '/\>[^\S ]+/s', // strip whitespaces after tags, except space |
||||
996 | '/[^\S ]+\</s', // strip whitespaces before tags, except space |
||||
997 | '/(\s)+/s', // shorten multiple whitespace sequences |
||||
998 | '/<!--(.|\s)*?-->/', // Remove HTML comments |
||||
999 | ]; |
||||
1000 | |||||
1001 | $replace = [ |
||||
1002 | '>', |
||||
1003 | '<', |
||||
1004 | '\\1', |
||||
1005 | '', |
||||
1006 | ]; |
||||
1007 | |||||
1008 | $buffer = preg_replace($search, $replace, $buffer); |
||||
1009 | |||||
1010 | return $buffer; |
||||
1011 | } |
||||
1012 | |||||
1013 | public static function trycatch($try) |
||||
1014 | { |
||||
1015 | try { |
||||
1016 | if (is_callable($try)) { |
||||
1017 | call_user_func($try); |
||||
1018 | } |
||||
1019 | } catch (\Throwable $th) { |
||||
1020 | if (ob_get_level()) { |
||||
1021 | ob_end_clean(); |
||||
1022 | ob_start(); |
||||
1023 | } |
||||
1024 | $title = 'ERROR'; |
||||
1025 | $desc = $th->getMessage(); |
||||
1026 | if (isset($_REQUEST['dmp']) || 'development' == \MVC\router::get_env()) { |
||||
1027 | $desc .= '<pre style="word-wrap: break-word;">' . nl2br(json_encode($th->getTrace(), JSON_UNESCAPED_UNICODE || JSON_PRETTY_PRINT || JSON_UNESCAPED_SLASHES)) . '</pre>'; |
||||
0 ignored issues
–
show
MVC\JSON_UNESCAPED_UNICO...\JSON_UNESCAPED_SLASHES of type boolean is incompatible with the type integer expected by parameter $flags of json_encode() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
1028 | } |
||||
1029 | include __DIR__ . '/themes/alert/content.php'; |
||||
1030 | exit; |
||||
0 ignored issues
–
show
|
|||||
1031 | } finally { |
||||
1032 | } |
||||
1033 | } |
||||
1034 | } |
||||
1035 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.