-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHttpFoundationBridge.php
More file actions
182 lines (167 loc) · 6.01 KB
/
Copy pathHttpFoundationBridge.php
File metadata and controls
182 lines (167 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
/**
* This file is part of HttpMessage
*
* @package bdk/http-message
* @author Brad Kent <bkfake-github@yahoo.com>
* @license http://opensource.org/licenses/MIT MIT
* @copyright 2014-2024 Brad Kent
* @version v1.0
*/
namespace bdk\HttpMessage\Utility;
use bdk\HttpMessage\Response as ResponseImplementation;
use bdk\HttpMessage\ServerRequest as ServerRequestImplementation;
use bdk\HttpMessage\Stream;
use bdk\HttpMessage\UploadedFile;
use bdk\HttpMessage\Uri as UriImplementation;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile as HttpFoundationUploadedFile;
use Symfony\Component\HttpFoundation\Request as HttpFoundationRequest;
use Symfony\Component\HttpFoundation\Response as HttpFoundationResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* Factories for creating ServerRequest & Response from HttpFoundation objects
*
* @psalm-api
*/
class HttpFoundationBridge
{
/**
* Create a Psr7 request object from HttpFoundation request
*
* @param HttpFoundationRequest $request HttpFoundation\Request obj
*
* @return ServerRequestImplementation
*
* @psalm-suppress ReservedWord complains about HttpFoundations' : mixed return spec
*/
public static function createRequest(HttpFoundationRequest $request): ServerRequestImplementation
{
/** @psalm-var string */
$query = $request->server->get('QUERY_STRING', '');
$uri = $request->getSchemeAndHttpHost()
. $request->getBaseUrl()
. $request->getPathInfo()
. ($query !== '' ? '?' . $query : '');
$uri = new UriImplementation($uri);
$bodyContentResource = $request->getContent(true);
$stream = new Stream($bodyContentResource);
$psr7request = new ServerRequestImplementation($request->getMethod(), $uri, $request->server->all());
$psr7request = $psr7request
->withBody($stream)
->withUploadedFiles(self::getFiles($request->files->all()))
->withCookieParams($request->cookies->all())
->withQueryParams($request->query->all())
->withParsedBody($request->request->all());
/** @var mixed $value */
foreach ($request->attributes->all() as $key => $value) {
$psr7request = $psr7request->withAttribute((string) $key, $value);
}
return $psr7request;
}
/**
* Create Response from HttpFoundationResponse
*
* @param HttpFoundationResponse $response HttpFoundationResponse instance
*
* @return ResponseImplementation
*/
public static function createResponse(HttpFoundationResponse $response): ResponseImplementation
{
$statusCode = $response->getStatusCode();
$protocolVersion = $response->getProtocolVersion();
$stream = self::createResponseStream($response);
$psr7response = new ResponseImplementation($statusCode);
$psr7response = $psr7response
->withProtocolVersion($protocolVersion)
->withBody($stream);
$headers = $response->headers->all();
foreach ($headers as $name => $values) {
$values = \array_filter($values, static function ($value) {
return $value !== null;
});
if ($values) {
$psr7response = $psr7response->withHeader($name, $values);
}
}
return $psr7response;
}
/**
* Create a Stream from HttpFoundationResponse
*
* @param HttpFoundationResponse $response response instance
*
* @return Stream
*/
private static function createResponseStream(HttpFoundationResponse $response): Stream
{
if ($response instanceof BinaryFileResponse && !$response->headers->has('Content-Range')) {
$pathName = $response->getFile()->getPathname();
return new Stream(\fopen($pathName, 'rb+'));
}
$stream = new Stream(\fopen('php://temp', 'wb+'));
if ($response instanceof StreamedResponse || $response instanceof BinaryFileResponse) {
\ob_start(
/**
* @param string $buffer
*
* @return string
*/
static function ($buffer) use ($stream) {
$stream->write($buffer);
return '';
}
);
$response->sendContent();
\ob_end_clean();
return $stream;
}
/** @psalm-suppress ReservedWord */
$content = $response->getContent();
if ($content !== false) {
$stream->write($content);
}
return $stream;
}
/**
* Creates a PSR-7 UploadedFile instance from a Symfony one.
*
* @param HttpFoundationUploadedFile $uploadedFile HttpFoundation\File\UploadedFile
*
* @return UploadedFile
*/
private static function createUploadedFile(HttpFoundationUploadedFile $uploadedFile): UploadedFile
{
return new UploadedFile(
$uploadedFile->getRealPath(),
(int) $uploadedFile->getSize(),
$uploadedFile->getError(),
$uploadedFile->getClientOriginalName(),
$uploadedFile->getClientMimeType()
);
}
/**
* Converts Symfony uploaded files array to the PSR one.
*
* @param array $uploadedFiles uploadedFiles
*
* @return array
*/
private static function getFiles(array $uploadedFiles): array
{
return \array_map(static function ($value) {
if ($value === null) {
$value = new UploadedFile(
null,
0,
UPLOAD_ERR_NO_FILE
);
} elseif ($value instanceof HttpFoundationUploadedFile) {
$value = self::createUploadedFile($value);
} elseif (\is_array($value)) {
$value = self::getFiles($value);
}
return $value;
}, $uploadedFiles);
}
}