Test Failed
Branch main (64d39c)
by Dimitri
02:51
created

cookie()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 4
dl 0
loc 13
rs 10
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
use BlitzPHP\Cli\Console\Console;
0 ignored issues
show
Bug introduced by
The type BlitzPHP\Cli\Console\Console 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...
13
use BlitzPHP\Config\Config;
14
use BlitzPHP\Container\Services;
15
use BlitzPHP\Contracts\Database\ConnectionInterface;
16
use BlitzPHP\Contracts\Session\CookieInterface;
17
use BlitzPHP\Contracts\Session\CookieManagerInterface;
18
use BlitzPHP\Exceptions\PageNotFoundException;
19
use BlitzPHP\Http\Redirection;
20
use BlitzPHP\Http\ServerRequest;
21
use BlitzPHP\Http\Uri;
22
use BlitzPHP\Loader\Load;
23
use BlitzPHP\Session\Store;
24
use BlitzPHP\Utilities\Helpers;
25
use BlitzPHP\Utilities\Iterable\Collection;
26
use BlitzPHP\Utilities\Support\Invader;
27
28
// ================================= FONCTIONS UTIILITAIRES ESSENTIELLES ================================= //
29
30
if (! function_exists('env')) {
31
    /**
32
     * Obtient une variable d'environnement à partir des sources disponibles et fournit une émulation
33
     * pour les variables d'environnement non prises en charge ou incohérentes
34
     *
35
     * @param string     $key     Nom de la variable d'environnement
36
     * @param mixed|null $default
37
     *
38
     * @return string Paramétrage des variables d'environnement.
39
     */
40
    function env(string $key, $default = null)
41
    {
42
        return Helpers::env($key, $default);
43
    }
44
}
45
46
if (! function_exists('helper')) {
47
    /**
48
     * Charge un fichier d'aide en mémoire. Prend en charge les assistants d'espace de noms,
49
     * à la fois dans et hors du répertoire 'helpers' d'un répertoire à espace de noms.
50
     *
51
     * Chargera TOUS les helpers du nom correspondant, dans l'ordre suivant :
52
     *   1. app/Helpers
53
     *   2. {namespace}/Helpers
54
     *   3. system/Helpers
55
     */
56
    function helper(array|string $filenames)
57
    {
58
        Load::helper($filenames);
59
    }
60
}
61
62
if (! function_exists('model')) {
63
    /**
64
     * Simple maniere d'obtenir un modele.
65
     *
66
     * @template T
67
     *
68
     * @param array<class-string<T>>|class-string<T> $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<T>>|class-string<T> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<T>>|class-string<T>.
Loading history...
69
     *
70
     * @return T
71
     */
72
    function model(array|string $name, ?ConnectionInterface &$conn = null)
73
    {
74
        return Load::model($name, $conn);
0 ignored issues
show
Bug Best Practice introduced by
The expression return BlitzPHP\Loader\Load::model($name, $conn) also could return the type array<mixed,object> which is incompatible with the documented return type T.
Loading history...
75
    }
76
}
77
78
if (! function_exists('service')) {
79
    /**
80
     * Permet un accès plus propre au fichier de configuration des services.
81
     * Renvoie toujours une instance SHARED de la classe, donc l'appel de la fonction plusieurs fois renvera toujours la même instance.
82
     *
83
     * Ceux-ci sont égaux :
84
     *  - $cache = service('cache')
85
     *  - $cache = \BlitzPHP\Container\Services::cache();
86
     *
87
     * @template T
88
     *
89
     * @param class-string<T> $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
90
     *
91
     * @return object|T
92
     */
93
    function service(string $name, ...$params)
94
    {
95
        return Services::$name(...$params);
96
    }
97
}
98
99
if (! function_exists('single_service')) {
100
    /**
101
     * Autoriser l'accès propre à un service.
102
     * Renvoie toujours une nouvelle instance de la classe.
103
     *
104
     * @template T
105
     *
106
     * @param class-string<T> $name
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
107
     *
108
     * @return object|T
109
     */
110
    function single_service(string $name, ...$params)
111
    {
112
        // Assurez-vous qu'il ne s'agit PAS d'une instance partagée
113
        $params[] = false;
114
115
        return Services::$name(...$params);
116
    }
117
}
118
119
if (! function_exists('show404')) {
120
    /**
121
     * Afficher une page 404 introuvable dans le navigateur
122
     */
123
    function show404(string $message = 'The page you requested was not found.', string $heading = 'Page Not Found', array $params = [])
124
    {
125
        throw PageNotFoundException::pageNotFound($message);
126
    }
127
}
128
129
if (! function_exists('command')) {
130
    /**
131
     * Exécute une seule commande.
132
     * Entrée attendue dans une seule chaîne comme celle qui serait utilisée sur la ligne de commande elle-même :
133
     *
134
     *  > command('migrate:create SomeMigration');
135
     *
136
     * @see https://github.com/codeigniter4/CodeIgniter4/blob/b56c85c9d09fd3b34893220b2221ed27f8d508e6/system/Common.php#L133
137
     *
138
     * @return false|string
139
     */
140
    function command(string $command)
141
    {
142
        $regexString = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
143
        $regexQuoted = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
144
145
        $args   = [];
146
        $length = strlen($command);
147
        $cursor = 0;
148
149
        /**
150
         * Adopté de `StringInput::tokenize()` de Symfony avec quelques modifications.
151
         *
152
         * @see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Console/Input/StringInput.php
153
         */
154
        while ($cursor < $length) {
155
            if (preg_match('/\s+/A', $command, $match, 0, $cursor)) {
156
                // Rien a faire
157
            } elseif (preg_match('/' . $regexQuoted . '/A', $command, $match, 0, $cursor)) {
158
                $args[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
159
            } elseif (preg_match('/' . $regexString . '/A', $command, $match, 0, $cursor)) {
160
                $args[] = stripcslashes($match[1]);
161
            } else {
162
                // @codeCoverageIgnoreStart
163
                throw new InvalidArgumentException(sprintf(
164
                    'Impossible d\'analyser l\'entrée à proximité "... %s ...".',
165
                    substr($command, $cursor, 10)
166
                ));
167
                // @codeCoverageIgnoreEnd
168
            }
169
170
            $cursor += strlen($match[0]);
171
        }
172
173
        $command = array_shift($args);
174
        $params  = [];
175
176
        foreach ($args as $key => $arg) {
177
            if (mb_strpos($arg, '--') !== false) {
178
                unset($args[$key]);
179
                [$arg, $v]          = explode('=', $arg) + [1 => true];
180
                $params[trim($arg)] = is_string($v) ? trim($v) : $v;
181
            }
182
        }
183
184
        ob_start();
185
        Console::call($command, $args, $params);
186
187
        return ob_get_clean();
188
    }
189
}
190
191
if (! function_exists('config')) {
192
    /**
193
     * GET/SET App config
194
     *
195
     * @param mixed|null $default
196
     *
197
     * @return Config|mixed|void
198
     */
199
    function config(null|array|string $key = null, $default = null)
200
    {
201
        $config = Services::config();
202
203
        if (null === $key) {
204
            return $config;
205
        }
206
207
        if (is_string($key)) {
0 ignored issues
show
introduced by
The condition is_string($key) is always false.
Loading history...
208
            return $config->get($key, $default);
209
        }
210
211
        foreach ($key as $k => $v) {
212
            if (is_string($k)) {
213
                $config->set($k, $v);
214
            }
215
        }
216
    }
217
}
218
219
if (! function_exists('logger')) {
220
    /**
221
     * Une méthode de commodité pour les événements de journalisation via le système Log.
222
     *
223
     * Les niveaux de journal autorisés sont :
224
     *  - emergency
225
     *  - alert
226
     *  - critical
227
     *  - error
228
     *  - warning
229
     *  - notice
230
     *  - info
231
     *  - debug
232
     *
233
     * @param int|string $level
234
     *
235
     * @return \BlitzPHP\Debug\Logger|void
236
     */
237
    function logger($level = null, ?string $message = null, array $context = [])
238
    {
239
        $logger = Services::logger();
240
241
        if (empty($level) || empty($message)) {
242
            return $logger;
243
        }
244
245
        $logger->log($level, $message, $context);
246
    }
247
}
248
249
if (! function_exists('cache')) {
250
    /**
251
     * Une méthode pratique qui donne accès au cache
252
     * objet. Si aucun paramètre n'est fourni, renverra l'objet,
253
     * sinon, tentera de renvoyer la valeur mise en cache.
254
     *
255
     * Exemples:
256
     *    cache()->set('foo', 'bar'); ou cache('foo', 'bar');
257
     *    $foo = cache('bar');
258
     *
259
     * @param mixed|null $value
260
     *
261
     * @return \BlitzPHP\Cache\Cache|bool|mixed
262
     */
263
    function cache(?string $key = null, $value = null)
264
    {
265
        $cache = Services::cache();
266
267
        if (empty($key)) {
268
            return $cache;
269
        }
270
271
        if (empty($value)) {
272
            return $cache->get($key);
273
        }
274
275
        return $cache->set($key, $value);
276
    }
277
}
278
279
if (! function_exists('cookie')) {
280
    /**
281
     * Une méthode pratique qui donne accès à l'objet cookie.
282
     * Si aucun paramètre n'est fourni, renverra l'objet,
283
     * sinon, tentera de renvoyer la valeur du cookie.
284
     *
285
     * Exemples:
286
     *    cookie()->make('foo', 'bar'); ou cookie('foo', 'bar');
287
     *    $foo = cookie('bar')
288
     *
289
     * @return CookieInterface|CookieManagerInterface|null
290
     */
291
    function cookie(?string $name = null, null|array|string $value = null, int $minutes = 0, array $options = [])
292
    {
293
        $cookie = Services::cookie();
294
295
        if (null === $name) {
296
            return $cookie;
297
        }
298
299
        if (null === $value) {
300
            return $cookie->get($name);
301
        }
302
303
        return $cookie->make($name, $value, $minutes, $options);
304
    }
305
}
306
307
if (! function_exists('session')) {
308
    /**
309
     * Une méthode pratique pour accéder à l'instance de session, ou un élément qui a été défini dans la session.
310
     *
311
     * Exemples:
312
     *    session()->set('foo', 'bar');
313
     *    $foo = session('bar');
314
     *
315
     * @return array|bool|float|int|object|Store|string|null
316
     */
317
    function session(?string $val = null)
318
    {
319
        $session = Services::session();
320
321
        // Vous retournez un seul element ?
322
        if (is_string($val)) {
323
            return $session->get($val);
324
        }
325
326
        return $session;
327
    }
328
}
329
330
// =========================== FONCTIONS DE PREVENTION D'ATTAQUE =========================== //
331
332
if (! function_exists('esc')) {
333
    /**
334
     * Effectue un simple échappement automatique des données pour des raisons de sécurité.
335
     * Pourrait envisager de rendre cela plus complexe à une date ultérieure.
336
     *
337
     * Si $data est une chaîne, il suffit alors de l'échapper et de la renvoyer.
338
     * Si $data est un tableau, alors il boucle dessus, s'échappant de chaque
339
     * 'valeur' des paires clé/valeur.
340
     *
341
     * Valeurs de contexte valides : html, js, css, url, attr, raw, null
342
     *
343
     * @param array|string $data
344
     *
345
     * @return array|string
346
     *
347
     * @throws InvalidArgumentException
348
     */
349
    function esc($data, ?string $context = 'html', ?string $encoding = null)
350
    {
351
        if (class_exists('\Laminas\Escaper\Escaper')) {
352
            return Helpers::esc($data, $context, $encoding);
353
        }
354
355
        return h($data, true, $encoding);
356
    }
357
}
358
359
if (! function_exists('h')) {
360
    /**
361
     * Méthode pratique pour htmlspecialchars.
362
     *
363
     * @param mixed       $text    Texte à envelopper dans htmlspecialchars. Fonctionne également avec des tableaux et des objets.
364
     *                             Les tableaux seront mappés et tous leurs éléments seront échappés. Les objets seront transtypés s'ils
365
     *                             implémenter une méthode `__toString`. Sinon, le nom de la classe sera utilisé.
366
     *                             Les autres types de scalaires seront renvoyés tels quels.
367
     * @param bool        $double  Encodez les entités html existantes.
368
     * @param string|null $charset Jeu de caractères à utiliser lors de l'échappement. La valeur par défaut est la valeur de configuration dans `mb_internal_encoding()` ou 'UTF-8'.
369
     *
370
     * @return mixed Texte enveloppé.
371
     */
372
    function h($text, bool $double = true, ?string $charset = null)
373
    {
374
        return Helpers::h($text, $double, $charset);
375
    }
376
}
377
378
if (! function_exists('purify')) {
379
    /**
380
     * Purifiez l'entrée à l'aide de la classe autonome HTMLPurifier.
381
     * Utilisez facilement plusieurs configurations de purificateur.
382
     *
383
     * @param string|string[] $dirty_html
384
     * @param false|string    $config
385
     *
386
     * @return string|string[]
387
     */
388
    function purify($dirty_html, $config = false)
389
    {
390
        return Helpers::purify($dirty_html, $config);
391
    }
392
}
393
394
if (! function_exists('remove_invisible_characters')) {
395
    /**
396
     * Supprimer les caractères invisibles
397
     *
398
     * Cela empêche de prendre en sandwich des caractères nuls
399
     * entre les caractères ascii, comme Java\0script.
400
     */
401
    function remove_invisible_characters(string $str, bool $url_encoded = true): string
402
    {
403
        return Helpers::removeInvisibleCharacters($str, $url_encoded);
404
    }
405
}
406
407
if (! function_exists('stringify_attributes')) {
408
    /**
409
     * Chaîner les attributs à utiliser dans les balises HTML.
410
     *
411
     * @param array|object|string $attributes
412
     */
413
    function stringify_attributes($attributes, bool $js = false): string
414
    {
415
        return Helpers::stringifyAttributes($attributes, $js);
416
    }
417
}
418
419
// ================================= FONCTIONS D'ENVIRONNEMENT D'EXECUTION ================================= //
420
421
if (! function_exists('environment')) {
422
    /**
423
     * Renvoi l'environnement d'execution actuel ou determine si on est dans un environnement specifie
424
     *
425
     * @return bool|string
426
     */
427
    function environment(null|array|string $env)
428
    {
429
        $current = env('ENVIRONMENT');
430
        if (empty($current) || $current === 'auto') {
431
            $current = config('app.environment');
432
        }
433
434
        if (empty($env)) {
435
            return $current;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $current also could return the type BlitzPHP\Config\Config which is incompatible with the documented return type boolean|string.
Loading history...
436
        }
437
438
        $envMap = [
439
            'dev'     => 'development',
440
            'local'   => 'development',
441
            'prod'    => 'production',
442
            'test'    => 'testing',
443
            'stage'   => 'testing',
444
            'staging' => 'testing',
445
        ];
446
447
        $current = $envMap[$current] ?? $current;
448
449
        if (is_string($env)) {
0 ignored issues
show
introduced by
The condition is_string($env) is always false.
Loading history...
450
            $env = [$env];
451
        }
452
453
        $env = array_map(static fn ($k) => $envMap[$k] ?? $k, $env);
454
455
        return in_array($current, $env, true);
456
    }
457
}
458
459
if (! function_exists('on_dev')) {
460
    /**
461
     * Testez pour voir si nous sommes dans un environnement de développement.
462
     */
463
    function on_dev(bool $checkOnline = false): bool
464
    {
465
        if ($checkOnline && is_online()) {
466
            return false;
467
        }
468
469
        return environment(['dev', 'development', 'local']);
470
    }
471
}
472
473
if (! function_exists('on_prod')) {
474
    /**
475
     * Testez pour voir si nous sommes dans un environnement de production.
476
     */
477
    function on_prod(bool $checkOnline = false): bool
478
    {
479
        if ($checkOnline && is_online()) {
480
            return true;
481
        }
482
483
        return environment(['prod', 'production']);
484
    }
485
}
486
487
if (! function_exists('on_test')) {
488
    /**
489
     * Testez pour voir si nous sommes dans un environnement de test
490
     */
491
    function on_test(): bool
492
    {
493
        return environment(['test', 'testing', 'stage', 'staging']);
494
    }
495
}
496
497
if (! function_exists('is_cli')) {
498
    /**
499
     * Testez pour voir si une demande a été faite à partir de la ligne de commande.
500
     */
501
    function is_cli(): bool
502
    {
503
        return Helpers::isCli();
504
    }
505
}
506
507
if (! function_exists('is_php')) {
508
    /**
509
     * Détermine si la version actuelle de PHP est égale ou supérieure à la valeur fournie.
510
     */
511
    function is_php(string $version): bool
512
    {
513
        return Helpers::isPhp($version);
514
    }
515
}
516
517
if (! function_exists('is_windows')) {
518
    /**
519
     * Déterminez si l'environnement actuel est basé sur Windows.
520
     */
521
    function is_windows(): bool
522
    {
523
        return PHP_OS_FAMILY === 'Windows';
524
    }
525
}
526
527
if (! function_exists('is_https')) {
528
    /**
529
     * Determines if the application is accessed via an encrypted * (HTTPS) connection.
530
     */
531
    function is_https(): bool
532
    {
533
        return Services::request()->is('ssl');
534
    }
535
}
536
537
if (! function_exists('is_localfile')) {
538
    /**
539
     * Vérifiez si le fichier auquel vous souhaitez accéder est un fichier local de votre application ou non
540
     */
541
    function is_localfile(string $name): bool
542
    {
543
        if (preg_match('#^' . base_url() . '#i', $name)) {
544
            return true;
545
        }
546
547
        return ! preg_match('#^(https?://)#i', $name);
548
    }
549
}
550
551
if (! function_exists('is_online')) {
552
    /**
553
     * Tester si l'application s'exécute en local ou en ligne.
554
     */
555
    function is_online(): bool
556
    {
557
        return Helpers::isOnline();
558
    }
559
}
560
561
if (! function_exists('is_connected')) {
562
    /**
563
     * Verifie si l'utilisateur a une connexion internet active.
564
     */
565
    function is_connected(): bool
566
    {
567
        return Helpers::isConnected();
568
    }
569
}
570
571
if (! function_exists('is_ajax_request')) {
572
    /**
573
     * Testez pour voir si une requête contient l'en-tête HTTP_X_REQUESTED_WITH.
574
     */
575
    function is_ajax_request(): bool
576
    {
577
        return Services::request()->is('ajax');
578
    }
579
}
580
581
if (! function_exists('redirection')) {
582
    /**
583
     * Redirige l'utilisateur
584
     */
585
    function redirection(string $uri = '', string $method = 'location', ?int $code = 302)
586
    {
587
        $response = redirect()->to($uri, $code, [], null, $method);
588
589
        Services::emitter()->emitHeaders($response);
590
591
        exit(EXIT_SUCCESS);
0 ignored issues
show
Best Practice introduced by
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...
592
    }
593
}
594
595
if (! function_exists('redirect')) {
596
    /**
597
     * Méthode pratique qui fonctionne avec la $request globale actuelle et
598
     * l'instance $router à rediriger à l'aide de routes nommées et le routage inversé
599
     * pour déterminer l'URL à laquelle aller. Si rien n'est trouvé, traitera
600
     * comme une redirection traditionnelle et passez la chaîne, en laissant
601
     * $redirection->redirect() détermine la méthode et le code corrects.
602
     *
603
     * Si plus de contrôle est nécessaire, vous devez utiliser explicitement $response->redirect.
604
     */
605
    function redirect(?string $uri = null): Redirection
606
    {
607
        $redirection = Services::redirection();
608
609
        if (! empty($uri)) {
610
            return $redirection->route($uri);
611
        }
612
613
        return $redirection;
614
    }
615
}
616
617
if (! function_exists('back')) {
618
    /**
619
     * Retourne a la page precedente
620
     *
621
     * @param mixed $fallback
622
     */
623
    function back(int $code = 302, array $headers = [], $fallback = false): Redirection
624
    {
625
        return redirect()->back($code, $headers, $fallback);
626
    }
627
}
628
629
if (! function_exists('link_to')) {
630
    /**
631
     * Étant donné une chaîne de contrôleur/méthode et tous les paramètres,
632
     * tentera de créer l'URL relative à la route correspondante.
633
     *
634
     * REMARQUE : Cela nécessite que le contrôleur/la méthode
635
     * ait une route définie dans le fichier de configuration des routes.
636
     */
637
    function link_to(string $method, ...$params): string
638
    {
639
        $url = Services::routes()->reverseRoute($method, ...$params);
640
641
        if (empty($url)) {
642
            return '';
643
        }
644
645
        return site_url($url);
646
    }
647
}
648
649
if (! function_exists('clean_path')) {
650
    /**
651
     * Une méthode pratique pour nettoyer les chemins pour
652
     * une sortie plus belle. Utile pour les exceptions
653
     * gestion, journalisation des erreurs, etc.
654
     */
655
    function clean_path(string $path): string
656
    {
657
        $path = realpath($path) ?: $path;
658
659
        switch (true) {
660
            case str_starts_with($path, APP_PATH)  :
661
                return 'APP_PATH' . DS . substr($path, strlen(APP_PATH));
662
663
            case str_starts_with($path, SYST_PATH)  :
664
                return 'SYST_PATH' . DS . substr($path, strlen(SYST_PATH));
665
666
            case defined('VENDOR_PATH') && str_starts_with($path, VENDOR_PATH . 'blitz-php' . DS)  :
667
                return 'BLITZ_PATH' . DS . substr($path, strlen(VENDOR_PATH . 'blitz-php' . DS));
668
669
            case defined('VENDOR_PATH') && str_starts_with($path, VENDOR_PATH)  :
670
                return 'VENDOR_PATH' . DS . substr($path, strlen(VENDOR_PATH));
671
672
            case str_starts_with($path, ROOTPATH)  :
673
                return 'ROOTPATH' . DS . substr($path, strlen(ROOTPATH));
674
675
            default:
676
                return $path;
677
        }
678
    }
679
}
680
681
if (! function_exists('old')) {
682
    /**
683
     * Fournit l'accès à "entrée ancienne" qui a été définie dans la session lors d'un redirect()-withInput().
684
     *
685
     * @param false|string $escape
686
     * @param mixed|null   $default
687
     * @phpstan-param false|'attr'|'css'|'html'|'js'|'raw'|'url' $escape
688
     *
689
     * @return array|string|null
690
     */
691
    function old(string $key, $default = null, $escape = 'html')
692
    {
693
        // Assurez-vous de charger la session
694
        if (session_status() === PHP_SESSION_NONE && ! on_test()) {
695
            session(); // @codeCoverageIgnore
696
        }
697
698
        // Retourne la valeur par défaut si rien n'a été trouvé dans l'ancien input.
699
        if (null === $value = Services::request()->old($key)) {
700
            return $default;
701
        }
702
703
        return $escape === false ? $value : esc($value, $escape);
704
    }
705
}
706
707
// ================================= FONCTIONS DE DEBOGAGE ================================= //
708
709
if (! function_exists('deprecationWarning')) {
710
    /**
711
     * Méthode d'assistance pour générer des avertissements d'obsolescence
712
     *
713
     * @param string $message    Le message à afficher comme avertissement d'obsolescence.
714
     * @param int    $stackFrame Le cadre de pile à inclure dans l'erreur. Par défaut à 1
715
     *                           car cela devrait pointer vers le code de l'application/du plugin.
716
     *
717
     * @return void
718
     */
719
    function deprecation_warning(string $message, int $stackFrame = 1)
720
    {
721
        Helpers::deprecationWarning($message, $stackFrame);
722
    }
723
}
724
725
if (! function_exists('pr')) {
726
    /**
727
     * print_r() convenience function.
728
     *
729
     * In terminals this will act similar to using print_r() directly, when not run on cli
730
     * print_r() will also wrap <pre> tags around the output of given variable. Similar to debug().
731
     *
732
     * This function returns the same variable that was passed.
733
     *
734
     * @param mixed $var Variable to print out.
735
     *
736
     * @return mixed the same $var that was passed to this function
737
     */
738
    function pr($var)
739
    {
740
        $template = (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') ? '<pre class="pr">%s</pre>' : "\n%s\n\n";
741
        printf($template, trim(print_r($var, true)));
0 ignored issues
show
Bug introduced by
It seems like print_r($var, true) can also be of type true; however, parameter $string of trim() 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 ignore-type  annotation

741
        printf($template, trim(/** @scrutinizer ignore-type */ print_r($var, true)));
Loading history...
742
743
        return $var;
744
    }
745
}
746
747
if (! function_exists('pj')) {
748
    /**
749
     * json pretty print convenience function.
750
     *
751
     * In terminals this will act similar to using json_encode() with JSON_PRETTY_PRINT directly, when not run on cli
752
     * will also wrap <pre> tags around the output of given variable. Similar to pr().
753
     *
754
     * This function returns the same variable that was passed.
755
     *
756
     * @param mixed $var Variable to print out.
757
     *
758
     * @return mixed the same $var that was passed to this function
759
     *
760
     * @see pr()
761
     */
762
    function pj($var)
763
    {
764
        return Helpers::pj($var);
765
    }
766
}
767
768
if (! function_exists('trigger_warning')) {
769
    /**
770
     * Déclenche un E_USER_WARNING.
771
     */
772
    function trigger_warning(string $message)
773
    {
774
        Helpers::triggerWarning($message);
775
    }
776
}
777
778
// ================================= FONCTIONS DIVERSES ================================= //
779
780
if (! function_exists('force_https')) {
781
    /**
782
     * Utilisé pour forcer l'accès à une page via HTTPS.
783
     * Utilise une redirection standard, plus définira l'en-tête HSTS
784
     * pour les navigateurs modernes qui prennent en charge, ce qui donne une meilleur
785
     * protection contre les attaques de l'homme du milieu.
786
     *
787
     * @see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
788
     *
789
     * @param int $duration Combien de temps l'en-tête SSL doit-il être défini ? (en secondes)
790
     *                      Par défaut à 1 an.
791
     *
792
     * @credit CodeIgniter <a href="http://codeigniter.com/">helpers force_https() - /system/Common.php</a>
793
     *
794
     * Non testable, car il sortira !
795
     *
796
     * @codeCoverageIgnore
797
     */
798
    function force_https(int $duration = 31536000, ?ServerRequest $request = null, ?Redirection $response = null)
799
    {
800
        if (null === $request) {
801
            $request = Services::request();
802
        }
803
        if (null === $response) {
804
            $response = Services::redirection();
805
        }
806
807
        if (is_cli() || $request->is('ssl')) {
808
            return;
809
        }
810
811
        // Si la bibliothèque de session est chargée, nous devons régénérer
812
        // l'ID de session pour des raisons de sécurité.
813
        Services::session()->regenerate();
814
815
        $baseURL = base_url();
816
817
        if (str_starts_with($baseURL, 'http://')) {
818
            $baseURL = (string) substr($baseURL, strlen('http://'));
819
        }
820
821
        $uri = Uri::createURIString(
822
            'https',
823
            $baseURL,
824
            $request->getUri()->getPath(), // Les URI absolus doivent utiliser un "/" pour un chemin vide
825
            $request->getUri()->getQuery(),
826
            $request->getUri()->getFragment()
827
        );
828
829
        // Définir un en-tête HSTS
830
        $response = $response->to($uri)->withHeader('Strict-Transport-Security', 'max-age=' . $duration);
831
832
        Services::emitter()->emitHeaders($response);
833
834
        exit(EXIT_SUCCESS);
0 ignored issues
show
Best Practice introduced by
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...
835
    }
836
}
837
838
if (! function_exists('get_type_name')) {
839
    /**
840
     * Renvoie la classe d'objets ou le type var de ce n'est pas un objet
841
     *
842
     * @param mixed $var Variable à vérifier
843
     *
844
     * @return string Renvoie le nom de la classe ou le type de variable
845
     */
846
    function get_type_name($var): string
847
    {
848
        return Helpers::typeName($var);
849
    }
850
}
851
852
if (! function_exists('ip_address')) {
853
    /**
854
     * Renvoie l'adresse IP de l'utilisateur actuel
855
     */
856
    function ip_address(): string
857
    {
858
        return (string) Services::request()->clientIp();
859
    }
860
}
861
862
if (! function_exists('is_really_writable')) {
863
    /**
864
     * Tests d'inscriptibilité des fichiers
865
     */
866
    function is_really_writable(string $file): bool
867
    {
868
        return Helpers::isReallyWritable($file);
869
    }
870
}
871
872
if (! function_exists('lang')) {
873
    /**
874
     * Une méthode pratique pour traduire une chaîne ou un tableau d'entrées et formater
875
     * le résultat avec le MessageFormatter de l'extension intl.
876
     */
877
    function lang(string $line, array $args = [], ?string $locale = null): string
878
    {
879
        return Services::translator($locale)->getLine($line, $args);
880
    }
881
}
882
883
if (! function_exists('__')) {
884
    /**
885
     * Une méthode pratique pour traduire une chaîne ou un tableau d'entrées et formater
886
     * le résultat avec le MessageFormatter de l'extension intl.
887
     */
888
    function __(string $line, array $args = [], ?string $locale = null): string
889
    {
890
        $tranlation = lang('App.' . $line, $args, $locale);
891
892
        return preg_replace('/^(App\.)/i', '', $tranlation);
893
    }
894
}
895
896
if (! function_exists('namespace_split')) {
897
    /**
898
     * Séparez l'espace de noms du nom de classe.
899
     *
900
     * Couramment utilisé comme `list($namespace, $className) = namespaceSplit($class);`.
901
     *
902
     * @param string $class Le nom complet de la classe, ie `BlitzPHP\Http\Request`.
903
     *
904
     * @return array Tableau avec 2 index. 0 => namespace, 1 => classname.
905
     */
906
    function namespace_split(string $class): array
907
    {
908
        $pos = strrpos($class, '\\');
909
        if ($pos === false) {
910
            return ['', $class];
911
        }
912
913
        return [substr($class, 0, $pos), substr($class, $pos + 1)];
914
    }
915
}
916
917
if (! function_exists('view_exist')) {
918
    /**
919
     * Verifie si un fichier de vue existe. Utile pour limiter les failles include
920
     */
921
    function view_exist(string $name, string $ext = '.php'): bool
922
    {
923
        $ext  = str_replace('.', '', $ext);
924
        $name = str_replace(VIEW_PATH, '', $name);
925
        $name = preg_match('#\.' . $ext . '$#', $name) ? $name : $name . '.' . $ext;
926
927
        return is_file(VIEW_PATH . rtrim($name, DS));
928
    }
929
}
930
931
if (! function_exists('view')) {
932
    /**
933
     * Charge une vue
934
     *
935
     * @return \BlitzPHP\View\View
936
     */
937
    function view(string $view, ?array $data = [], ?array $options = [])
938
    {
939
        $object = Services::viewer(false);
940
941
        $object->addData($data)->setOptions($options);
942
943
        return $object->display($view);
944
    }
945
}
946
947
if (! function_exists('flash')) {
948
    /**
949
     * Fournisseur d'acces rapide a la classe PHP Flash
950
     *
951
     * @return FlashMessages|string
952
     */
953
    /*
954
    function flash()
955
    {
956
         @var FlashMessages $flash
957
        $flash = service(FlashMessages::class);
958
959
        $params = func_get_args();
960
        $type = array_shift($params);
961
962
        if (!empty($type)) {
963
            if (empty($params)) {
964
                if ($type === 'all') {
965
                    $type = null;
966
                }
967
                return $flash->display($type, false);
968
            }
969
970
            $message = array_shift($params);
971
972
            return $flash->add($message, $type, ...$params);
973
        }
974
975
        return $flash;
976
    }*/
977
}
978
979
if (! function_exists('geo_ip')) {
980
    /**
981
     * Recuperation des coordonnees (pays, ville, etc) d'un utilisateur en fonction de son ip
982
     */
983
    function geo_ip(?string $ip = null): ?array
984
    {
985
        return json_decode(file_get_contents('http://ip-api.com/json/' . $ip), true);
986
    }
987
}
988
989
if (! function_exists('to_stream')) {
990
    /**
991
     * Créez un nouveau flux basé sur le type d'entrée.
992
     *
993
     * Options est un tableau associatif pouvant contenir les clés suivantes :
994
     * - metadata : Tableau de métadonnées personnalisées.
995
     * - size : Taille du flux.
996
     *
997
     * @param bool|callable|float|int|\Iterator|\Psr\Http\Message\StreamInterface|resource|string|null $resource Données du corps de l'entité
998
     * @param array                                                                                    $options  Additional options
999
     *
1000
     * @uses GuzzleHttp\Psr7\stream_for
1001
     *
1002
     * @throws \InvalidArgumentException si l'argument $resource n'est pas valide.
1003
     */
1004
    function to_stream($resource = '', array $options = []): Psr\Http\Message\StreamInterface
1005
    {
1006
        return \GuzzleHttp\Psr7\Utils::streamFor($resource, $options);
1007
    }
1008
}
1009
1010
if (! function_exists('value')) {
1011
    /**
1012
     * Renvoie la valeur par défaut de la valeur donnée.
1013
     */
1014
    function value(mixed $value, ...$args): mixed
1015
    {
1016
        return Helpers::value($value, ...$args);
1017
    }
1018
}
1019
1020
if (! function_exists('collect')) {
1021
    /**
1022
     * Créez une collection à partir de la valeur donnée.
1023
     */
1024
    function collect(mixed $value = null): Collection
1025
    {
1026
        return Helpers::collect($value);
1027
    }
1028
}
1029
1030
if (! function_exists('with')) {
1031
    /**
1032
     * Renvoie la valeur donnée, éventuellement transmise via le rappel donné.
1033
     *
1034
     * @param mixed $value
1035
     */
1036
    function with($value, ?callable $callback = null): mixed
1037
    {
1038
        return Helpers::with($value, $callback);
1039
    }
1040
}
1041
1042
if (! function_exists('tap')) {
1043
    /**
1044
     * Appelez la Closure donnée avec cette instance puis renvoyez l'instance.
1045
     */
1046
    function tap(mixed $value, ?callable $callback = null): mixed
1047
    {
1048
        return Helpers::tap($value, $callback);
1049
    }
1050
}
1051
1052
if (! function_exists('last')) {
1053
    /**
1054
     * Recupere le dernier element d'un tableau
1055
     */
1056
    function last(array|object $array)
1057
    {
1058
        return end($array);
1059
    }
1060
}
1061
1062
if (! function_exists('invade')) {
1063
    /**
1064
     * Cette classe offre une fonction d'invasion qui vous permettra de lire / écrire des propriétés privées d'un objet.
1065
     * Il vous permettra également de définir, obtenir et appeler des méthodes privées.
1066
     *
1067
     * @return Invader
1068
     *
1069
     * @see https://github.com/spatie/invade/blob/main/src/Invader.php
1070
     */
1071
    function invade(object $object)
1072
    {
1073
        return Invader::make($object);
1074
    }
1075
}
1076