Browse code

added appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:35:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,340 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+namespace GuzzleHttp\Psr7;
6
+
7
+use InvalidArgumentException;
8
+use Psr\Http\Message\ServerRequestInterface;
9
+use Psr\Http\Message\StreamInterface;
10
+use Psr\Http\Message\UploadedFileInterface;
11
+use 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
+}
Browse code

removed appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:12:22
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,378 +0,0 @@
1
-<?php
2
-
3
-namespace GuzzleHttp\Psr7;
4
-
5
-use InvalidArgumentException;
6
-use Psr\Http\Message\ServerRequestInterface;
7
-use Psr\Http\Message\UriInterface;
8
-use Psr\Http\Message\StreamInterface;
9
-use Psr\Http\Message\UploadedFileInterface;
10
-
11
-/**
12
- * Server-side HTTP request
13
- *
14
- * Extends the Request definition to add methods for accessing incoming data,
15
- * specifically server parameters, cookies, matched path parameters, query
16
- * string arguments, body parameters, and upload file information.
17
- *
18
- * "Attributes" are discovered via decomposing the request (and usually
19
- * specifically the URI path), and typically will be injected by the application.
20
- *
21
- * Requests are considered immutable; all methods that might change state are
22
- * implemented such that they retain the internal state of the current
23
- * message and return a new instance that contains the changed state.
24
- */
25
-class ServerRequest extends Request implements ServerRequestInterface
26
-{
27
-    /**
28
-     * @var array
29
-     */
30
-    private $attributes = [];
31
-
32
-    /**
33
-     * @var array
34
-     */
35
-    private $cookieParams = [];
36
-
37
-    /**
38
-     * @var null|array|object
39
-     */
40
-    private $parsedBody;
41
-
42
-    /**
43
-     * @var array
44
-     */
45
-    private $queryParams = [];
46
-
47
-    /**
48
-     * @var array
49
-     */
50
-    private $serverParams;
51
-
52
-    /**
53
-     * @var array
54
-     */
55
-    private $uploadedFiles = [];
56
-
57
-    /**
58
-     * @param string                               $method       HTTP method
59
-     * @param string|UriInterface                  $uri          URI
60
-     * @param array                                $headers      Request headers
61
-     * @param string|null|resource|StreamInterface $body         Request body
62
-     * @param string                               $version      Protocol version
63
-     * @param array                                $serverParams Typically the $_SERVER superglobal
64
-     */
65
-    public function __construct(
66
-        $method,
67
-        $uri,
68
-        array $headers = [],
69
-        $body = null,
70
-        $version = '1.1',
71
-        array $serverParams = []
72
-    ) {
73
-        $this->serverParams = $serverParams;
74
-
75
-        parent::__construct($method, $uri, $headers, $body, $version);
76
-    }
77
-
78
-    /**
79
-     * Return an UploadedFile instance array.
80
-     *
81
-     * @param array $files A array which respect $_FILES structure
82
-     *
83
-     * @return array
84
-     *
85
-     * @throws InvalidArgumentException for unrecognized values
86
-     */
87
-    public static function normalizeFiles(array $files)
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
-     * @return array|UploadedFileInterface
115
-     */
116
-    private static function createUploadedFileFromSpec(array $value)
117
-    {
118
-        if (is_array($value['tmp_name'])) {
119
-            return self::normalizeNestedFileSpec($value);
120
-        }
121
-
122
-        return new UploadedFile(
123
-            $value['tmp_name'],
124
-            (int) $value['size'],
125
-            (int) $value['error'],
126
-            $value['name'],
127
-            $value['type']
128
-        );
129
-    }
130
-
131
-    /**
132
-     * Normalize an array of file specifications.
133
-     *
134
-     * Loops through all nested files and returns a normalized array of
135
-     * UploadedFileInterface instances.
136
-     *
137
-     * @param array $files
138
-     * @return UploadedFileInterface[]
139
-     */
140
-    private static function normalizeNestedFileSpec(array $files = [])
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],
148
-                'error'    => $files['error'][$key],
149
-                'name'     => $files['name'][$key],
150
-                'type'     => $files['type'][$key],
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
-     * @return ServerRequestInterface
167
-     */
168
-    public static function fromGlobals()
169
-    {
170
-        $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
171
-        $headers = getallheaders();
172
-        $uri = self::getUriFromGlobals();
173
-        $body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
174
-        $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
175
-
176
-        $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
177
-
178
-        return $serverRequest
179
-            ->withCookieParams($_COOKIE)
180
-            ->withQueryParams($_GET)
181
-            ->withParsedBody($_POST)
182
-            ->withUploadedFiles(self::normalizeFiles($_FILES));
183
-    }
184
-
185
-    private static function extractHostAndPortFromAuthority($authority)
186
-    {
187
-        $uri = 'http://'.$authority;
188
-        $parts = parse_url($uri);
189
-        if (false === $parts) {
190
-            return [null, null];
191
-        }
192
-
193
-        $host = isset($parts['host']) ? $parts['host'] : null;
194
-        $port = isset($parts['port']) ? $parts['port'] : null;
195
-
196
-        return [$host, $port];
197
-    }
198
-
199
-    /**
200
-     * Get a Uri populated with values from $_SERVER.
201
-     *
202
-     * @return UriInterface
203
-     */
204
-    public static function getUriFromGlobals()
205
-    {
206
-        $uri = new Uri('');
207
-
208
-        $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
209
-
210
-        $hasPort = false;
211
-        if (isset($_SERVER['HTTP_HOST'])) {
212
-            list($host, $port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
213
-            if ($host !== null) {
214
-                $uri = $uri->withHost($host);
215
-            }
216
-
217
-            if ($port !== null) {
218
-                $hasPort = true;
219
-                $uri = $uri->withPort($port);
220
-            }
221
-        } elseif (isset($_SERVER['SERVER_NAME'])) {
222
-            $uri = $uri->withHost($_SERVER['SERVER_NAME']);
223
-        } elseif (isset($_SERVER['SERVER_ADDR'])) {
224
-            $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
225
-        }
226
-
227
-        if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
228
-            $uri = $uri->withPort($_SERVER['SERVER_PORT']);
229
-        }
230
-
231
-        $hasQuery = false;
232
-        if (isset($_SERVER['REQUEST_URI'])) {
233
-            $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2);
234
-            $uri = $uri->withPath($requestUriParts[0]);
235
-            if (isset($requestUriParts[1])) {
236
-                $hasQuery = true;
237
-                $uri = $uri->withQuery($requestUriParts[1]);
238
-            }
239
-        }
240
-
241
-        if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
242
-            $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
243
-        }
244
-
245
-        return $uri;
246
-    }
247
-
248
-
249
-    /**
250
-     * {@inheritdoc}
251
-     */
252
-    public function getServerParams()
253
-    {
254
-        return $this->serverParams;
255
-    }
256
-
257
-    /**
258
-     * {@inheritdoc}
259
-     */
260
-    public function getUploadedFiles()
261
-    {
262
-        return $this->uploadedFiles;
263
-    }
264
-
265
-    /**
266
-     * {@inheritdoc}
267
-     */
268
-    public function withUploadedFiles(array $uploadedFiles)
269
-    {
270
-        $new = clone $this;
271
-        $new->uploadedFiles = $uploadedFiles;
272
-
273
-        return $new;
274
-    }
275
-
276
-    /**
277
-     * {@inheritdoc}
278
-     */
279
-    public function getCookieParams()
280
-    {
281
-        return $this->cookieParams;
282
-    }
283
-
284
-    /**
285
-     * {@inheritdoc}
286
-     */
287
-    public function withCookieParams(array $cookies)
288
-    {
289
-        $new = clone $this;
290
-        $new->cookieParams = $cookies;
291
-
292
-        return $new;
293
-    }
294
-
295
-    /**
296
-     * {@inheritdoc}
297
-     */
298
-    public function getQueryParams()
299
-    {
300
-        return $this->queryParams;
301
-    }
302
-
303
-    /**
304
-     * {@inheritdoc}
305
-     */
306
-    public function withQueryParams(array $query)
307
-    {
308
-        $new = clone $this;
309
-        $new->queryParams = $query;
310
-
311
-        return $new;
312
-    }
313
-
314
-    /**
315
-     * {@inheritdoc}
316
-     */
317
-    public function getParsedBody()
318
-    {
319
-        return $this->parsedBody;
320
-    }
321
-
322
-    /**
323
-     * {@inheritdoc}
324
-     */
325
-    public function withParsedBody($data)
326
-    {
327
-        $new = clone $this;
328
-        $new->parsedBody = $data;
329
-
330
-        return $new;
331
-    }
332
-
333
-    /**
334
-     * {@inheritdoc}
335
-     */
336
-    public function getAttributes()
337
-    {
338
-        return $this->attributes;
339
-    }
340
-
341
-    /**
342
-     * {@inheritdoc}
343
-     */
344
-    public function getAttribute($attribute, $default = null)
345
-    {
346
-        if (false === array_key_exists($attribute, $this->attributes)) {
347
-            return $default;
348
-        }
349
-
350
-        return $this->attributes[$attribute];
351
-    }
352
-
353
-    /**
354
-     * {@inheritdoc}
355
-     */
356
-    public function withAttribute($attribute, $value)
357
-    {
358
-        $new = clone $this;
359
-        $new->attributes[$attribute] = $value;
360
-
361
-        return $new;
362
-    }
363
-
364
-    /**
365
-     * {@inheritdoc}
366
-     */
367
-    public function withoutAttribute($attribute)
368
-    {
369
-        if (false === array_key_exists($attribute, $this->attributes)) {
370
-            return $this;
371
-        }
372
-
373
-        $new = clone $this;
374
-        unset($new->attributes[$attribute]);
375
-
376
-        return $new;
377
-    }
378
-}
Browse code

