InteractsWithInput::hasAny()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 3
cp 0
crap 6
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
namespace BlitzPHP\Http\Concerns;
13
14
use BlitzPHP\Filesystem\Files\UploadedFile;
15
use BlitzPHP\Utilities\Date;
16
use BlitzPHP\Utilities\Iterable\Arr;
17
use BlitzPHP\Utilities\Iterable\Collection;
18
use BlitzPHP\Utilities\String\Stringable;
19
use BlitzPHP\Utilities\String\Text;
20
use Kint\Kint;
21
use Psr\Http\Message\UploadedFileInterface;
22
use SplFileInfo;
23
use stdClass;
24
25
/**
26
 * @credit <a href="http://laravel.com/">Laravel - Illuminate\Http\Concerns\InteractsWithInput</a>
27
 */
28
trait InteractsWithInput
29
{
30
    /**
31
     * Récupérez une variable de serveur à partir de la requête.
32
     *
33
     * @return array|string|null
34
     */
35
    public function server(?string $key = null, array|string|null $default = null)
36
    {
37
        return Arr::get($this->_environment, $key, $default);
38
    }
39
40
    /**
41
     * Récupérer un en-tête de la requête.
42
     *
43
     * @return array|string|null
44
     */
45
    public function header(?string $key = null, array|string|null $default = null)
46
    {
47
        if (null === $key) {
48
            return $this->getHeaders();
0 ignored issues
show
Bug introduced by
It seems like getHeaders() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

48
            return $this->/** @scrutinizer ignore-call */ getHeaders();
Loading history...
49
        }
50
51
        return empty($header = $this->getHeaderLine($key)) ? $default : $header;
0 ignored issues
show
Bug introduced by
It seems like getHeaderLine() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
        return empty($header = $this->/** @scrutinizer ignore-call */ getHeaderLine($key)) ? $default : $header;
Loading history...
52
    }
53
54
    /**
55
     * Obtenez le jeton du porteur à partir des en-têtes de requête.
56
     */
57
    public function bearerToken(): ?string
58
    {
59
        $header = $this->header('Authorization', '');
60
61
        $position = strrpos($header, 'Bearer ');
0 ignored issues
show
Bug introduced by
It seems like $header can also be of type array and null; however, parameter $haystack of strrpos() 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

61
        $position = strrpos(/** @scrutinizer ignore-type */ $header, 'Bearer ');
Loading history...
62
63
        if ($position !== false) {
64
            $header = substr($header, $position + 7);
0 ignored issues
show
Bug introduced by
It seems like $header can also be of type array and null; however, parameter $string of substr() 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

64
            $header = substr(/** @scrutinizer ignore-type */ $header, $position + 7);
Loading history...
65
66
            return str_contains($header, ',') ? strstr($header, ',', true) : $header;
67
        }
68
69
        return null;
70
    }
71
72
    /**
73
     * Déterminez si la demande contient une clé d'élément d'entrée donnée.
74
     */
75
    public function exists(array|string $key): bool
76
    {
77
        return $this->has($key);
78
    }
79
80
    /**
81
     *Déterminez si la demande contient une clé d'élément d'entrée donnée.
82
     */
83
    public function has(array|string $key): bool
84
    {
85
        $keys = is_array($key) ? $key : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
86
87
        $input = $this->all();
88
89
        foreach ($keys as $value) {
90
            if (! Arr::has($input, $value)) {
91
                return false;
92
            }
93
        }
94
95
        return true;
96
    }
97
98
    /**
99
     * Déterminez si la demande contient l'une des entrées données.
100
     */
101
    public function hasAny(array|string $keys): bool
102
    {
103
        $keys = is_array($keys) ? $keys : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($keys) is always true.
Loading history...
104
105
        $input = $this->all();
106
107
        return Arr::hasAny($input, $keys);
108
    }
109
110
    /**
111
     * Appliquez le rappel si la demande contient la clé d'élément d'entrée donnée.
112
     *
113
     * @return mixed|self
114
     */
115
    public function whenHas(string $key, callable $callback, ?callable $default = null)
116
    {
117
        if ($this->has($key)) {
118
            return $callback(Arr::dataGet($this->all(), $key)) ?: $this;
119
        }
120
121
        if ($default) {
122
            return $default();
123
        }
124
125
        return $this;
126
    }
127
128
    /**
129
     * Déterminez si la requête contient une valeur non vide pour un élément d'entrée.
130
     */
131
    public function filled(array|string $key): bool
132
    {
133
        $keys = is_array($key) ? $key : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
134
135
        foreach ($keys as $value) {
136
            if ($this->isEmptyString($value)) {
137
                return false;
138
            }
139
        }
140
141
        return true;
142
    }
143
144
    /**
145
     * Déterminez si la requête contient une valeur vide pour un élément d'entrée.
146
     */
147
    public function isNotFilled(array|string $key): bool
148
    {
149
        $keys = is_array($key) ? $key : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
150
151
        foreach ($keys as $value) {
152
            if (! $this->isEmptyString($value)) {
153
                return false;
154
            }
155
        }
156
157
        return true;
158
    }
159
160
    /**
161
     * Determine if the request contains a non-empty value for any of the given inputs.
162
     */
163
    public function anyFilled(array|string $keys): bool
164
    {
165
        $keys = is_array($keys) ? $keys : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($keys) is always true.
Loading history...
166
167
        foreach ($keys as $key) {
168
            if ($this->filled($key)) {
169
                return true;
170
            }
171
        }
172
173
        return false;
174
    }
175
176
    /**
177
     * Appliquez le rappel si la requête contient une valeur non vide pour la clé d'élément d'entrée donnée.
178
     *
179
     * @return mixed|self
180
     */
181
    public function whenFilled(string $key, callable $callback, ?callable $default = null)
182
    {
183
        if ($this->filled($key)) {
184
            return $callback(Arr::dataGet($this->all(), $key)) ?: $this;
185
        }
186
187
        if ($default) {
188
            return $default();
189
        }
190
191
        return $this;
192
    }
193
194
    /**
195
     * Déterminez s'il manque une clé d'élément d'entrée donnée dans la requête.
196
     */
197
    public function missing(array|string $key): bool
198
    {
199
        $keys = is_array($key) ? $key : func_get_args();
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
200
201
        return ! $this->has($keys);
202
    }
203
204
    /**
205
     * Appliquez le rappel s'il manque à la demande la clé d'élément d'entrée donnée.
206
     *
207
     * @return mixed|self
208
     */
209
    public function whenMissing(string $key, callable $callback, ?callable $default = null)
210
    {
211
        if ($this->missing($key)) {
212
            return $callback(Arr::dataGet($this->all(), $key)) ?: $this;
213
        }
214
215
        if ($default) {
216
            return $default();
217
        }
218
219
        return $this;
220
    }
221
222
    /**
223
     * Déterminez si la clé d'entrée donnée est une chaîne vide pour "remplie".
224
     */
225
    protected function isEmptyString(string $key): bool
226
    {
227
        $value = $this->input($key);
228
229
        return ! is_bool($value) && ! is_array($value) && trim((string) $value) === '';
230
    }
231
232
    /**
233
     * Obtenez les clés pour toutes les entrées et tous les fichiers.
234
     */
235
    public function keys(): array
236
    {
237
        return array_keys($this->input());
238
    }
239
240
    /**
241
     * Obtenez toutes les entrées et tous les fichiers de la requête.
242
     *
243
     * @param array|mixed|null $keys
244
     */
245
    public function all($keys = null): array
246
    {
247
        $input = array_replace_recursive($this->input(), $this->allFiles());
248
249
        if (! $keys) {
250
            return $input;
251
        }
252
253
        $results = [];
254
255
        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
256
            Arr::set($results, $key, Arr::get($input, $key));
257
        }
258
259
        return $results;
260
    }
