Issues (994)

src/shim/bootstrap.php (28 issues)

1
<?php
2
3
/**
4
 * Include file if exists.
5
 *
6
 * @return include|false
0 ignored issues
show
The type include 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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
 */
8
function inc(string $file)
9
{
10
  return file_exists($file) ? include $file : false;
11
}
12
13
/**
14
 * Sort array key ascending multidimensional supported.
15
 *
16
 * @return array
17
 */
18
function sort_iterable(array $arrayObj)
19
{
20
  $arrayObj = array_map(function ($object) {
21
    if (\ArrayHelper\helper::is_iterable($object)) {
22
      $object = sort_iterable($object);
23
    }
24
25
    return $object;
26
  }, $arrayObj);
27
  ksort($arrayObj);
28
29
  return $arrayObj;
30
}
31
32
/**
33
 * Exit var_dump with text/plain header.
34
 *
35
 * @return void
36
 */
37
function ev()
38
{
39
  $args = func_get_args();
40
  if (1 == count($args)) {
41
    $args = $args[0];
42
  }
43
  if (!headers_sent()) {
44
    header('Content-Type: text/plain; charset=utf-8');
45
  }
46
  exit(var_dump($args));
0 ignored issues
show
Are you sure the usage of var_dump($args) is correct as it 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 getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Security Debugging Code introduced by
var_dump($args) looks like debug code. Are you sure you do not want to remove it?
Loading history...
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
47
}
48
49
/**
50
 * Var Dump with removing all previous obstacles.
51
 *
52
 * @return void
53
 */
54
function vd()
55
{
56
  $args = func_get_args();
57
  if (1 == count($args)) {
58
    $args = $args[0];
59
  }
60
  if (ob_get_level()) {
61
    ob_end_clean();
62
  }
63
  var_dump($args);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($args) looks like debug code. Are you sure you do not want to remove it?
Loading history...
64
  exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
65
}
66
67
/**
68
 * Exit var_dump with JSON header.
69
 *
70
 * @param [type] ...$a
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
71
 *
72
 * @return void
73
 */
74
function evj(...$a)
75
{
76
  \JSON\json::json($a);
77
  exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
78
}
79
80
/**
81
 * Fastest Unique ID Generator.
82
 *
83
 * @param int $length default 5
84
 */
85
function uid(int $length = 5)
86
{
87
  return bin2hex(openssl_random_pseudo_bytes($length / 2));
88
}
89
90
/**
91
 * Clean string from multiple whitespaces.
92
 *
93
 * @param string $string
94
 *
95
 * @return string
96
 */
97
function clean_string($string)
98
{
99
  $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
100
101
  return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
102
}
103
104
/**
105
 * Local path to url path conversion.
106
 *
107
 * @param string|array $locations
108
 */
109
function get_urlpath($locations)
110
{
111
  /**
112
   * @var string|null $get
113
   */
114
  $get = function (string $location) {
115
    if (file_exists($location)) {
116
      return \MVC\helper::get_url_path($location, true);
117
    }
118
119
    return null;
120
  };
121
  if (is_string($locations)) {
122
    return $get($locations);
123
  } elseif (\ArrayHelper\helper::is_iterable($locations)) {
124
    foreach ($locations as $location) {
125
      $result = $get($location);
126
      if ($result) {
127
        return $result;
128
        break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

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 case statements, you can safely mark this issue as a false-positive.

Loading history...
129
      }
130
    }
131
  }
132
133
  return null;
134
}
135
136
/**
137
 * Include asset with fallback and callback.
138
 * * if found automatically call include().
139
 *
140
 * @author Dimas Lanjaka <[email protected]>
141
 *
142
 * @param string        $fn       first file to check
143
 * @param string        $fn2      fallback file to check
144
 * @param function|null $callback if not exists both, shoul we calling the callback
145
 *
146
 * @return void always void
147
 */
