PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / modules / GuzzleHttp / Psr7 / ServerRequest.php

ServerRequest.php in Depicter — Popup & Slider Builder trunk, at modules/GuzzleHttp/Psr7/ServerRequest.php

341 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Depicter\GuzzleHttp\Psr7;
6
7 use InvalidArgumentException;
8 use Depicter\Psr\Http\Message\ServerRequestInterface;
9 use Depicter\Psr\Http\Message\StreamInterface;
10 use Depicter\Psr\Http\Message\UploadedFileInterface;
11 use Depicter\Psr\Http\Message\UriInterface;
12
13 /**
14 * Server-side HTTP request
15 *
16 * Extends the Request definition to add methods for accessing incoming data,
17 * specifically server parameters, cookies, matched path parameters, query
18 * string arguments, body parameters, and upload file information.
19 *
20 * "Attributes" are discovered via decomposing the request (and usually
21 * specifically the URI path), and typically will be injected by the application.
22 *
23 * Requests are considered immutable; all methods that might change state are
24 * implemented such that they retain the internal state of the current
25 * message and return a new instance that contains the changed state.
26 */
27 class ServerRequest extends Request implements ServerRequestInterface
28 {
29 /**
30 * @var array
31 */
32 private $attributes = [];
33
34 /**
35 * @var array
36 */
37 private $cookieParams = [];
38
39 /**
40 * @var array|object|null
41 */
42 private $parsedBody;
43
44 /**
45 * @var array
46 */
47 private $queryParams = [];
48
49 /**
50 * @var array
51 */
52 private $serverParams;
53
54 /**
55 * @var array
56 */
57 private $uploadedFiles = [];
58
59 /**
60 * @param string $method HTTP method
61 * @param string|UriInterface $uri URI
62 * @param (string|string[])[] $headers Request headers
63 * @param string|resource|StreamInterface|null $body Request body
64 * @param string $version Protocol version
65 * @param array $serverParams Typically the $_SERVER superglobal
66 */
67 public function __construct(
68 string $method,
69 $uri,
70 array $headers = [],
71 $body = null,
72 string $version = '1.1',
73 array $serverParams = []
74 ) {
75 $this->serverParams = $serverParams;
76
77 parent::__construct($method, $uri, $headers, $body, $version);
78 }
79
80 /**
81 * Return an UploadedFile instance array.
82 *
83 * @param array $files An array which respect $_FILES structure
84 *
85 * @throws InvalidArgumentException for unrecognized values
86 */
87 public static function normalizeFiles(array $files): array
88 {
89 $normalized = [];
90
91 foreach ($files as $key => $value) {
92 if ($value instanceof UploadedFileInterface) {
93 $normalized[$key] = $value;
94 } elseif (is_array($value) && isset($value['tmp_name'])) {
95 $normalized[$key] = self::createUploadedFileFromSpec($value);
96 } elseif (is_array($value)) {
97 $normalized[$key] = self::normalizeFiles($value);
98 continue;
99 } else {
100 throw new InvalidArgumentException('Invalid value in files specification');
101 }
102 }
103
104 return $normalized;
105 }
106
107 /**
108 * Create and return an UploadedFile instance from a $_FILES specification.
109 *
110 * If the specification represents an array of values, this method will
111 * delegate to normalizeNestedFileSpec() and return that return value.
112 *
113 * @param array $value $_FILES struct
114 *
115 * @return UploadedFileInterface|UploadedFileInterface[]
116 */
117 private static function createUploadedFileFromSpec(array $value)
118 {
119 if (is_array($value['tmp_name'])) {
120 return self::normalizeNestedFileSpec($value);
121 }
122
123 return new UploadedFile(
124 $value['tmp_name'],
125 (int) $value['size'],
126 (int) $value['error'],
127 $value['name'],
128 $value['type']
129 );
130 }
131
132 /**
133 * Normalize an array of file specifications.
134 *
135 * Loops through all nested files and returns a normalized array of
136 * UploadedFileInterface instances.
137 *
138 * @return UploadedFileInterface[]
139 */
140 private static function normalizeNestedFileSpec(array $files = []): array
141 {
142 $normalizedFiles = [];
143
144 foreach (array_keys($files['tmp_name']) as $key) {
145 $spec = [
146 'tmp_name' => $files['tmp_name'][$key],
147 'size' => $files['size'][$key] ?? null,
148 'error' => $files['error'][$key] ?? null,
149 'name' => $files['name'][$key] ?? null,
150 'type' => $files['type'][$key] ?? null,
151 ];
152 $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
153 }
154
155 return $normalizedFiles;
156 }
157
158 /**
159 * Return a ServerRequest populated with superglobals:
160 * $_GET
161 * $_POST
162 * $_COOKIE
163 * $_FILES
164 * $_SERVER
165 */
166 public static function fromGlobals(): ServerRequestInterface
167 {
168 $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
169 $headers = getallheaders();
170 $uri = self::getUriFromGlobals();
171 $body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
172 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
173
174 $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
175
176 return $serverRequest
177 ->withCookieParams($_COOKIE)
178 ->withQueryParams($_GET)
179 ->withParsedBody($_POST)
180 ->withUploadedFiles(self::normalizeFiles($_FILES));
181 }
182
183 private static function extractHostAndPortFromAuthority(string $authority): array
184 {
185 $uri = 'http://'.$authority;
186 $parts = parse_url($uri);
187 if (false === $parts) {
188 return [null, null];
189 }
190
191 $host = $parts['host'] ?? null;
192 $port = $parts['port'] ?? null;
193
194 return [$host, $port];
195 }
196
197 /**
198 * Get a Uri populated with values from $_SERVER.
199 */
200 public static function getUriFromGlobals(): UriInterface
201 {
202 $uri = new Uri('');
203
204 $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
205
206 $hasPort = false;
207 if (isset($_SERVER['HTTP_HOST'])) {
208 [$host, $port] = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
209 if ($host !== null) {
210 $uri = $uri->withHost($host);
211 }
212
213 if ($port !== null) {
214 $hasPort = true;
215 $uri = $uri->withPort($port);
216 }
217 } elseif (isset($_SERVER['SERVER_NAME'])) {
218 $uri = $uri->withHost($_SERVER['SERVER_NAME']);
219 } elseif (isset($_SERVER['SERVER_ADDR'])) {
220 $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
221 }
222
223 if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
224 $uri = $uri->withPort($_SERVER['SERVER_PORT']);
225 }
226
227 $hasQuery = false;
228 if (isset($_SERVER['REQUEST_URI'])) {
229 $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2);
230 $uri = $uri->withPath($requestUriParts[0]);
231 if (isset($requestUriParts[1])) {
232 $hasQuery = true;
233 $uri = $uri->withQuery($requestUriParts[1]);
234 }
235 }
236
237 if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
238 $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
239 }
240
241 return $uri;
242 }
243
244 public function getServerParams(): array
245 {
246 return $this->serverParams;
247 }
248
249 public function getUploadedFiles(): array
250 {
251 return $this->uploadedFiles;
252 }
253
254 public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
255 {
256 $new = clone $this;
257 $new->uploadedFiles = $uploadedFiles;
258
259 return $new;
260 }
261
262 public function getCookieParams(): array
263 {
264 return $this->cookieParams;
265 }
266
267 public function withCookieParams(array $cookies): ServerRequestInterface
268 {
269 $new = clone $this;
270 $new->cookieParams = $cookies;
271
272 return $new;
273 }
274
275 public function getQueryParams(): array
276 {
277 return $this->queryParams;
278 }
279
280 public function withQueryParams(array $query): ServerRequestInterface
281 {
282 $new = clone $this;
283 $new->queryParams = $query;
284
285 return $new;
286 }
287
288 /**
289 * @return array|object|null
290 */
291 public function getParsedBody()
292 {
293 return $this->parsedBody;
294 }
295
296 public function withParsedBody($data): ServerRequestInterface
297 {
298 $new = clone $this;
299 $new->parsedBody = $data;
300
301 return $new;
302 }
303
304 public function getAttributes(): array
305 {
306 return $this->attributes;
307 }
308
309 /**
310 * @return mixed
311 */
312 public function getAttribute($attribute, $default = null)
313 {
314 if (false === array_key_exists($attribute, $this->attributes)) {
315 return $default;
316 }
317
318 return $this->attributes[$attribute];
319 }
320
321 public function withAttribute($attribute, $value): ServerRequestInterface
322 {
323 $new = clone $this;
324 $new->attributes[$attribute] = $value;
325
326 return $new;
327 }
328
329 public function withoutAttribute($attribute): ServerRequestInterface
330 {
331 if (false === array_key_exists($attribute, $this->attributes)) {
332 return $this;
333 }
334
335 $new = clone $this;
336 unset($new->attributes[$attribute]);
337
338 return $new;
339 }
340 }
341