261
262
    /**
263
     * Récupérer un élément d'entrée de la requête.
264
     */
265
    public function input(?string $key = null, mixed $default = null): mixed
266
    {
267
        return Arr::dataGet(
268
            $this->data + $this->query,
269
            $key,
270
            $default
271
        );
272
    }
273
274
    /**
275
     * Récupérez l'entrée de la requête en tant qu'instance Stringable.
276
     */
277
    public function str(string $key, mixed $default = null): ?Stringable
278
    {
279
        if (null === $value = $this->string($key, $default)) {
280
            return null;
281
        }
282
283
        return Text::of($value);
284
    }
285
286
    /**
287
     * Récupérez l'entrée de la requête en tant que chaine de caractere.
288
     */
289
    public function string(string $key, mixed $default = null): ?string
290
    {
291
        if (null === $value = $this->input($key, $default)) {
292
            return null;
293
        }
294
295
        return (string) $value;
296
    }
297
298
    /**
299
     * Récupérer l'entrée sous forme de valeur booléenne.
300
     *
301
     * Renvoie true lorsque la valeur est "1", "true", "on" et "yes". Sinon, renvoie faux.
302
     */
303
    public function boolean(?string $key = null, bool $default = false): bool
304
    {
305
        return filter_var($this->input($key, $default), FILTER_VALIDATE_BOOLEAN);
306
    }