Added README.md appinfo/info.xml appinfo/signature.json lib/Controller/AuthorApiController.php and the providers directory

DoubleBastionAdmin authored on 20/08/2022 16:33:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,378 @@
1
+<?php
2
+
3
+namespace GuzzleHttp\Psr7;
4
+
5
+use InvalidArgumentException;
6
+use Psr\Http\Message\ServerRequestInterface;
7
+use Psr\Http\Message\UriInterface;
8
+use Psr\Http\Message\StreamInterface;
9
+use Psr\Http\Message\UploadedFileInterface;
10
+
11
+/**
12
+ * Server-side HTTP request
13
+ *
14
+ * Extends the Request definition to add methods for accessing incoming data,
15
+ * specifically server parameters, cookies, matched path parameters, query
16
+ * string arguments, body parameters, and upload file information.
17
+ *
18
+ * "Attributes" are discovered via decomposing the request (and usually
19
+ * specifically the URI path), and typically will be injected by the application.
20
+ *
21
+ * Requests are considered immutable; all methods that might change state are
22
+ * implemented such that they retain the internal state of the current
23
+ * message and return a new instance that contains the changed state.
24
+ */
25
+class ServerRequest extends Request implements ServerRequestInterface
26
+{
27
+    /**
28
+     * @var array
29
+     */
30
+    private $attributes = [];
31
+
32
+    /**
33
+     * @var array
34
+     */
35
+    private $cookieParams = [];
36
+
37
+    /**
38
+     * @var null|array|object
39
+     */
40
+    private $parsedBody;
41
+
42
+    /**
43
+     * @var array
44
+     */
45
+    private $queryParams = [];
46
+
47
+    /**
48
+     * @var array
49
+     */
50
+    private $serverParams;
51
+
52
+    /**
53
+     * @var array
54
+     */
55
+    private $uploadedFiles = [];
56
+
57
+    /**
58
+     * @param string                               $method       HTTP method
59
+     * @param string|UriInterface                  $uri          URI
60
+     * @param array                                $headers      Request headers
61
+     * @param string|null|resource|StreamInterface $body         Request body
62
+     * @param string                               $version      Protocol version
63
+     * @param array                                $serverParams Typically the $_SERVER superglobal
64
+     */
65
+    public function __construct(
66
+        $method,
67
+        $uri,
68
+        array $headers = [],
69
+        $body = null,
70
+        $version = '1.1',
71
+        array $serverParams = []
72
+    ) {
73
+        $this->serverParams = $serverParams;
74
+
75
+        parent::__construct($method, $uri, $headers, $body, $version);
76
+    }
77
+
78
+    /**
79
+     * Return an UploadedFile instance array.
80
+     *
81
+     * @param array $files A array which respect $_FILES structure
82
+     *
83
+     * @return array
84
+     *
85
+     * @throws InvalidArgumentException for unrecognized values
86
+     */
87
+    public static function normalizeFiles(array $files)
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
+     * @return array|UploadedFileInterface
115
+     */
116
+    private static function createUploadedFileFromSpec(array $value)
117
+    {
118
+        if (is_array($value['tmp_name'])) {
119
+            return self::normalizeNestedFileSpec($value);
120
+        }
121
+
122
+        return new UploadedFile(
123
+            $value['tmp_name'],
124
+            (int) $value['size'],
125
+            (int) $value['error'],
126
+            $value['name'],
127
+            $value['type']
128
+        );
129
+    }
130
+
131
+    /**
132
+     * Normalize an array of file specifications.
133
+     *
134
+     * Loops through all nested files and returns a normalized array of
135
+     * UploadedFileInterface instances.
136
+     *
137
+     * @param array $files
138
+     * @return UploadedFileInterface[]
139
+     */
140
+    private static function normalizeNestedFileSpec(array $files = [])
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],
148
+                'error'    => $files['error'][$key],
149
+                'name'     => $files['name'][$key],
150
+                'type'     => $files['type'][$key],
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
+     * @return ServerRequestInterface
167
+     */
168
+    public static function fromGlobals()
169
+    {
170
+        $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
171
+        $headers = getallheaders();
172
+        $uri = self::getUriFromGlobals();
173
+        $body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
174
+        $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
175
+
176
+        $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
177
+
178
+        return $serverRequest
179
+            ->withCookieParams($_COOKIE)
180
+            ->withQueryParams($_GET)
181
+            ->withParsedBody($_POST)
182
+            ->withUploadedFiles(self::normalizeFiles($_FILES));
183
+    }
184
+
185
+    private static function extractHostAndPortFromAuthority($authority)
186
+    {
187
+        $uri = 'http://'.$authority;
188
+        $parts = parse_url($uri);
189
+        if (false === $parts) {
190
+            return [null, null];
191
+        }
192
+
193
+        $host = isset($parts['host']) ? $parts['host'] : null;
194
+        $port = isset($parts['port']) ? $parts['port'] : null;
195
+
196
+        return [$host, $port];
197
+    }
198
+
199
+    /**
200
+     * Get a Uri populated with values from $_SERVER.
201
+     *
202
+     * @return UriInterface
203
+     */
204
+    public static function getUriFromGlobals()
205
+    {
206
+        $uri = new Uri('');
207
+
208
+        $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
209
+
210
+        $hasPort = false;
211
+        if (isset($_SERVER['HTTP_HOST'])) {
212
+            list($host, $port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
213
+            if ($host !== null) {
214
+                $uri = $uri->withHost($host);
215
+            }
216
+
217
+            if ($port !== null) {
218
+                $hasPort = true;
219
+                $uri = $uri->withPort($port);
220
+            }
221
+        } elseif (isset($_SERVER['SERVER_NAME'])) {
222
+            $uri = $uri->withHost($_SERVER['SERVER_NAME']);
223
+        } elseif (isset($_SERVER['SERVER_ADDR'])) {
224
+            $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
225
+        }
226
+
227
+        if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
228
+            $uri = $uri->withPort($_SERVER['SERVER_PORT']);
229
+        }
230
+
231
+        $hasQuery = false;
232
+        if (isset($_SERVER['REQUEST_URI'])) {
233
+            $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2);
234
+            $uri = $uri->withPath($requestUriParts[0]);
235
+            if (isset($requestUriParts[1])) {
236
+                $hasQuery = true;
237
+                $uri = $uri->withQuery($requestUriParts[1]);
238
+            }
239
+        }
240
+
241
+        if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
242
+            $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
243
+        }
244
+
245
+        return $uri;
246
+    }
247
+
248
+
249
+    /**
250
+     * {@inheritdoc}
251
+     */
252
+    public function getServerParams()
253
+    {
254
+        return $this->serverParams;
255
+    }
256
+
257
+    /**
258
+     * {@inheritdoc}
259
+     */
260
+    public function getUploadedFiles()
261
+    {
262
+        return $this->uploadedFiles;
263
+    }
264
+
265
+    /**
266
+     * {@inheritdoc}
267
+     */
268
+    public function withUploadedFiles(array $uploadedFiles)
269
+    {
270
+        $new = clone $this;
271
+        $new->uploadedFiles = $uploadedFiles;
272
+
273
+        return $new;
274
+    }
275
+
276
+    /**
277
+     * {@inheritdoc}
278
+     */
279
+    public function getCookieParams()
280
+    {
281
+        return $this->cookieParams;
282
+    }
283
+
284
+    /**
285
+     * {@inheritdoc}
286
+     */
287
+    public function withCookieParams(array $cookies)
288
+    {
289
+        $new = clone $this;
290
+        $new->cookieParams = $cookies;
291
+
292
+        return $new;
293
+    }
294
+
295
+    /**
296
+     * {@inheritdoc}
297
+     */
298
+    public function getQueryParams()
299
+    {
300
+        return $this->queryParams;
301
+    }
302
+
303
+    /**
304
+     * {@inheritdoc}
305
+     */
306
+    public function withQueryParams(array $query)
307
+    {
308
+        $new = clone $this;
309
+        $new->queryParams = $query;
310
+
311
+        return $new;
312
+    }
313
+
314
+    /**
315
+     * {@inheritdoc}
316
+     */
317
+    public function getParsedBody()
318
+    {
319
+        return $this->parsedBody;
320
+    }
321
+
322
+    /**
323
+     * {@inheritdoc}
324
+     */
325
+    public function withParsedBody($data)
326
+    {
327
+        $new = clone $this;
328
+        $new->parsedBody = $data;
329
+
330
+        return $new;
331
+    }
332
+
333
+    /**
334
+     * {@inheritdoc}
335
+     */
336
+    public function getAttributes()
337
+    {
338
+        return $this->attributes;
339
+    }
340
+
341
+    /**
342
+     * {@inheritdoc}
343
+     */
344
+    public function getAttribute($attribute, $default = null)
345
+    {
346
+        if (false === array_key_exists($attribute, $this->attributes)) {
347
+            return $default;
348
+        }
349
+
350
+        return $this->attributes[$attribute];
351
+    }
352
+
353
+    /**
354
+     * {@inheritdoc}
355
+     */
356
+    public function withAttribute($attribute, $value)
357
+    {
358
+        $new = clone $this;
359
+        $new->attributes[$attribute] = $value;
360
+
361
+        return $new;
362
+    }
363
+
364
+    /**
365
+     * {@inheritdoc}
366
+     */
367
+    public function withoutAttribute($attribute)
368
+    {
369
+        if (false === array_key_exists($attribute, $this->attributes)) {
370
+            return $this;
371
+        }
372
+
373
+        $new = clone $this;
374
+        unset($new->attributes[$attribute]);
375
+
376
+        return $new;
377
+    }
378
+}