148
function include_asset($fn, $fn2 = null, $callback = null)
149
{
150
  if (file_exists($fn)) {
151
    include $fn;
152
  } elseif ($fn2 && file_exists($fn2)) {
153
    include $fn2;
154
  } elseif (is_callable($callback)) {
155
    call_user_func($callback, $fn);
0 ignored issues
show
It seems like $callback can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, 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 ignore-type  annotation

155
    call_user_func(/** @scrutinizer ignore-type */ $callback, $fn);
Loading history...
156
  }
157
}
158
159
/**
160
 * Create <pre/> element from func_get_args().
161
 *
162
 * @return void
163
 */
164
function pre()
165
{
166
  $obj = func_get_args();
167
  echo '<pre style="word-wrap: break-word;">';
168
  if (count($obj) > 1) {
169
    foreach ($obj as $objek) {
170
      \JSON\json::json($objek, false, true);
171
    }
172
  } else {
173
    \JSON\json::json($obj[0], false, true);
174
  }
175
  echo '</pre>';
176
}
177
178
/**
179
 * Create <pre/> element from arguments
180
 *
181
 * @param mixed $obj
182
 * @return void
183
 */
184
function pretext($obj)
185
{
186
  echo '<pre style="word-wrap: break-word;">';
187
  if (is_countable($obj)) {
188
    if (count($obj) > 1) {
189
      foreach ($obj as $objek) {
190
        \JSON\json::json($objek, false, true);
191
      }
192
    } else {
193
      \JSON\json::json($obj[0], false, true);
194
    }
195
  } else {
196
    \JSON\json::json($obj, false, true);
197
  }
198
  echo '</pre>';
199
}
200
201
/**
202
 * var_dump in <pre/>.
203
 *
204
 * @return void
205
 */
206
function predump()
207
{
208
  $obj = func_get_args();
209
  echo '<pre style="word-wrap: break-word;">';
210
  if (count($obj) > 1) {
211
    foreach ($obj as $objek) {
212
      var_dump($objek);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($objek) looks like debug code. Are you sure you do not want to remove it?
Loading history...
213
    }
214
  } else {
215
    var_dump($obj[0]);
216
  }
217
  echo '</pre>';
218
}
219
220
/**
221
 * Exit JSON.
222
 *
223
 * @param mixed $result
224
 *
225
 * @return void
226
 */
227
function e()
228
{
229
  $results = func_get_args();
230
  if (count($results) > 1) {
231
    foreach ($results as $check) {
232
      if (is_string($check) && \JSON\json::is_json($check)) {
233
        $check = json_decode($check);
0 ignored issues
show
The assignment to $check is dead and can be removed.
Loading history...
234
      }
235
    }
236
  } else {
237
    $results = $results[0];
238
  }
239
  \JSON\json::json($results);
240
  exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
241
}
242
243
if (!function_exists('is_json')) {
244
  /**
245
   * Check is json string.
246
   *
247
   * @return bool
248
   */
249
  function is_json(string $string)
250
  {
251
    return \JSON\json::is_json($string);
252
  }
253
}
254
255
/**
256
 * Header redirect.
257
 */
258
function redirect(string $url, bool $exit = true)
259
{
260
  header("Location: $url");
261
  if ($exit) {
262
    exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
263
  }
264
}
265
266
/**
267
 * Header redirect advance.
268
 */
269
function safe_redirect(string $url, bool $exit = true)
270
{
271
  if (!headers_sent()) {
272
    return redirect($url, $exit);
0 ignored issues
show
Are you sure the usage of redirect($url, $exit) is correct as it 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 getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
273
  } else {
274
    echo '<script>location.href = `' . $url . '`;</script>';
275
  }
276
  if ($exit) {
277
    exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
278
  }
279
}
280
281
/**
282
 * Get latest file from folder.
283
 *
284
 * @param array $path             Folder path array list
285
 * @param bool  $return_timestamp false return filename
286
 *                                ```php
287
 *                                latestFile([__DIR__ . '/src/MVC/', __DIR__ . '/libs/', __DIR__ . '/views/'])
288
 *                                ```
289
 */
