PluginProbe
Packeta / 2.1
Packeta v2.1
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / http / src / Http / Request.php

Request.php in Packeta 2.1, at deps/nette/http/src/Http/Request.php

280 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7 declare (strict_types=1);
8 namespace Packetery\Nette\Http;
9
10 use Packetery\Nette;
11 /**
12 * HttpRequest provides access scheme for request sent via HTTP.
13 *
14 * @property-read UrlScript $url
15 * @property-read array $query
16 * @property-read array $post
17 * @property-read array $files
18 * @property-read array $cookies
19 * @property-read string $method
20 * @property-read array $headers
21 * @property-read UrlImmutable|null $referer
22 * @property-read bool $secured
23 * @property-read bool $ajax
24 * @property-read string|null $remoteAddress
25 * @property-read string|null $remoteHost
26 * @property-read string|null $rawBody
27 */
28 class Request implements IRequest
29 {
30 use \Packetery\Nette\SmartObject;
31 /** @var string */
32 private $method;
33 /** @var UrlScript */
34 private $url;
35 /** @var array */
36 private $post;
37 /** @var array */
38 private $files;
39 /** @var array */
40 private $cookies;
41 /** @var array */
42 private $headers;
43 /** @var string|null */
44 private $remoteAddress;
45 /** @var string|null */
46 private $remoteHost;
47 /** @var callable|null */
48 private $rawBodyCallback;
49 public function __construct(UrlScript $url, ?array $post = null, ?array $files = null, ?array $cookies = null, ?array $headers = null, ?string $method = null, ?string $remoteAddress = null, ?string $remoteHost = null, ?callable $rawBodyCallback = null)
50 {
51 $this->url = $url;
52 $this->post = (array) $post;
53 $this->files = (array) $files;
54 $this->cookies = (array) $cookies;
55 $this->headers = \array_change_key_case((array) $headers, \CASE_LOWER);
56 $this->method = $method ?: 'GET';
57 $this->remoteAddress = $remoteAddress;
58 $this->remoteHost = $remoteHost;
59 $this->rawBodyCallback = $rawBodyCallback;
60 }
61 /**
62 * Returns a clone with a different URL.
63 * @return static
64 */
65 public function withUrl(UrlScript $url)
66 {
67 $dolly = clone $this;
68 $dolly->url = $url;
69 return $dolly;
70 }
71 /**
72 * Returns the URL of the request.
73 */
74 public function getUrl() : UrlScript
75 {
76 return $this->url;
77 }
78 /********************* query, post, files & cookies ****************d*g**/
79 /**
80 * Returns variable provided to the script via URL query ($_GET).
81 * If no key is passed, returns the entire array.
82 * @return mixed
83 */
84 public function getQuery(?string $key = null)
85 {
86 if (\func_num_args() === 0) {
87 return $this->url->getQueryParameters();
88 } elseif (\func_num_args() > 1) {
89 \trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', \E_USER_DEPRECATED);
90 }
91 return $this->url->getQueryParameter($key);
92 }
93 /**
94 * Returns variable provided to the script via POST method ($_POST).
95 * If no key is passed, returns the entire array.
96 * @return mixed
97 */
98 public function getPost(?string $key = null)
99 {
100 if (\func_num_args() === 0) {
101 return $this->post;
102 } elseif (\func_num_args() > 1) {
103 \trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', \E_USER_DEPRECATED);
104 }
105 return $this->post[$key] ?? null;
106 }
107 /**
108 * Returns uploaded file.
109 * @param string|string[] $key
110 * @return ?FileUpload
111 */
112 public function getFile($key)
113 {
114 $res = \Packetery\Nette\Utils\Arrays::get($this->files, $key, null);
115 return $res instanceof FileUpload ? $res : null;
116 }
117 /**
118 * Returns tree of upload files in a normalized structure, with each leaf an instance of \Packetery\Nette\Http\FileUpload.
119 */
120 public function getFiles() : array
121 {
122 return $this->files;
123 }
124 /**
125 * Returns a cookie or `null` if it does not exist.
126 * @return mixed
127 */
128 public function getCookie(string $key)
129 {
130 if (\func_num_args() > 1) {
131 \trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', \E_USER_DEPRECATED);
132 }
133 return $this->cookies[$key] ?? null;
134 }
135 /**
136 * Returns all cookies.
137 */
138 public function getCookies() : array
139 {
140 return $this->cookies;
141 }
142 /********************* method & headers ****************d*g**/
143 /**
144 * Returns the HTTP method with which the request was made (GET, POST, HEAD, PUT, ...).
145 */
146 public function getMethod() : string
147 {
148 return $this->method;
149 }
150 /**
151 * Checks the HTTP method with which the request was made. The parameter is case-insensitive.
152 */
153 public function isMethod(string $method) : bool
154 {
155 return \strcasecmp($this->method, $method) === 0;
156 }
157 /**
158 * Returns an HTTP header or `null` if it does not exist. The parameter is case-insensitive.
159 */
160 public function getHeader(string $header) : ?string
161 {
162 if (\func_num_args() > 1) {
163 \trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', \E_USER_DEPRECATED);
164 }
165 $header = \strtolower($header);
166 return $this->headers[$header] ?? null;
167 }
168 /**
169 * Returns all HTTP headers as associative array.
170 */
171 public function getHeaders() : array
172 {
173 return $this->headers;
174 }
175 /**
176 * What URL did the user come from? Beware, it is not reliable at all.
177 * @deprecated deprecated in favor of the getOrigin()
178 */
179 public function getReferer() : ?UrlImmutable
180 {
181 return isset($this->headers['referer']) ? new UrlImmutable($this->headers['referer']) : null;
182 }
183 /**
184 * What origin did the user come from? It contains scheme, hostname and port.
185 */
186 public function getOrigin() : ?UrlImmutable
187 {
188 $header = $this->headers['origin'] ?? 'null';
189 try {
190 return $header === 'null' ? null : new UrlImmutable($header);
191 } catch (\Packetery\Nette\InvalidArgumentException $e) {
192 return null;
193 }
194 }
195 /**
196 * Is the request sent via secure channel (https)?
197 */
198 public function isSecured() : bool
199 {
200 return $this->url->getScheme() === 'https';
201 }
202 /**
203 * Is the request coming from the same site and is initiated by clicking on a link?
204 */
205 public function isSameSite() : bool
206 {
207 return isset($this->cookies[Helpers::StrictCookieName]);
208 }
209 /**
210 * Is it an AJAX request?
211 */
212 public function isAjax() : bool
213 {
214 return $this->getHeader('X-Requested-With') === 'XMLHttpRequest';
215 }
216 /**
217 * Returns the IP address of the remote client.
218 */
219 public function getRemoteAddress() : ?string
220 {
221 return $this->remoteAddress;
222 }
223 /**
224 * Returns the host of the remote client.
225 */
226 public function getRemoteHost() : ?string
227 {
228 if ($this->remoteHost === null && $this->remoteAddress !== null) {
229 $this->remoteHost = \gethostbyaddr($this->remoteAddress);
230 }
231 return $this->remoteHost;
232 }
233 /**
234 * Returns raw content of HTTP request body.
235 */
236 public function getRawBody() : ?string
237 {
238 return $this->rawBodyCallback ? ($this->rawBodyCallback)() : null;
239 }
240 /**
241 * Returns basic HTTP authentication credentials.
242 * @return array{string, string}|null
243 */
244 public function getBasicCredentials() : ?array
245 {
246 return \preg_match('~^Basic (\\S+)$~', $this->headers['authorization'] ?? '', $t) && ($t = \base64_decode($t[1], \true)) && ($t = \explode(':', $t, 2)) && \count($t) === 2 ? $t : null;
247 }
248 /**
249 * Returns the most preferred language by browser. Uses the `Accept-Language` header. If no match is reached, it returns `null`.
250 * @param string[] $langs supported languages
251 */
252 public function detectLanguage(array $langs) : ?string
253 {
254 $header = $this->getHeader('Accept-Language');
255 if (!$header) {
256 return null;
257 }
258 $s = \strtolower($header);
259 // case insensitive
260 $s = \strtr($s, '_', '-');
261 // cs_CZ means cs-CZ
262 \rsort($langs);
263 // first more specific
264 \preg_match_all('#(' . \implode('|', $langs) . ')(?:-[^\\s,;=]+)?\\s*(?:;\\s*q=([0-9.]+))?#', $s, $matches);
265 if (!$matches[0]) {
266 return null;
267 }
268 $max = 0;
269 $lang = null;
270 foreach ($matches[1] as $key => $value) {
271 $q = $matches[2][$key] === '' ? 1.0 : (float) $matches[2][$key];
272 if ($q > $max) {
273 $max = $q;
274 $lang = $value;
275 }
276 }
277 return $lang;
278 }
279 }
280