Chris@17
|
1 <?php
|
Chris@17
|
2
|
Chris@17
|
3 /*
|
Chris@17
|
4 * This file is part of the Symfony package.
|
Chris@17
|
5 *
|
Chris@17
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@17
|
7 *
|
Chris@17
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@17
|
9 * file that was distributed with this source code.
|
Chris@17
|
10 */
|
Chris@17
|
11
|
Chris@17
|
12 namespace Symfony\Bridge\PsrHttpMessage\Factory;
|
Chris@17
|
13
|
Chris@17
|
14 use Psr\Http\Message\ResponseFactoryInterface;
|
Chris@17
|
15 use Psr\Http\Message\ServerRequestFactoryInterface;
|
Chris@17
|
16 use Psr\Http\Message\StreamFactoryInterface;
|
Chris@17
|
17 use Psr\Http\Message\UploadedFileFactoryInterface;
|
Chris@17
|
18 use Psr\Http\Message\UploadedFileInterface;
|
Chris@17
|
19 use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
|
Chris@17
|
20 use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
Chris@17
|
21 use Symfony\Component\HttpFoundation\File\UploadedFile;
|
Chris@17
|
22 use Symfony\Component\HttpFoundation\Request;
|
Chris@17
|
23 use Symfony\Component\HttpFoundation\Response;
|
Chris@17
|
24 use Symfony\Component\HttpFoundation\StreamedResponse;
|
Chris@17
|
25
|
Chris@17
|
26 /**
|
Chris@17
|
27 * Builds Psr\HttpMessage instances using a PSR-17 implementation.
|
Chris@17
|
28 *
|
Chris@17
|
29 * @author Antonio J. GarcĂa Lagar <aj@garcialagar.es>
|
Chris@17
|
30 */
|
Chris@17
|
31 class PsrHttpFactory implements HttpMessageFactoryInterface
|
Chris@17
|
32 {
|
Chris@17
|
33 private $serverRequestFactory;
|
Chris@17
|
34 private $streamFactory;
|
Chris@17
|
35 private $uploadedFileFactory;
|
Chris@17
|
36 private $responseFactory;
|
Chris@17
|
37
|
Chris@17
|
38 public function __construct(ServerRequestFactoryInterface $serverRequestFactory, StreamFactoryInterface $streamFactory, UploadedFileFactoryInterface $uploadedFileFactory, ResponseFactoryInterface $responseFactory)
|
Chris@17
|
39 {
|
Chris@17
|
40 $this->serverRequestFactory = $serverRequestFactory;
|
Chris@17
|
41 $this->streamFactory = $streamFactory;
|
Chris@17
|
42 $this->uploadedFileFactory = $uploadedFileFactory;
|
Chris@17
|
43 $this->responseFactory = $responseFactory;
|
Chris@17
|
44 }
|
Chris@17
|
45
|
Chris@17
|
46 /**
|
Chris@17
|
47 * {@inheritdoc}
|
Chris@17
|
48 */
|
Chris@17
|
49 public function createRequest(Request $symfonyRequest)
|
Chris@17
|
50 {
|
Chris@17
|
51 $request = $this->serverRequestFactory->createServerRequest(
|
Chris@17
|
52 $symfonyRequest->getMethod(),
|
Chris@17
|
53 $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getRequestUri(),
|
Chris@17
|
54 $symfonyRequest->server->all()
|
Chris@17
|
55 );
|
Chris@17
|
56
|
Chris@17
|
57 foreach ($symfonyRequest->headers->all() as $name => $value) {
|
Chris@17
|
58 $request = $request->withHeader($name, $value);
|
Chris@17
|
59 }
|
Chris@17
|
60
|
Chris@17
|
61 if (PHP_VERSION_ID < 50600) {
|
Chris@17
|
62 $body = $this->streamFactory->createStreamFromFile('php://temp', 'wb+');
|
Chris@17
|
63 $body->write($symfonyRequest->getContent());
|
Chris@17
|
64 } else {
|
Chris@17
|
65 $body = $this->streamFactory->createStreamFromResource($symfonyRequest->getContent(true));
|
Chris@17
|
66 }
|
Chris@17
|
67
|
Chris@17
|
68 $request = $request
|
Chris@17
|
69 ->withBody($body)
|
Chris@17
|
70 ->withUploadedFiles($this->getFiles($symfonyRequest->files->all()))
|
Chris@17
|
71 ->withCookieParams($symfonyRequest->cookies->all())
|
Chris@17
|
72 ->withQueryParams($symfonyRequest->query->all())
|
Chris@17
|
73 ->withParsedBody($symfonyRequest->request->all())
|
Chris@17
|
74 ;
|
Chris@17
|
75
|
Chris@17
|
76 foreach ($symfonyRequest->attributes->all() as $key => $value) {
|
Chris@17
|
77 $request = $request->withAttribute($key, $value);
|
Chris@17
|
78 }
|
Chris@17
|
79
|
Chris@17
|
80 return $request;
|
Chris@17
|
81 }
|
Chris@17
|
82
|
Chris@17
|
83 /**
|
Chris@17
|
84 * Converts Symfony uploaded files array to the PSR one.
|
Chris@17
|
85 *
|
Chris@17
|
86 * @param array $uploadedFiles
|
Chris@17
|
87 *
|
Chris@17
|
88 * @return array
|
Chris@17
|
89 */
|
Chris@17
|
90 private function getFiles(array $uploadedFiles)
|
Chris@17
|
91 {
|
Chris@17
|
92 $files = array();
|
Chris@17
|
93
|
Chris@17
|
94 foreach ($uploadedFiles as $key => $value) {
|
Chris@17
|
95 if (null === $value) {
|
Chris@17
|
96 $files[$key] = $this->uploadedFileFactory->createUploadedFile($this->streamFactory->createStream(), 0, UPLOAD_ERR_NO_FILE);
|
Chris@17
|
97 continue;
|
Chris@17
|
98 }
|
Chris@17
|
99 if ($value instanceof UploadedFile) {
|
Chris@17
|
100 $files[$key] = $this->createUploadedFile($value);
|
Chris@17
|
101 } else {
|
Chris@17
|
102 $files[$key] = $this->getFiles($value);
|
Chris@17
|
103 }
|
Chris@17
|
104 }
|
Chris@17
|
105
|
Chris@17
|
106 return $files;
|
Chris@17
|
107 }
|
Chris@17
|
108
|
Chris@17
|
109 /**
|
Chris@17
|
110 * Creates a PSR-7 UploadedFile instance from a Symfony one.
|
Chris@17
|
111 *
|
Chris@17
|
112 * @param UploadedFile $symfonyUploadedFile
|
Chris@17
|
113 *
|
Chris@17
|
114 * @return UploadedFileInterface
|
Chris@17
|
115 */
|
Chris@17
|
116 private function createUploadedFile(UploadedFile $symfonyUploadedFile)
|
Chris@17
|
117 {
|
Chris@17
|
118 return $this->uploadedFileFactory->createUploadedFile(
|
Chris@17
|
119 $this->streamFactory->createStreamFromFile(
|
Chris@17
|
120 $symfonyUploadedFile->getRealPath()
|
Chris@17
|
121 ),
|
Chris@17
|
122 (int) $symfonyUploadedFile->getSize(),
|
Chris@17
|
123 $symfonyUploadedFile->getError(),
|
Chris@17
|
124 $symfonyUploadedFile->getClientOriginalName(),
|
Chris@17
|
125 $symfonyUploadedFile->getClientMimeType()
|
Chris@17
|
126 );
|
Chris@17
|
127 }
|
Chris@17
|
128
|
Chris@17
|
129 /**
|
Chris@17
|
130 * {@inheritdoc}
|
Chris@17
|
131 */
|
Chris@17
|
132 public function createResponse(Response $symfonyResponse)
|
Chris@17
|
133 {
|
Chris@17
|
134 $response = $this->responseFactory->createResponse($symfonyResponse->getStatusCode());
|
Chris@17
|
135
|
Chris@17
|
136 if ($symfonyResponse instanceof BinaryFileResponse) {
|
Chris@17
|
137 $stream = $this->streamFactory->createStreamFromFile(
|
Chris@17
|
138 $symfonyResponse->getFile()->getPathname()
|
Chris@17
|
139 );
|
Chris@17
|
140 } else {
|
Chris@17
|
141 $stream = $this->streamFactory->createStreamFromFile('php://temp', 'wb+');
|
Chris@17
|
142 if ($symfonyResponse instanceof StreamedResponse) {
|
Chris@17
|
143 ob_start(function ($buffer) use ($stream) {
|
Chris@17
|
144 $stream->write($buffer);
|
Chris@17
|
145
|
Chris@17
|
146 return '';
|
Chris@17
|
147 });
|
Chris@17
|
148
|
Chris@17
|
149 $symfonyResponse->sendContent();
|
Chris@17
|
150 ob_end_clean();
|
Chris@17
|
151 } else {
|
Chris@17
|
152 $stream->write($symfonyResponse->getContent());
|
Chris@17
|
153 }
|
Chris@17
|
154 }
|
Chris@17
|
155
|
Chris@17
|
156 $response = $response->withBody($stream);
|
Chris@17
|
157
|
Chris@17
|
158 $headers = $symfonyResponse->headers->all();
|
Chris@17
|
159 $cookies = $symfonyResponse->headers->getCookies();
|
Chris@17
|
160 if (!empty($cookies)) {
|
Chris@17
|
161 $headers['Set-Cookie'] = array();
|
Chris@17
|
162
|
Chris@17
|
163 foreach ($cookies as $cookie) {
|
Chris@17
|
164 $headers['Set-Cookie'][] = $cookie->__toString();
|
Chris@17
|
165 }
|
Chris@17
|
166 }
|
Chris@17
|
167
|
Chris@17
|
168 foreach ($headers as $name => $value) {
|
Chris@17
|
169 $response = $response->withHeader($name, $value);
|
Chris@17
|
170 }
|
Chris@17
|
171
|
Chris@17
|
172 $protocolVersion = $symfonyResponse->getProtocolVersion();
|
Chris@17
|
173 $response = $response->withProtocolVersion($protocolVersion);
|
Chris@17
|
174
|
Chris@17
|
175 return $response;
|
Chris@17
|
176 }
|
Chris@17
|
177 }
|