290
function latestFile(array $path, bool $return_timestamp = true)
291
{
292
  $timestamp = 0;
293
  $file = '';
294
295
  foreach ($path as $str_path) {
296
    if (!is_dir($str_path)) {
297
      continue;
298
    }
299
    $cls_rii = new \RecursiveIteratorIterator(
300
      new \RecursiveDirectoryIterator($str_path),
301
      \RecursiveIteratorIterator::CHILD_FIRST
302
    );
303
304
    $ary_files = [];
305
306
    foreach ($cls_rii as $str_fullfilename => $cls_spl) {
307
      if ($cls_spl->isFile()) {
308
        $ary_files[] = $str_fullfilename;
309
      }
310
    }
311
312
    $ary_files = array_combine(
313
      $ary_files,
314
      array_map('filemtime', $ary_files)
315
    );
316
317
    arsort($ary_files);
318
    $time = $ary_files[key($ary_files)];
319
    if ($time > $timestamp) {
320
      $file = key($ary_files);
321
      $timestamp = $time;
322
    }
323
  }
324
  if ($return_timestamp) {
325
    return $timestamp;
326
  } else {
327
    return $file;
328
  }
329
  //echo "file:" . $file . "\n";
330
  //echo "time:" . $time;
331
}
332
333
/**
334
 * Disable direct access static php.
335
 */
