Issues (92)

src/Traits/InteractsWithInput.php (7 issues)

1
<?php
2
3
namespace Nip\Http\Traits;
4
5
use Nip\Utility\Arr;
6
use Nip\Utility\Str;
7
use SplFileInfo;
8
use stdClass;
9
use Symfony\Component\HttpFoundation\File\UploadedFile;
10
11
/**
12
 * Trait InteractsWithInput
13
 * @package Nip\Http\Traits
14
 */
15
trait InteractsWithInput
16
{
17
18
    /**
19
     * Retrieve a server variable from the request.
20
     *
21
     * @param string|null $key
22
     * @param string|array|null $default
23
     * @return string|array|null
24
     */
25
    public function server($key = null, $default = null)
26
    {
27
        return $this->retrieveItem('server', $key, $default);
28
    }
29
30
    /**
31
     * Determine if a header is set on the request.
32
     *
33
     * @param string $key
34
     * @return bool
35
     */
36
    public function hasHeader($key)
37
    {
38
        return !is_null($this->header($key));
39
    }
40
41
    /**
42
     * Retrieve a header from the request.
43
     *
44
     * @param string|null $key
45
     * @param string|array|null $default
46
     * @return string|array|null
47
     */
48 1
    public function header($key = null, $default = null)
49
    {
50 1
        return $this->retrieveItem('headers', $key, $default);
51
    }
52
53
    /**
54
     * Get the bearer token from the request headers.
55
     *
56
     * @return string|null
57
     */
58
    public function bearerToken()
59
    {
60
        $header = $this->header('Authorization', '');
61
62
        if (Str::startsWith($header, 'Bearer ')) {
0 ignored issues
show
It seems like $header can also be of type array; however, parameter $haystack of Nip\Utility\Str::startsWith() 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

62
        if (Str::startsWith(/** @scrutinizer ignore-type */ $header, 'Bearer ')) {
Loading history...
63
            return Str::substr($header, 7);
0 ignored issues
show
It seems like $header can also be of type array; however, parameter $string of Nip\Utility\Str::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

63
            return Str::substr(/** @scrutinizer ignore-type */ $header, 7);
Loading history...
64
        }
65
    }
66
67
    /**
68
     * Determine if the request contains a given input item key.
69
     *
70
     * @param string|array $key
71
     * @return bool
72
     */
73
    public function exists($key)
74
    {
75
        return $this->has($key);
76
    }
77
78
    /**
79
     * Determine if the request contains a given input item key.
80
     *
81
     * @param string|array $key
82
     * @return bool
83
     */
84 1
    public function has($key)
85
    {
86 1
        $keys = is_array($key) ? $key : func_get_args();
87
88 1
        $input = $this->all();
89
90 1
        foreach ($keys as $value) {
91 1
            if (!Arr::has($input, $value)) {
92 1
                return false;
93
            }
94
        }
95
96 1
        return true;
97
    }
98
99
    /**
100
     * Determine if the request contains any of the given inputs.
101
     *
102
     * @param string|array $keys
103
     * @return bool
104
     */
105
    public function hasAny($keys)
106
    {
107
        $keys = is_array($keys) ? $keys : func_get_args();
108
109
        $input = $this->all();
110
111
        return Arr::hasAny($input, $keys);
0 ignored issues
show
The method hasAny() does not exist on Nip\Utility\Arr. ( Ignorable by Annotation )

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

111
        return Arr::/** @scrutinizer ignore-call */ hasAny($input, $keys);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
112
    }
113
114
    /**
115
     * Determine if the request contains a non-empty value for an input item.
116
     *
117
     * @param string|array $key
118
     * @return bool
119
     */
120
    public function filled($key)
121
    {
122
        $keys = is_array($key) ? $key : func_get_args();
123
124
        foreach ($keys as $value) {
125
            if ($this->isEmptyString($value)) {
126
                return false;
127
            }
128
        }
129
130
        return true;
131
    }
132
133
    /**
134
     * Determine if the request contains a non-empty value for any of the given inputs.
135
     *
136
     * @param string|array $keys
137
     * @return bool
138
     */
139
    public function anyFilled($keys)
140
    {
141
        $keys = is_array($keys) ? $keys : func_get_args();
142
143
        foreach ($keys as $key) {
144
            if ($this->filled($key)) {
145
                return true;
146
            }
147
        }
148
149
        return false;
150
    }
151
152
    /**
153
     * Determine if the request is missing a given input item key.
154
     *
155
     * @param string|array $key
156
     * @return bool
157
     */
158
    public function missing($key)
159
    {
160
        $keys = is_array($key) ? $key : func_get_args();
161
162
        return !$this->has($keys);
163
    }
164
165
    /**
166
     * Determine if the given input key is an empty string for "has".
167
     *
168
     * @param string $key
169
     * @return bool
170
     */
171
    protected function isEmptyString($key)
172
    {
173
        $value = $this->input($key);
174
175
        return !is_bool($value) && !is_array($value) && trim((string)$value) === '';
176
    }
177
178
    /**
179
     * Get the keys for all of the input and files.
180
     *
181
     * @return array
182
     */
183
    public function keys()
184
    {
185
        return array_merge(array_keys($this->input()), $this->files->keys());
186
    }
187
188
    /**
189
     * Get all of the input and files for the request.
190
     *
191
     * @param array|mixed|null $keys
192
     * @return array
193
     */
194 1
    public function all($keys = null)
195
    {
196 1
        $input = array_replace_recursive($this->input(), $this->allFiles());
197
198 1
        if (!$keys) {
199 1
            return $input;
200
        }
201
202
        $results = [];
203
204
        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
205
            Arr::set($results, $key, Arr::get($input, $key));
206
        }
207
208
        return $results;
209
    }
210
211
    /**
212
     * Retrieve an input item from the request.
213
     *
214
     * @param string|null $key
215
     * @param mixed $default
216
     * @return mixed
217
     */
218 1
    public function input($key = null, $default = null)
219
    {
220 1
        return data_get(
221 1
            $this->getInputSource()->all()
0 ignored issues
show
It seems like getInputSource() 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

221
            $this->/** @scrutinizer ignore-call */ 
222
                   getInputSource()->all()
Loading history...
222 1
            + $this->attributes->all()
223 1
            + $this->query->all(),
224 1
            $key,
225 1
            $default
226
        );
227
    }
228
229
    /**
230
     * Retrieve input as a boolean value.
231
     *
232
     * Returns true when value is "1", "true", "on", and "yes". Otherwise, returns false.
233
     *
234
     * @param string|null $key
235
     * @param bool $default
236
     * @return bool
237
     */
238
    public function boolean($key = null, $default = false)
239
    {
240
        return filter_var($this->input($key, $default), FILTER_VALIDATE_BOOLEAN);
241
    }
242
243
    /**
244
     * Get a subset containing the provided keys with values from the input data.
245
     *
246
     * @param array|mixed $keys
247
     * @return array
248
     */
249
    public function only($keys)
250
    {
251
        $results = [];
252
253
        $input = $this->all();
254
255
        $placeholder = new stdClass;
256
257
        foreach (is_array($keys) ? $keys : func_get_args() as $key) {
258
            $value = data_get($input, $key, $placeholder);
259
260
            if ($value !== $placeholder) {
261
                Arr::set($results, $key, $value);
262
            }
263
        }
264
265
        return $results;
266
    }
267
268
    /**
269
     * Get all of the input except for a specified array of items.
270
     *
271
     * @param array|mixed $keys
272
     * @return array
273
     */
274
    public function except($keys)
275
    {
276
        $keys = is_array($keys) ? $keys : func_get_args();
277
278
        $results = $this->all();
279
280
        Arr::forget($results, $keys);
281
282
        return $results;
283
    }
284
285
    /**
286
     * Retrieve a query string item from the request.
287
     *
288
     * @param string|null $key
289
     * @param string|array|null $default
290
     * @return string|array|null
291
     */
292
    public function query($key = null, $default = null)
293
    {
294
        return $this->retrieveItem('query', $key, $default);
295
    }
296
297
    /**
298
     * Retrieve a request payload item from the request.
299
     *
300
     * @param string|null $key
301
     * @param string|array|null $default
302
     * @return string|array|null
303
     */
304
    public function post($key = null, $default = null)
305
    {
306
        return $this->retrieveItem('request', $key, $default);
307
    }
308
309
    /**
310
     * Determine if a cookie is set on the request.
311
     *
312
     * @param string $key
313
     * @return bool
314
     */
315
    public function hasCookie($key)
316
    {
317
        return !is_null($this->cookie($key));
318
    }
319
320
    /**
321
     * Retrieve a cookie from the request.
322
     *
323
     * @param string|null $key
324
     * @param string|array|null $default
325
     * @return string|array|null
326
     */
327
    public function cookie($key = null, $default = null)
328
    {
329
        return $this->retrieveItem('cookies', $key, $default);
330
    }
331
332
    /**
333
     * Get an array of all of the files on the request.
334
     *
335
     * @return array
336
     */
337 1
    public function allFiles()
338
    {
339 1
        $files = $this->files->all();
340
341 1
        return $this->convertedFiles = $this->convertedFiles ?? $this->convertUploadedFiles($files);
0 ignored issues
show
Bug Best Practice introduced by
The property convertedFiles does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
342
    }
343
344
    /**
345
     * Convert the given array of Symfony UploadedFiles to custom Laravel UploadedFiles.
346
     *
347
     * @param array $files
348
     * @return array
349
     */
350 1
    protected function convertUploadedFiles(array $files)
351
    {
352
        return array_map(function ($file) {
353
            if (is_null($file) || (is_array($file) && empty(array_filter($file)))) {
354
                return $file;
355
            }
356
357
            return is_array($file)
358
                ? $this->convertUploadedFiles($file)
359
                : UploadedFile::createFromBase($file);
0 ignored issues
show
The method createFromBase() does not exist on Symfony\Component\HttpFoundation\File\UploadedFile. ( Ignorable by Annotation )

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

359
                : UploadedFile::/** @scrutinizer ignore-call */ createFromBase($file);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
360 1
        }, $files);
361
    }
362
363
    /**
364
     * Determine if the uploaded data contains a file.
365
     *
366
     * @param string $key
367
     * @return bool
368
     */
369
    public function hasFile($key)
370
    {
371
        if (!is_array($files = $this->file($key))) {
372
            $files = [$files];
373
        }
374
375
        foreach ($files as $file) {
376
            if ($this->isValidFile($file)) {
377
                return true;
378
            }
379
        }
380
381
        return false;
382
    }
383
384
    /**
385
     * Check that the given file is a valid file instance.
386
     *
387
     * @param mixed $file
388
     * @return bool
389
     */
390
    protected function isValidFile($file)
391
    {
392
        return $file instanceof SplFileInfo && $file->getPath() !== '';
393
    }
394
395
    /**
396
     * Retrieve a file from the request.
397
     *
398
     * @param string|null $key
399
     * @param mixed $default
400
     * @return UploadedFile|array|null
401
     */
402
    public function file($key = null, $default = null)
403
    {
404
        return data_get($this->allFiles(), $key, $default);
405
    }
406
407
    /**
408
     * Retrieve a parameter item from a given source.
409
     *
410
     * @param string $source
411
     * @param string $key
412
     * @param string|array|null $default
413
     * @return string|array|null
414
     */
415 1
    protected function retrieveItem($source, $key, $default)
416
    {
417 1
        if (is_null($key)) {
0 ignored issues
show
The condition is_null($key) is always false.
Loading history...
418
            return $this->{$source}->all();
419
        }
420
421 1
        return $this->{$source}->get($key, $default);
422
    }
423
}
424