Security update for Core, with self-updated composer
[yaffs-website] / vendor / zendframework / zend-diactoros / src / ServerRequest.php
1 <?php
2 /**
3  * @see       https://github.com/zendframework/zend-diactoros for the canonical source repository
4  * @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://www.zend.com)
5  * @license   https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
6  */
7
8 namespace Zend\Diactoros;
9
10 use InvalidArgumentException;
11 use Psr\Http\Message\ServerRequestInterface;
12 use Psr\Http\Message\StreamInterface;
13 use Psr\Http\Message\UploadedFileInterface;
14 use Psr\Http\Message\UriInterface;
15
16 /**
17  * Server-side HTTP request
18  *
19  * Extends the Request definition to add methods for accessing incoming data,
20  * specifically server parameters, cookies, matched path parameters, query
21  * string arguments, body parameters, and upload file information.
22  *
23  * "Attributes" are discovered via decomposing the request (and usually
24  * specifically the URI path), and typically will be injected by the application.
25  *
26  * Requests are considered immutable; all methods that might change state are
27  * implemented such that they retain the internal state of the current
28  * message and return a new instance that contains the changed state.
29  */
30 class ServerRequest implements ServerRequestInterface
31 {
32     use RequestTrait;
33
34     /**
35      * @var array
36      */
37     private $attributes = [];
38
39     /**
40      * @var array
41      */
42     private $cookieParams = [];
43
44     /**
45      * @var null|array|object
46      */
47     private $parsedBody;
48
49     /**
50      * @var array
51      */
52     private $queryParams = [];
53
54     /**
55      * @var array
56      */
57     private $serverParams;
58
59     /**
60      * @var array
61      */
62     private $uploadedFiles;
63
64     /**
65      * @param array $serverParams Server parameters, typically from $_SERVER
66      * @param array $uploadedFiles Upload file information, a tree of UploadedFiles
67      * @param null|string|UriInterface $uri URI for the request, if any.
68      * @param null|string $method HTTP method for the request, if any.
69      * @param string|resource|StreamInterface $body Message body, if any.
70      * @param array $headers Headers for the message, if any.
71      * @param array $cookies Cookies for the message, if any.
72      * @param array $queryParams Query params for the message, if any.
73      * @param null|array|object $parsedBody The deserialized body parameters, if any.
74      * @param string $protocol HTTP protocol version.
75      * @throws InvalidArgumentException for any invalid value.
76      */
77     public function __construct(
78         array $serverParams = [],
79         array $uploadedFiles = [],
80         $uri = null,
81         $method = null,
82         $body = 'php://input',
83         array $headers = [],
84         array $cookies = [],
85         array $queryParams = [],
86         $parsedBody = null,
87         $protocol = '1.1'
88     ) {
89         $this->validateUploadedFiles($uploadedFiles);
90
91         if ($body === 'php://input') {
92             $body = new PhpInputStream();
93         }
94
95         $this->initialize($uri, $method, $body, $headers);
96         $this->serverParams  = $serverParams;
97         $this->uploadedFiles = $uploadedFiles;
98         $this->cookieParams  = $cookies;
99         $this->queryParams   = $queryParams;
100         $this->parsedBody    = $parsedBody;
101         $this->protocol      = $protocol;
102     }
103
104     /**
105      * {@inheritdoc}
106      */
107     public function getServerParams()
108     {
109         return $this->serverParams;
110     }
111
112     /**
113      * {@inheritdoc}
114      */
115     public function getUploadedFiles()
116     {
117         return $this->uploadedFiles;
118     }
119
120     /**
121      * {@inheritdoc}
122      */
123     public function withUploadedFiles(array $uploadedFiles)
124     {
125         $this->validateUploadedFiles($uploadedFiles);
126         $new = clone $this;
127         $new->uploadedFiles = $uploadedFiles;
128         return $new;
129     }
130
131     /**
132      * {@inheritdoc}
133      */
134     public function getCookieParams()
135     {
136         return $this->cookieParams;
137     }
138
139     /**
140      * {@inheritdoc}
141      */
142     public function withCookieParams(array $cookies)
143     {
144         $new = clone $this;
145         $new->cookieParams = $cookies;
146         return $new;
147     }
148
149     /**
150      * {@inheritdoc}
151      */
152     public function getQueryParams()
153     {
154         return $this->queryParams;
155     }
156
157     /**
158      * {@inheritdoc}
159      */
160     public function withQueryParams(array $query)
161     {
162         $new = clone $this;
163         $new->queryParams = $query;
164         return $new;
165     }
166
167     /**
168      * {@inheritdoc}
169      */
170     public function getParsedBody()
171     {
172         return $this->parsedBody;
173     }
174
175     /**
176      * {@inheritdoc}
177      */
178     public function withParsedBody($data)
179     {
180         $new = clone $this;
181         $new->parsedBody = $data;
182         return $new;
183     }
184
185     /**
186      * {@inheritdoc}
187      */
188     public function getAttributes()
189     {
190         return $this->attributes;
191     }
192
193     /**
194      * {@inheritdoc}
195      */
196     public function getAttribute($attribute, $default = null)
197     {
198         if (! array_key_exists($attribute, $this->attributes)) {
199             return $default;
200         }
201
202         return $this->attributes[$attribute];
203     }
204
205     /**
206      * {@inheritdoc}
207      */
208     public function withAttribute($attribute, $value)
209     {
210         $new = clone $this;
211         $new->attributes[$attribute] = $value;
212         return $new;
213     }
214
215     /**
216      * {@inheritdoc}
217      */
218     public function withoutAttribute($attribute)
219     {
220         $new = clone $this;
221         unset($new->attributes[$attribute]);
222         return $new;
223     }
224
225     /**
226      * Proxy to receive the request method.
227      *
228      * This overrides the parent functionality to ensure the method is never
229      * empty; if no method is present, it returns 'GET'.
230      *
231      * @return string
232      */
233     public function getMethod()
234     {
235         if (empty($this->method)) {
236             return 'GET';
237         }
238         return $this->method;
239     }
240
241     /**
242      * Set the request method.
243      *
244      * Unlike the regular Request implementation, the server-side
245      * normalizes the method to uppercase to ensure consistency
246      * and make checking the method simpler.
247      *
248      * This methods returns a new instance.
249      *
250      * @param string $method
251      * @return self
252      */
253     public function withMethod($method)
254     {
255         $this->validateMethod($method);
256         $new = clone $this;
257         $new->method = $method;
258         return $new;
259     }
260
261     /**
262      * Recursively validate the structure in an uploaded files array.
263      *
264      * @param array $uploadedFiles
265      * @throws InvalidArgumentException if any leaf is not an UploadedFileInterface instance.
266      */
267     private function validateUploadedFiles(array $uploadedFiles)
268     {
269         foreach ($uploadedFiles as $file) {
270             if (is_array($file)) {
271                 $this->validateUploadedFiles($file);
272                 continue;
273             }
274
275             if (! $file instanceof UploadedFileInterface) {
276                 throw new InvalidArgumentException('Invalid leaf in uploaded files structure');
277             }
278         }
279     }
280 }