336
function disable_direct_access_php(string $file)
337
{
338
  if (!file_exists(dirname($file) . '/.htaccess')) {
339
    \Filemanager\file::file(dirname($file) . '/.htaccess', 'RewriteEngine On
0 ignored issues
show
'RewriteEngine On Rewr...192.168.0.1 </Files>' of type 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 ignore-type  annotation

339
    \Filemanager\file::file(dirname($file) . '/.htaccess', /** @scrutinizer ignore-type */ 'RewriteEngine On
Loading history...
340
		RewriteRule ^.*\.php$ - [F,L,NC]
341
		<Files (file|class)\.php>
342
		order allow,deny
343
		deny from all
344
		allow from 127.0.0.1
345
		allow from 192.168.0.1
346
		</Files>', true);
347
  }
348
}
349
350
/**
351
 * Create nested folder recursively.
352
 *
353
 * @return string $dir
354
 */
355
function resolve_dir(string $dir)
356
{
357
  $dir = normalize_path($dir);
358
  recursive_mkdir($dir);
359
360
  return $dir;
361
}
362
363
/**
364
 * Disable output buffering.
365
 *
366
 * @return void
367
 */
368
function disable_buffering()
369
{
370
  // Turn off output buffering
371
  ini_set('output_buffering', 'off');
372
  // Turn off PHP output compression
373
  ini_set('zlib.output_compression', false);
0 ignored issues
show
false of type false is incompatible with the type string expected by parameter $value of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

373
  ini_set('zlib.output_compression', /** @scrutinizer ignore-type */ false);
Loading history...
374
375
  //Flush (send) the output buffer and turn off output buffering
376
  while (@ob_end_flush());
377
378
  // Implicitly flush the buffer(s)
379
  ini_set('implicit_flush', true);
0 ignored issues
show
true of type true is incompatible with the type string expected by parameter $value of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

379
  ini_set('implicit_flush', /** @scrutinizer ignore-type */ true);
Loading history...
380
  ob_implicit_flush(true);
381
}
382
383
/**
384
 * Disable user abort.
385
 *
386
 * @return ignore_user_abort|null
0 ignored issues
show
The type ignore_user_abort 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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
387
 */
388
function disable_abort(bool $abort = false)
389
{
390
  if (function_exists('ignore_user_abort')) {
391
    return ignore_user_abort($abort);
0 ignored issues
show
Bug Best Practice introduced by
The expression return ignore_user_abort($abort) returns the type integer which is incompatible with the documented return type ignore_user_abort|null.
Loading history...
392
  }
393
}
394
395
function is_aborted()
396
{
397
  return CONNECTION_NORMAL != connection_status();
398
}
399
400
/**
401
 * set Limit execution.
402
 *
403
 * @return set_time_limit|null
0 ignored issues
show
The type set_time_limit 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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
404
 */
405
function set_limit(int $secs = 0)
406
{
407
  if (function_exists('set_time_limit')) {
408
    return set_time_limit($secs);
0 ignored issues
show
Bug Best Practice introduced by
The expression return set_time_limit($secs) returns the type boolean which is incompatible with the documented return type null|set_time_limit.
Loading history...
409
  }
410
}
411
412
/**
413
 * Create dir recursively.
414
 *
415
 * @param int  $permissions
416
 * @param bool $recursive
417
 */
418
function recursive_mkdir(string $dest, $permissions = 0755, $recursive = true)
419
{
420
  if (!is_dir(dirname($dest))) {
421
    recursive_mkdir(dirname($dest), $permissions, $recursive);
422
  }
423
  if (!file_exists($dest)) {
424
    try {
425
      mkdir($dest, $permissions, $recursive);
426
427
      return true;
428
    } catch (\Throwable $th) {
429
      return false;
430
    }
431
  } else {
432
    return true;
433
  }
434
}
435
436
/**
437
 * Resolve file. (create if not exists)
438
 *
439
 * @param string $file
440
 * @param string $content
441
 * @return string
442
 */
443
function resolve_file(string $file, string $content = '')
444
{
445
  if (!is_dir(dirname($file))) {
446
    resolve_dir(dirname($file));
447
  }
448
449
  if (!file_exists($file)) {
450
    file_put_contents($file, $content);
451
  }
452
453
  return $file;
454
}
455
456
/**
457
 * Convert Windows path to UNIX path.
458
 *
459
 * @return string
460
 */
461
function normalize_path(string $path)
462
{
463
  $path = str_replace('\\', '/', $path);
464
  $path = preg_replace('|(?<=.)/+|', '/', $path);
465
  $path = preg_replace('/\/{2,99}/s', '/', $path);
466
  if (':' === substr($path, 1, 1)) {
467
    $path = ucfirst($path);
468
  }
469
470
  return $path;
471
}
472
473
/**
474
 * Remove root from path.
475
 */
476
function remove_root(string $path)
477
{
478
  $path = normalize_path($path);
479
  $path = str_replace(normalize_path(ROOT), '', $path);
480
481
  return $path;
482
}
483
484
/**
485
 * Shell runner.
486
 *
487
 * @return string|null
488
 */
489
function shell(string $command)
490
{
491
  $output = null;
492
  if (function_exists('shell_exec')) {
493
    $output = shell_exec($command);
494
  } elseif (function_exists('exec')) {
495
    exec($command, $output);
496
  }
497
498
  return \ArrayHelper\helper::is_iterable($output) ? \JSON\json::json($output, false, false) : $output;
499
}
500
501
/**
502
 * Check shell can be executed.
503
 *
504
 * @return string|null
505
 */
506
function shell_check()
507
{
508
  if (function_exists('shell_exec')) {
509
    return 'shell_exec';
510
  } elseif (function_exists('exec')) {
511
    return 'exec';
512
  } else {
513
    return null;
514
  }
515
}
516
517
function shell_required($callback)
0 ignored issues
show
The parameter $callback is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

517
function shell_required(/** @scrutinizer ignore-unused */ $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
518
{
519
  $result = [];
520
  if ('string' != gettype(shell_check()) || !\MVC\helper::env('dev')) {
521
    $result = ['error' => true, 'message' => 'Cannot execute command here environtment(' . \MVC\helper::env('dev') . ') command(' . gettype(shell_check()) . ')', 'title' => 'Cannot Access This Page'];
522
  }
523
  if (!empty($result)) {
524
    if (headers_sent()) {
525
      exit('<div class="alert alert-danger">
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
526
      <span class="alert-title"> ' . $result['title'] . ' </span>
527
      </div>');
528
    }
529
  }
530
}
531
532
/**
533
 * ```php
534
 * // callback if function
535
 * call_user_func($callback, $path)
536
 * ```
537
 * Read file contents.
538
 *
539
 * @author Dimas Lanjaka <[email protected]>
540
 *
541
 * @param mixed $callback if null not exist return this callback
542
 *
543
 * @return string|null NULL if not exists
544
 */
545
function read_file(string $path, $callback = null)
546
{
547
  if (file_exists($path) && is_readable($path)) {
548
    if (function_exists('file_get_contents')) {
549
      return file_get_contents($path);
550
    } else {
551
      $handle = fopen($path, 'r');
552
      $contents = fread($handle, filesize($path));
553
      fclose($handle);
554
555
      return $contents;
556
    }
557
  }
558
  if (is_callable($callback)) {
559
    return call_user_func($callback, $path);
0 ignored issues
show
It seems like $callback can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, 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 ignore-type  annotation

559
    return call_user_func(/** @scrutinizer ignore-type */ $callback, $path);
Loading history...
560
  }
561
562
  return $callback;
563
}
564
565
function write_file(string $path, $content, bool $force = false)
566
{
567
  resolve_dir(dirname($path));
568
  if (\ArrayHelper\helper::is_iterable($content)) {
569
    $content = json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
570
  }
571
  if ($force || !file_exists($path)) {
572
    if (!function_exists('file_put_contents')) {
573
      $fh = fopen($path, 'wa+');
574
      fwrite($path, $content);
0 ignored issues
show
$path of type string is incompatible with the type resource expected by parameter $stream of fwrite(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

574
      fwrite(/** @scrutinizer ignore-type */ $path, $content);
Loading history...
575
      fclose($fh);
576
    } else {
577
      file_put_contents($path, $content);
578
    }
579
  }
580
}
581
582
function htmlcomment()
583
{
584
  return '<comment style="display:none"> ' . json_encode(func_get_args(), JSON_PRETTY_PRINT) . ' </comment>';
585
}
586
587
function parse_newline(string $str)
588
{
589
  $str = str_replace("\r", '', $str);
590
  $parsed = explode("\n", $str);
591
  if ($parsed) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsed of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
592
    return $parsed;
593
  }
594
595
  return [];
596
}
597
598
/**
599
 * Get Output Buffer Content And Re-construct current output buffer.
600
 *
601
 * @return string|false
602
 */
603
function ob_get()
604
{
605
  $content = ob_get_clean();
606
  ob_end_clean();
607
  ob_start();
608
609
  return $content;
610
}
611
612
$imageCache = null;
613
function imgCDN(string $url)
614
{
615
  global $imageCache;
616
  if (!$imageCache) {
617
    $imageCache = new \img\cache();
618
  }
619
  $imageCache->url2cache($url);
620
}
621
622
/**
623
 * htaccess generator.
624
 *
625
 * @param bool $deny        default deny access. default (true)
626
 * @param bool $DirectPHP   allow direct php access. default (false)
627
 * @param bool $allowStatic allow static files access. default (true)
628
 */
629
function htaccess($deny = true, $DirectPHP = false, $allowStatic = true)
630
{
631
  $ht = '';
632
  if ($deny) {
633
    $ht .= 'deny from all';
634
  }
635
  if (!$DirectPHP) {
636
    $ht .= 'RewriteEngine On
637
    RewriteRule ^.*\.php$ - [F,L,NC]
638
    <Files (file|class)\.php>
639
      order allow,deny
640
      deny from all
641
      allow from 127.0.0.1
642
      allow from 192.168.0.1
643
    </Files>';
644
  }
645
  if ($allowStatic) {
646
    $ht .= '<Files ~ "\.(css|js|png|jpg|svg|jpeg|ico|gif)$">
647
  Allow from all
648
</Files>';
649
  }
650
651
  return $ht;
652
}
653
654
/**
655
 * Is valid email ?
656
 *
657
 * @param string $email
658
 *
659
 * @return bool
660
 */
661
function is_email($email)
662
{
663
  return filter_var($email, FILTER_VALIDATE_EMAIL);
664
}
665
666
/**
667
 * Is valid url ?
668
 *
669
 * @param string $url
670
 *
671
 * @return bool
672
 */
673
function is_url($url)
674
{
675
  return filter_var($url, FILTER_VALIDATE_URL);
676
}
677
678
include __DIR__ . '/../MVC/themes/assets/partial/fab.php';
679