Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
65.28% covered (warning)
65.28%
47 / 72
37.50% covered (danger)
37.50%
6 / 16
CRAP
0.00% covered (danger)
0.00%
0 / 1
RequestAbstract
65.28% covered (warning)
65.28%
47 / 72
37.50% covered (danger)
37.50%
6 / 16
120.40
0.00% covered (danger)
0.00%
0 / 1
 getData
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
10.02
 getDataString
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getDataInt
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getDataFloat
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getDataBool
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getDataDateTime
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getDataJson
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
4.05
 getDataList
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 getLike
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 hasData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 setData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 fromData
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 lock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getOrigin
n/a
0 / 0
n/a
0 / 0
0
 getRouteVerb
n/a
0 / 0
n/a
0 / 0
0
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addFile
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Message
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Message;
16
17use phpOMS\Uri\UriInterface;
18
19/**
20 * Request class.
21 *
22 * @package phpOMS\Message
23 * @license OMS License 2.0
24 * @link    https://jingga.app
25 * @since   1.0.0
26 */
27abstract class RequestAbstract implements MessageInterface
28{
29    /**
30     * Uri.
31     *
32     * @var UriInterface
33     * @since 1.0.0
34     */
35    public UriInterface $uri;
36
37    /**
38     * Request data.
39     *
40     * @var array<int|string, mixed>
41     * @since 1.0.0
42     */
43    public array $data = [];
44
45    /**
46     * Files data.
47     *
48     * @var array
49     * @since 1.0.0
50     */
51    public array $files = [];
52
53    /**
54     * Request lock.
55     *
56     * @var bool
57     * @since 1.0.0
58     */
59    protected bool $lock = false;
60
61    /**
62     * Request header.
63     *
64     * @var HeaderAbstract
65     * @since 1.0.0
66     */
67    public HeaderAbstract $header;
68
69    /**
70     * Local
71     *
72     * @var string
73     * @since 1.0.0
74     */
75    protected string $locale = '';
76
77    /**
78     * Request hash.
79     *
80     * @var string[]
81     * @since 1.0.0
82     */
83    protected array $hash = [];
84
85    /**
86     * Get data.
87     *
88     * @param string $key  Data key
89     * @param string $type Return type
90     *
91     * @return mixed
92     *
93     * @since 1.0.0
94     */
95    public function getData(string $key = null, string $type = null) : mixed
96    {
97        if ($key === null) {
98            return $this->data;
99        }
100
101        $key = \mb_strtolower($key);
102        if (!isset($this->data[$key])) {
103            return null;
104        }
105
106        switch ($type) {
107            case null:
108                return $this->data[$key];
109            case 'int':
110                return (int) $this->data[$key];
111            case 'string':
112                return (string) $this->data[$key];
113            case 'float':
114                return (float) $this->data[$key];
115            case 'bool':
116                return (bool) $this->data[$key];
117            case 'DateTime':
118                return new \DateTime((string) $this->data[$key]);
119            default:
120                return $this->data[$key];
121        }
122    }
123
124    /**
125     * Get data.
126     *
127     * @param string $key Data key
128     *
129     * @return null|string
130     *
131     * @since 1.0.0
132     */
133    public function getDataString(string $key) : ?string
134    {
135        $key = \mb_strtolower($key);
136        if (($this->data[$key] ?? '') === '') {
137            return null;
138        }
139
140        return (string) $this->data[$key];
141    }
142
143    /**
144     * Get data.
145     *
146     * @param string $key Data key
147     *
148     * @return null|int
149     *
150     * @since 1.0.0
151     */
152    public function getDataInt(string $key) : ?int
153    {
154        $key = \mb_strtolower($key);
155        if (($this->data[$key] ?? '') === '') {
156            return null;
157        }
158
159        return (int) $this->data[$key];
160    }
161
162    /**
163     * Get data.
164     *
165     * @param string $key Data key
166     *
167     * @return null|float
168     *
169     * @since 1.0.0
170     */
171    public function getDataFloat(string $key) : ?float
172    {
173        $key = \mb_strtolower($key);
174        if (($this->data[$key] ?? '') === '') {
175            return null;
176        }
177
178        return (float) $this->data[$key];
179    }
180
181    /**
182     * Get data.
183     *
184     * @param string $key Data key
185     *
186     * @return null|bool
187     *
188     * @since 1.0.0
189     */
190    public function getDataBool(string $key) : ?bool
191    {
192        $key = \mb_strtolower($key);
193        if (($this->data[$key] ?? '') === '') {
194            return null;
195        }
196
197        return (bool) $this->data[$key];
198    }
199
200    /**
201     * Get data.
202     *
203     * @param string $key Data key
204     *
205     * @return null|\DateTime
206     *
207     * @since 1.0.0
208     */
209    public function getDataDateTime(string $key) : ?\DateTime
210    {
211        $key = \mb_strtolower($key);
212
213        return empty($this->data[$key] ?? null)
214            ? null
215            : new \DateTime((string) $this->data[$key]);
216    }
217
218    /**
219     * Get data.
220     *
221     * @param string $key Data key
222     *
223     * @return array
224     *
225     * @since 1.0.0
226     */
227    public function getDataJson(string $key) : array
228    {
229        $key = \mb_strtolower($key);
230        if (($this->data[$key] ?? '') === '') {
231            return [];
232        }
233
234        $json = \json_decode($this->data[$key], true); /** @phpstan-ignore-line */
235        if ($json === null) {
236            $json = $this->data[$key];
237        }
238
239        return \is_array($json) ? $json : [$json];
240    }
241
242    /**
243     * Get data.
244     *
245     * @param string $key   Data key
246     * @param string $delim Data delimiter
247     *
248     * @return array
249     *
250     * @since 1.0.0
251     */
252    public function getDataList(string $key, string $delim = ',') : array
253    {
254        $key = \mb_strtolower($key);
255        if (($this->data[$key] ?? '') === '') {
256            return [];
257        }
258
259        /* @phpstan-ignore-next-line */
260        $list = \explode($delim, (string) $this->data[$key]);
261        if ($list === false) {
262            return []; // @codeCoverageIgnore
263        }
264
265        foreach ($list as $i => $e) {
266            $list[$i] = \trim($e);
267        }
268
269        return $list;
270    }
271
272    /**
273     * Get data based on wildcard.
274     *
275     * @param string $regex Regex data key
276     *
277     * @return array
278     *
279     * @since 1.0.0
280     */
281    public function getLike(string $regex) : array
282    {
283        $data = [];
284        foreach ($this->data as $key => $value) {
285            if (\preg_match('/' . $regex . '/', (string) $key) === 1) {
286                $data[$key] = $value;
287            }
288        }
289
290        return $data;
291    }
292
293    /**
294     * Check if has data.
295     *
296     * The following empty values are considered as not set (null, '', 0)
297     *
298     * @param string $key Data key
299     *
300     * @return bool
301     *
302     * @since 1.0.0
303     */
304    public function hasData(string $key) : bool
305    {
306        $key = \mb_strtolower($key);
307
308        return isset($this->data[$key])
309            && $this->data[$key] !== ''
310            && $this->data[$key] !== null;
311    }
312
313    /**
314     * Set request data.
315     *
316     * @param string $key       Data key
317     * @param mixed  $value     Value
318     * @param bool   $overwrite Overwrite data
319     *
320     * @return bool
321     *
322     * @since 1.0.0
323     */
324    public function setData(string $key, mixed $value, bool $overwrite = false) : bool
325    {
326        if (!$this->lock) {
327            $key = \mb_strtolower($key);
328            if ($overwrite || !isset($this->data[$key])) {
329                $this->data[$key] = $value;
330
331                return true;
332            }
333        }
334
335        return false;
336    }
337
338    /**
339     * Create from data array
340     *
341     * @param array $data Data array
342     *
343     * @return void
344     *
345     * @since 1.0.0
346     */
347    public function fromData(array $data) : void
348    {
349        $this->data = $data;
350    }
351
352    /**
353     * Lock request for further manipulations.
354     *
355     * @return void
356     *
357     * @since 1.0.0
358     */
359    public function lock() : void
360    {
361        $this->lock = true;
362    }
363
364    /**
365     * Get request hash.
366     *
367     * @return string[]
368     *
369     * @since 1.0.0
370     */
371    public function getHash() : array
372    {
373        return $this->hash;
374    }
375
376    /**
377     * Get the origin request source (IPv4/IPv6)
378     *
379     * @return string
380     *
381     * @since 1.0.0
382     */
383    abstract public function getOrigin() : string;
384
385    /**
386     * Get the route verb
387     *
388     * @return int
389     *
390     * @since 1.0.0
391     */
392    abstract public function getRouteVerb() : int;
393
394    /**
395     * {@inheritdoc}
396     */
397    public function __toString() : string
398    {
399        return $this->uri->__toString();
400    }
401
402    /**
403     * Add file to request
404     *
405     * @param array $file File data to add (Array here means one file with multiple information e.g. name, path, size)
406     *
407     * @return void
408     *
409     * @since 1.0.0
410     */
411    public function addFile(array $file) : void
412    {
413        $this->files[] = $file;
414    }
415}