10000 Create PSR-7 messages using PSR-17 factories · symfony/symfony@dd81b4b · GitHub
[go: up one dir, main page]

Skip to content

Commit dd81b4b

Browse files
ajgarlagfabpot
authored andcommitted
Create PSR-7 messages using PSR-17 factories
1 parent f11f173 commit dd81b4b

7 files changed

+453
-201
lines changed

.travis.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ env:
99
global:
1010
- PHPUNIT_FLAGS="-v"
1111
- SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit"
12-
- DEPENDENCIES="zendframework/zend-diactoros:^1.4.1"
12+
- DEPENDENCIES="zendframework/zend-diactoros:^1.4.1 http-interop/http-factory-diactoros:^1.0"
1313

1414
matrix:
1515
fast_finish: true
@@ -26,8 +26,11 @@ matrix:
2626
dist: 'precise'
2727
env: DEPENDENCIES=""
2828
- php: 5.4
29+
env: DEPENDENCIES="zendframework/zend-diactoros:^1.4.1"
2930
- php: 5.5
31+
env: DEPENDENCIES="zendframework/zend-diactoros:^1.4.1"
3032
- php: 5.6
33+
env: DEPENDENCIES="zendframework/zend-diactoros:^1.4.1"
3134
- php: 7.0
3235
- php: 7.1
3336
- php: 7.2
@@ -36,9 +39,9 @@ matrix:
3639
# Test LTS versions. This makes sure we do not use Symfony packages with version greater
3740
# than 2 or 3 respectively.
3841
- php: 7.2
39-
env: DEPENDENCIES="symfony/lts:^2 symfony/force-lowest:~2.8.0 zendframework/zend-diactoros:^1.4.1"
42+
env: DEPENDENCIES="$DEPENDENCIES symfony/lts:^2 symfony/force-lowest:~2.8.0"
4043
- php: 7.2
41-
env: DEPENDENCIES="symfony/lts:^3 symfony/force-lowest:~3.4.0 zendframework/zend-diactoros:^1.4.1"
44+
env: DEPENDENCIES="$DEPENDENCIES symfony/lts:^3 symfony/force-lowest:~3.4.0"
4245

4346
# Latest commit to master
4447
- php: 7.2

Factory/DiactorosFactory.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public function createResponse(Response $symfonyResponse)
133133
ob_start(function ($buffer) use ($stream) {
134134
$stream->write($buffer);
135135

136-
return false;
136+
return '';
137137
});
138138

139139
$symfonyResponse->sendContent();

Factory/PsrHttpFactory.php

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

0 commit comments

Comments
 (0)
0