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