307
308
    /**
309
     * Récupérer l'entrée sous forme de valeur entière.
310
     */
311
    public function integer(string $key, int $default = 0): int
312
    {
313
        return (int) ($this->input($key, $default));
314
    }
315
316
    /**
317
     * Récupérer l'entrée sous forme de valeur flottante.
318
     */
319
    public function float(string $key, float $default = 0.0): float
320
    {
321
        return (float) ($this->input($key, $default));
322
    }
323
324
    /**
325
     * Récupérez l'entrée de la demande en tant qu'instance Date.
326
     */
327
    public function date(string $key, ?string $format = null, ?string $tz = null): ?Date
328
    {
329
        if ($this->isNotFilled($key)) {
330
            return null;
331
        }
332
333
        if (null === $format) {
334
            return Date::parse($this->input($key), $tz);
335
        }
336
337
        return Date::createFromFormat($format, $this->input($key), $tz);
338
    }
339
340
    /**
341
     * Retrieve input from the request as an enum.
342
     *
343
     * @template TEnum
344
     *
345
     * @param class-string<TEnum> $enumClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TEnum> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TEnum>.
Loading history...
346
     *
347
     * @return TEnum|null
348
     */
349
    public function enum(string $key, $enumClass)
350
    {
351
        if ($this->isNotFilled($key)
352
            || ! function_exists('enum_exists')
353
            || ! enum_exists($enumClass)
354
            || ! method_exists($enumClass, 'tryFrom')) {
355
            return null;
356
        }
357
358
        return $enumClass::tryFrom($this->input($key));
359
    }
360
361
    /**
362
     * Récupérer l'entrée de la requête sous forme de collection.
363
     */
364
    public function collect(array|string|null $key = null): Collection
365
    {
366
        return collect(is_array($key) ? $this->only($key) : $this->input($key));
367
    }
368
369
    /**
370
     * Obtenez un sous-ensemble contenant les clés fournies avec les valeurs des données d'entrée.
371
     *
372
     * @param array|mixed $keys
373
     */
374
    public function only($keys): array
375
    {
376
        $results = [];
377
378
        $input = $this->all();
379
380
        $placeholder = new stdClass();
381
382
        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
383
            $value = Arr::dataGet($input, $key, $placeholder);
384
385
            if ($value !== $placeholder) {
386
                Arr::set($results, $key, $value);
387
            }
388
        }
389
390
        return $results;
391
    }
392
393
    /**
394
     * Récupère toutes les entrées à l'exception d'un tableau d'éléments spécifié.
395
     *
396
     * @param array|mixed $keys
397
     */
398
    public function except($keys): array
