Passed
Push — master ( 5dce3b...1cb76e )
by Fran
02:56
created

Request::header()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PSFS\base;
4
5
use JetBrains\PhpStorm\NoReturn;
6
use PSFS\base\types\helpers\ServerHelper;
7
use PSFS\base\types\traits\Helper\ServerTrait;
8
use PSFS\base\types\traits\SingletonTrait;
9
10
/**
11
 * Class Request
12
 * @package PSFS
13
 */
14
class Request
15
{
16
    use SingletonTrait;
17
    use ServerTrait;
18
19
    const VERB_GET = 'GET';
20
    const VERB_POST = 'POST';
21
    const VERB_PUT = 'PUT';
22
    const VERB_DELETE = 'DELETE';
23
    const VERB_OPTIONS = 'OPTIONS';
24
    const VERB_HEAD = 'HEAD';
25
    const VERB_PATCH = 'PATCH';
26
27
    /**
28
     * @var array
29
     */
30
    protected array $cookies;
31
    /**
32
     * @var array
33
     */
34
    protected array $upload;
35
    /**
36
     * @var array
37
     */
38
    protected array $header;
39
    /**
40
     * @var array
41
     */
42
    protected array $data;
43
    /**
44
     * @var array
45
     */
46
    protected array $raw = [];
47
    /**
48
     * @var array
49
     */
50
    protected array $query;
51
    /**
52
     * @var bool
53
     */
54
    private bool $isLoaded = false;
55
56 2
    public function init()
57
    {
58 2
        $this->setServer(ServerHelper::getServerData());
59 2
        $this->cookies = is_array($_COOKIE) ? $_COOKIE : [];
60 2
        $this->upload = is_array($_FILES) ? $_FILES : [];
61 2
        $this->header = $this->parseHeaders();
62 2
        $this->data = is_array($_REQUEST) ? $_REQUEST : [];
63 2
        $this->query = is_array($_GET) ? $_GET : [];
64 2
        $this->raw = json_decode(file_get_contents('php://input'), true) ?: [];
65 2
        $this->isLoaded = true;
66
    }
67
68
    /**
69
     * Método que devuelve las cabeceras de la petición
70
     * @return array
71
     */
72 2
    private function parseHeaders(): array
73
    {
74 2
        return getallheaders() ?: [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return getallheaders() ?: array() could return the type true which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
75
    }
76
77
    /**
78
     * Método que verifica si existe una cabecera concreta
79
     * @param $header
80
     *
81
     * @return boolean
82
     */
83 7
    public function hasHeader($header): bool
84
    {
85 7
        return array_key_exists($header, $this->header);
86
    }
87
88
89
    /**
90
     * Método que indica si una petición tiene cookies
91
     * @return boolean
92
     */
93 1
    public function hasCookies(): bool
94
    {
95 1
        return (null !== $this->cookies && 0 !== count($this->cookies));
96
    }
97
98
    /**
99
     * Método que indica si una petición tiene cookies
100
     * @return boolean
101
     */
102 1
    public function hasUpload(): bool
103
    {
104 1
        return (null !== $this->upload && 0 !== count($this->upload));
105
    }
106
107
    /**
108
     * Método que devuelve el TimeStamp de la petición
109
     *
110
     * @param boolean $formatted
111
     *
112
     * @return string
113
     */
114
    public static function getTimestamp(bool $formatted = false)
115
    {
116
        return self::getInstance()->getTs($formatted);
117
    }
118
119
    /**
120
     * Método que devuelve una cabecera de la petición si existe
121
     * @param string $name
122
     * @param string|null $default
123
     *
124
     * @return string|null
125
     */
126 6
    public static function header(string $name, string $default = null)
127
    {
128 6
        return self::getInstance()->getHeader($name, $default);
129
    }
130
131
    /**
132
     * @param string $name
133
     * @param string|null $default
134
     * @return string|null
135
     */
136 6
    public function getHeader(string $name, string $default = null)
137
    {
138 6
        $header = null;
139 6
        if ($this->hasHeader($name)) {
140
            $header = $this->header[$name];
141 6
        } else if (array_key_exists('h_' . strtolower($name), $this->query)) {
142
            $header = $this->query['h_' . strtolower($name)];
143 6
        } else if (array_key_exists('HTTP_' . strtoupper(str_replace('-', '_', $name)), $this->server)) {
144
            $header = $this->getServer('HTTP_' . strtoupper(str_replace('-', '_', $name)));
145
        }
146 6
        return $header ?: $default;
147
    }
148
149
    /**
150
     * @param string $language
151
     * @return void
152
     */
153
    public static function setLanguageHeader(string $language): void
154
    {
155
        self::getInstance()->header['X-API-LANG'] = $language;
156
    }
157
158
    /**
159
     * Método que devuelve la url solicitada
160
     * @return string|null
161
     */
162 1
    public static function requestUri()
163
    {
164 1
        return self::getInstance()->getRequestUri();
165
    }
166
167
    /**
168
     * Método que determina si se ha solicitado un fichero
169
     * @return boolean
170
     */
171 5
    public function isFile(): bool
172
    {
173 5
        return preg_match('/\.[a-z0-9]{2,4}$/', $this->getRequestUri()) !== 0;
174
    }
175
176
    /**
177
     * Get query params
178
     *
179
     * @param string $queryParams
180
     *
181
     * @return mixed
182
     */
183
    public function getQuery($queryParams): mixed
184
    {
185
        return array_key_exists($queryParams, $this->query) ? $this->query[$queryParams] : null;
186
    }
187
188
    /**
189
     * Get all query params
190
     *
191
     * @return mixed
192
     */
193 5
    public function getQueryParams(): mixed
194
    {
195 5
        return $this->query;
196
    }
197
198
    /**
199
     * Método que devuelve un parámetro de la solicitud
200
     * @param string $param
201
     *
202
     * @return string|null
203
     */
204
    public function get(string $param)
205
    {
206
        return array_key_exists($param, $this->data) ? $this->data[$param] : null;
207
    }
208
209
    /**
210
     * Método que devuelve todos los datos del Request
211
     * @return array
212
     */
213 6
    public function getData(): array
214
    {
215 6
        return array_merge($this->data, $this->raw);
216
    }
217
218
    /**
219
     * @return array
220
     */
221
    public function getRawData(): array
222
    {
223
        return $this->raw;
224
    }
225
226
    /**
227
     * Método que devuelve el valor de una cookie en caso de que exista
228
     * @param string $name
229
     *
230
     * @return string
231
     */
232 2
    public function getCookie(string $name)
233
    {
234 2
        return array_key_exists($name, $this->cookies) ? $this->cookies[$name] : null;
235
    }
236
237
    /**
238
     * Método que devuelve los files subidos por POST
239
     * @param $name
240
     *
241
     * @return array
242
     */
243
    public function getFile($name): array
244
    {
245
        return array_key_exists($name, $this->upload) ? $this->upload[$name] : [];
246
    }
247
248
    /**
249
     * Método que realiza una redirección a la url dada
250
     * @param string|null $url
251
     */
252
    #[NoReturn] public function redirect(string $url = null): void
253
    {
254
        if (null === $url) {
255
            $url = $this->getServer('HTTP_ORIGIN');
256
        }
257
        ob_start();
258
        header('Location: ' . $url);
259
        ob_end_clean();
260
        Security::getInstance()->updateSession();
261
        exit(t('Redirect...'));
262
    }
263
264
    /**
265
     * Devuelve la url completa de base
266
     * @param boolean $hasProtocol
267
     * @return string
268
     */
269 2
    public function getRootUrl(bool $hasProtocol = true): string
270
    {
271 2
        $url = $this->getServerName();
272 2
        $protocol = $hasProtocol ? $this->getProtocol() : '';
273 2
        if (!empty($protocol)) {
274 2
            $url = $protocol . $url;
275
        }
276 2
        return $this->checkServerPort($url);
277
    }
278
279
    /**
280
     * @param string $url
281
     * @return string
282
     */
283 2
    protected function checkServerPort(string $url): string
284
    {
285 2
        $port = (integer)$this->getServer('SERVER_PORT');
286 2
        $host = $this->getServer('HTTP_HOST');
287 2
        if (!empty($host)) {
288
            $parts = explode(':', $host);
289
            $hostPort = (integer)end($parts);
290
            if ($hostPort !== $port && count($parts) > 1) {
291
                $port = $hostPort;
292
            }
293
        }
294 2
        if (!in_array($port, [80, 443], true)) {
295 2
            $url .= ':' . $port;
296
        }
297 2
        return $url;
298
    }
299
300
}
301