Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Bridge\PsrHttpMessage\Factory;
|
Chris@0
|
13
|
Chris@0
|
14 use Psr\Http\Message\ServerRequestInterface;
|
Chris@0
|
15 use Psr\Http\Message\ResponseInterface;
|
Chris@0
|
16 use Psr\Http\Message\UploadedFileInterface;
|
Chris@0
|
17 use Psr\Http\Message\UriInterface;
|
Chris@0
|
18 use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
|
Chris@0
|
19 use Symfony\Component\HttpFoundation\Cookie;
|
Chris@0
|
20 use Symfony\Component\HttpFoundation\File\UploadedFile;
|
Chris@0
|
21 use Symfony\Component\HttpFoundation\Request;
|
Chris@0
|
22 use Symfony\Component\HttpFoundation\Response;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * {@inheritdoc}
|
Chris@0
|
26 *
|
Chris@0
|
27 * @author Kévin Dunglas <dunglas@gmail.com>
|
Chris@0
|
28 */
|
Chris@0
|
29 class HttpFoundationFactory implements HttpFoundationFactoryInterface
|
Chris@0
|
30 {
|
Chris@0
|
31 /**
|
Chris@0
|
32 * {@inheritdoc}
|
Chris@0
|
33 */
|
Chris@0
|
34 public function createRequest(ServerRequestInterface $psrRequest)
|
Chris@0
|
35 {
|
Chris@0
|
36 $server = array();
|
Chris@0
|
37 $uri = $psrRequest->getUri();
|
Chris@0
|
38
|
Chris@0
|
39 if ($uri instanceof UriInterface) {
|
Chris@0
|
40 $server['SERVER_NAME'] = $uri->getHost();
|
Chris@0
|
41 $server['SERVER_PORT'] = $uri->getPort();
|
Chris@0
|
42 $server['REQUEST_URI'] = $uri->getPath();
|
Chris@0
|
43 $server['QUERY_STRING'] = $uri->getQuery();
|
Chris@0
|
44 }
|
Chris@0
|
45
|
Chris@0
|
46 $server['REQUEST_METHOD'] = $psrRequest->getMethod();
|
Chris@0
|
47
|
Chris@0
|
48 $server = array_replace($server, $psrRequest->getServerParams());
|
Chris@0
|
49
|
Chris@0
|
50 $parsedBody = $psrRequest->getParsedBody();
|
Chris@0
|
51 $parsedBody = is_array($parsedBody) ? $parsedBody : array();
|
Chris@0
|
52
|
Chris@0
|
53 $request = new Request(
|
Chris@0
|
54 $psrRequest->getQueryParams(),
|
Chris@0
|
55 $parsedBody,
|
Chris@0
|
56 $psrRequest->getAttributes(),
|
Chris@0
|
57 $psrRequest->getCookieParams(),
|
Chris@0
|
58 $this->getFiles($psrRequest->getUploadedFiles()),
|
Chris@0
|
59 $server,
|
Chris@0
|
60 $psrRequest->getBody()->__toString()
|
Chris@0
|
61 );
|
Chris@0
|
62 $request->headers->replace($psrRequest->getHeaders());
|
Chris@0
|
63
|
Chris@0
|
64 return $request;
|
Chris@0
|
65 }
|
Chris@0
|
66
|
Chris@0
|
67 /**
|
Chris@0
|
68 * Converts to the input array to $_FILES structure.
|
Chris@0
|
69 *
|
Chris@0
|
70 * @param array $uploadedFiles
|
Chris@0
|
71 *
|
Chris@0
|
72 * @return array
|
Chris@0
|
73 */
|
Chris@0
|
74 private function getFiles(array $uploadedFiles)
|
Chris@0
|
75 {
|
Chris@0
|
76 $files = array();
|
Chris@0
|
77
|
Chris@0
|
78 foreach ($uploadedFiles as $key => $value) {
|
Chris@0
|
79 if ($value instanceof UploadedFileInterface) {
|
Chris@0
|
80 $files[$key] = $this->createUploadedFile($value);
|
Chris@0
|
81 } else {
|
Chris@0
|
82 $files[$key] = $this->getFiles($value);
|
Chris@0
|
83 }
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 return $files;
|
Chris@0
|
87 }
|
Chris@0
|
88
|
Chris@0
|
89 /**
|
Chris@0
|
90 * Creates Symfony UploadedFile instance from PSR-7 ones.
|
Chris@0
|
91 *
|
Chris@0
|
92 * @param UploadedFileInterface $psrUploadedFile
|
Chris@0
|
93 *
|
Chris@0
|
94 * @return UploadedFile
|
Chris@0
|
95 */
|
Chris@0
|
96 private function createUploadedFile(UploadedFileInterface $psrUploadedFile)
|
Chris@0
|
97 {
|
Chris@0
|
98 $temporaryPath = '';
|
Chris@0
|
99 $clientFileName = '';
|
Chris@0
|
100 if (UPLOAD_ERR_NO_FILE !== $psrUploadedFile->getError()) {
|
Chris@0
|
101 $temporaryPath = $this->getTemporaryPath();
|
Chris@0
|
102 $psrUploadedFile->moveTo($temporaryPath);
|
Chris@0
|
103
|
Chris@0
|
104 $clientFileName = $psrUploadedFile->getClientFilename();
|
Chris@0
|
105 }
|
Chris@0
|
106
|
Chris@17
|
107 if (class_exists('Symfony\Component\HttpFoundation\HeaderUtils')) {
|
Chris@17
|
108 // Symfony 4.1+
|
Chris@17
|
109 return new UploadedFile(
|
Chris@17
|
110 $temporaryPath,
|
Chris@17
|
111 null === $clientFileName ? '' : $clientFileName,
|
Chris@17
|
112 $psrUploadedFile->getClientMediaType(),
|
Chris@17
|
113 $psrUploadedFile->getError(),
|
Chris@17
|
114 true
|
Chris@17
|
115 );
|
Chris@17
|
116 }
|
Chris@17
|
117
|
Chris@0
|
118 return new UploadedFile(
|
Chris@0
|
119 $temporaryPath,
|
Chris@0
|
120 null === $clientFileName ? '' : $clientFileName,
|
Chris@0
|
121 $psrUploadedFile->getClientMediaType(),
|
Chris@0
|
122 $psrUploadedFile->getSize(),
|
Chris@0
|
123 $psrUploadedFile->getError(),
|
Chris@0
|
124 true
|
Chris@0
|
125 );
|
Chris@0
|
126 }
|
Chris@0
|
127
|
Chris@0
|
128 /**
|
Chris@0
|
129 * Gets a temporary file path.
|
Chris@0
|
130 *
|
Chris@0
|
131 * @return string
|
Chris@0
|
132 */
|
Chris@0
|
133 protected function getTemporaryPath()
|
Chris@0
|
134 {
|
Chris@0
|
135 return tempnam(sys_get_temp_dir(), uniqid('symfony', true));
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@0
|
138 /**
|
Chris@0
|
139 * {@inheritdoc}
|
Chris@0
|
140 */
|
Chris@0
|
141 public function createResponse(ResponseInterface $psrResponse)
|
Chris@0
|
142 {
|
Chris@18
|
143 $cookies = $psrResponse->getHeader('Set-Cookie');
|
Chris@18
|
144 $psrResponse = $psrResponse->withoutHeader('Set-Cookie');
|
Chris@18
|
145
|
Chris@0
|
146 $response = new Response(
|
Chris@0
|
147 $psrResponse->getBody()->__toString(),
|
Chris@0
|
148 $psrResponse->getStatusCode(),
|
Chris@0
|
149 $psrResponse->getHeaders()
|
Chris@0
|
150 );
|
Chris@0
|
151 $response->setProtocolVersion($psrResponse->getProtocolVersion());
|
Chris@0
|
152
|
Chris@18
|
153 foreach ($cookies as $cookie) {
|
Chris@0
|
154 $response->headers->setCookie($this->createCookie($cookie));
|
Chris@0
|
155 }
|
Chris@0
|
156
|
Chris@0
|
157 return $response;
|
Chris@0
|
158 }
|
Chris@0
|
159
|
Chris@0
|
160 /**
|
Chris@0
|
161 * Creates a Cookie instance from a cookie string.
|
Chris@0
|
162 *
|
Chris@0
|
163 * Some snippets have been taken from the Guzzle project: https://github.com/guzzle/guzzle/blob/5.3/src/Cookie/SetCookie.php#L34
|
Chris@0
|
164 *
|
Chris@0
|
165 * @param string $cookie
|
Chris@0
|
166 *
|
Chris@0
|
167 * @return Cookie
|
Chris@0
|
168 *
|
Chris@0
|
169 * @throws \InvalidArgumentException
|
Chris@0
|
170 */
|
Chris@0
|
171 private function createCookie($cookie)
|
Chris@0
|
172 {
|
Chris@0
|
173 foreach (explode(';', $cookie) as $part) {
|
Chris@0
|
174 $part = trim($part);
|
Chris@0
|
175
|
Chris@0
|
176 $data = explode('=', $part, 2);
|
Chris@0
|
177 $name = $data[0];
|
Chris@0
|
178 $value = isset($data[1]) ? trim($data[1], " \n\r\t\0\x0B\"") : null;
|
Chris@0
|
179
|
Chris@0
|
180 if (!isset($cookieName)) {
|
Chris@0
|
181 $cookieName = $name;
|
Chris@0
|
182 $cookieValue = $value;
|
Chris@0
|
183
|
Chris@0
|
184 continue;
|
Chris@0
|
185 }
|
Chris@0
|
186
|
Chris@0
|
187 if ('expires' === strtolower($name) && null !== $value) {
|
Chris@0
|
188 $cookieExpire = new \DateTime($value);
|
Chris@0
|
189
|
Chris@0
|
190 continue;
|
Chris@0
|
191 }
|
Chris@0
|
192
|
Chris@0
|
193 if ('path' === strtolower($name) && null !== $value) {
|
Chris@0
|
194 $cookiePath = $value;
|
Chris@0
|
195
|
Chris@0
|
196 continue;
|
Chris@0
|
197 }
|
Chris@0
|
198
|
Chris@0
|
199 if ('domain' === strtolower($name) && null !== $value) {
|
Chris@0
|
200 $cookieDomain = $value;
|
Chris@0
|
201
|
Chris@0
|
202 continue;
|
Chris@0
|
203 }
|
Chris@0
|
204
|
Chris@0
|
205 if ('secure' === strtolower($name)) {
|
Chris@0
|
206 $cookieSecure = true;
|
Chris@0
|
207
|
Chris@0
|
208 continue;
|
Chris@0
|
209 }
|
Chris@0
|
210
|
Chris@0
|
211 if ('httponly' === strtolower($name)) {
|
Chris@0
|
212 $cookieHttpOnly = true;
|
Chris@0
|
213
|
Chris@0
|
214 continue;
|
Chris@0
|
215 }
|
Chris@18
|
216
|
Chris@18
|
217 if ('samesite' === strtolower($name) && null !== $value) {
|
Chris@18
|
218 $samesite = $value;
|
Chris@18
|
219
|
Chris@18
|
220 continue;
|
Chris@18
|
221 }
|
Chris@0
|
222 }
|
Chris@0
|
223
|
Chris@0
|
224 if (!isset($cookieName)) {
|
Chris@0
|
225 throw new \InvalidArgumentException('The value of the Set-Cookie header is malformed.');
|
Chris@0
|
226 }
|
Chris@0
|
227
|
Chris@0
|
228 return new Cookie(
|
Chris@0
|
229 $cookieName,
|
Chris@0
|
230 $cookieValue,
|
Chris@0
|
231 isset($cookieExpire) ? $cookieExpire : 0,
|
Chris@0
|
232 isset($cookiePath) ? $cookiePath : '/',
|
Chris@0
|
233 isset($cookieDomain) ? $cookieDomain : null,
|
Chris@0
|
234 isset($cookieSecure),
|
Chris@18
|
235 isset($cookieHttpOnly),
|
Chris@18
|
236 false,
|
Chris@18
|
237 isset($samesite) ? $samesite : null
|
Chris@0
|
238 );
|
Chris@0
|
239 }
|
Chris@0
|
240 }
|