399
    {
400
        $keys = is_array($keys) ? $keys : func_get_args();
401
402
        $results = $this->all();
403
404
        Arr::forget($results, $keys);
405
406
        return $results;
407
    }
408
409
    /**
410
     * Récupérez un élément de chaîne de requête à partir de la demande.
411
     *
412
     * @return array|string|null
413
     */
414
    public function query(?string $key = null, array|string|null $default = null)
415
    {
416
        return $this->getQuery($key, $default);
0 ignored issues
show
Bug introduced by
It seems like getQuery() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

416
        return $this->/** @scrutinizer ignore-call */ getQuery($key, $default);
Loading history...
417
    }
418
419
    /**
420
     * Récupérer un élément de charge utile de requête à partir de la requête.
421
     *
422
     * @return array|string|null
423
     */
424
    public function post(?string $key = null, array|string|null $default = null)
425
    {
426
        if ($key === null) {
427
            return $this->data;
428
        }
429
430
        return Arr::get($this->data, $key, $default);
431
    }
432
433
    /**
434
     * Déterminez si un cookie est défini sur la demande.
435
     */
436
    public function hasCookie(string $key): bool
437
    {
438
        return null !== $this->cookie($key);
439
    }
440
441
    /**
442
     * Récupérer un cookie de la requête.
443
     *
444
     * @return array|string|null
445
     */
446
    public function cookie(?string $key = null, array|string|null $default = null)
447
    {
448
        if (null === $key) {
449
            return $this->getCookieParams();
0 ignored issues
show
Bug introduced by
It seems like getCookieParams() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

449
            return $this->/** @scrutinizer ignore-call */ getCookieParams();
Loading history...
450
        }
451
452
        return $this->getCookie($key, $default);
0 ignored issues
show
Bug introduced by
It seems like getCookie() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

452
        return $this->/** @scrutinizer ignore-call */ getCookie($key, $default);
Loading history...
453
    }
454
455
    /**
456
     * Obtenez un tableau de tous les fichiers de la requête.
457
     */
458
    public function allFiles(): array
459
    {
460
        return $this->getUploadedFiles();
0 ignored issues
show
Bug introduced by
It seems like getUploadedFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

460
        return $this->/** @scrutinizer ignore-call */ getUploadedFiles();
Loading history...
461
    }
462
463
    /**
464
     * Déterminez si les données téléchargées contiennent un fichier.
465
     */
466
    public function hasFile(string $key): bool
467
    {
468
        if (! is_array($files = $this->file($key))) {
469
            $files = [$files];
470
        }
471
472
        foreach ($files as $file) {
473
            if ($this->isValidFile($file)) {
474
                return true;
475
            }
476
        }
477
478
        return false;
479
    }
480
481
    /**
482
     * Vérifiez que le fichier donné est une instance de fichier valide.
483
     */
484
    protected function isValidFile(mixed $file): bool
485
    {
486
        return ($file instanceof SplFileInfo && $file->getPath() !== '') || $file instanceof UploadedFileInterface;
487
    }
488
489
    /**
490
     * Récupérer un fichier à partir de la requête.
491
     *
492
     * @return array|list<UploadedFile>|UploadedFile|null
0 ignored issues
show
Bug introduced by
The type BlitzPHP\Http\Concerns\list 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...
493
     */
494
    public function file(?string $key = null, mixed $default = null)
495
    {
496
        return Arr::dataGet($this->allFiles(), $key, $default);
497
    }
498
499
    /**
500
     * Videz les éléments de la requête et terminez le script.
501
     */
502
    public function dd(...$keys): never
503
    {
504
        $this->dump(...$keys);
505
506
        exit(1);
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...
507
    }
508
509
    /**
510
     * Videz les elements.
511
     *
512
     * @param mixed $keys
513
     */
514
    public function dump($keys = []): self
515
    {
516
        $keys = is_array($keys) ? $keys : func_get_args();
517
518
        Kint::dump($keys !== [] ? $this->only($keys) : $this->all());
519
520
        return $this;
521
    }
522
}
523