From 999be72fc9fa35be23d79361ef1eeb5dfe5bb8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 22:21:32 +0200 Subject: [PATCH 01/37] Add composer dependencies --- composer.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 700becc..5afd2e9 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "symfony/psr-http-message-bridge", "type": "symfony-bridge", "description": "PSR HTTP message bridge", - "keywords": [], + "keywords": ["http", "psr-7", "http-message"], "homepage": "http://symfony.com", "license": "MIT", "authors": [ @@ -16,16 +16,18 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "psr/http-message": "~1.0" }, "require-dev": { + "zendframework/zend-diactoros": "~1.0" }, "suggest": { + "zendframework/zend-diactoros": "To use the zend-diactoros adapter" }, "autoload": { - "psr-0": { "Symfony\\Bridge\\PsrHttpMessage\\": "" } + "psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" } }, - "target-dir": "Symfony/Bridge/PsrHttpMessage", "minimum-stability": "dev", "extra": { "branch-alias": { From 47c656444b61fda7b070d6abc69ecfd339aa04b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 22:35:48 +0200 Subject: [PATCH 02/37] More dependencies --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5afd2e9..57eae1b 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,11 @@ ], "require": { "php": ">=5.3.3", - "psr/http-message": "~1.0" + "psr/http-message": "~1.0", + "symfony/http-foundation": "~2.3" }, "require-dev": { + "symfony/phpunit-bridge": "~2.7", "zendframework/zend-diactoros": "~1.0" }, "suggest": { From 6a4ab9bc4ca47c5616a756c1ee314aa7f9475ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 22:55:41 +0200 Subject: [PATCH 03/37] Add interfaces and stubs. --- Factory/DiactorosFactory.php | 9 +++++++ Factory/HttpFoundationFactory.php | 6 +++++ HttpFoundationFactoryInterface.php | 40 ++++++++++++++++++++++++++++++ PsrHttpMessageFactoryInterface.php | 34 +++++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 Factory/DiactorosFactory.php create mode 100644 Factory/HttpFoundationFactory.php create mode 100644 HttpFoundationFactoryInterface.php create mode 100644 PsrHttpMessageFactoryInterface.php diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php new file mode 100644 index 0000000..d6fa879 --- /dev/null +++ b/Factory/DiactorosFactory.php @@ -0,0 +1,9 @@ + + */ +class HttpFoundationFactory +{ + /** + * Creates a Symfony Request from a PSR-7 one. + * + * @param RequestInterface $psrHttpMessageRequest + * + * @return Request + */ + public function createRequest(RequestInterface $psrHttpMessageRequest) + { + // TODO + } + + /** + * Creates a Symfony Response from a PSR-7 one. + * + * @param ResponseInterface $psrHttpMessageResponse + * + * @return Response + */ + public function createResponse(ResponseInterface $psrHttpMessageResponse) + { + // TODO + } +} diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php new file mode 100644 index 0000000..16d0555 --- /dev/null +++ b/PsrHttpMessageFactoryInterface.php @@ -0,0 +1,34 @@ + + */ +interface PsrHttpMessageFactoryInterface +{ + /** + * Creates a PSR-7 Request from a Symfony one. + * + * @param Request $symfonyRequest + * + * @return RequestInterface + */ + public function createRequest(Request $symfonyRequest); + + /** + * Creates a PSR-7 Response from a Symfony one. + * + * @param Response $symfonyResponse + * + * @return ResponseInterface + */ + public function createResponse(Response $symfonyResponse); +} From 1ed3bfff834778cba36cd00bc1679d7dedbd9b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 22:56:48 +0200 Subject: [PATCH 04/37] Add .gitignore --- .gitignore | 3 +++ Factory/DiactorosFactory.php | 31 ++++++++++++++++++++++++++--- Factory/HttpFoundationFactory.php | 32 ++++++++++++++++++++++++++++-- HttpFoundationFactoryInterface.php | 12 +++-------- 4 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c49a5d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index d6fa879..f580364 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -1,9 +1,34 @@ + */ +class DiactorosFactory implements PsrHttpMessageFactoryInterface +{ -class DiactorosFactory { + /** + * {@inheritdoc} + */ + public function createRequest(Request $symfonyRequest) + { + // TODO: Implement createRequest() method. + } -} \ No newline at end of file + /** + * {@inheritdoc} + */ + public function createResponse(Response $symfonyResponse) + { + // TODO: Implement createResponse() method. + } +} diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index df793b6..59e7b09 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -1,6 +1,34 @@ + */ +class HttpFoundationFactory implements HttpFoundationFactoryInterface +{ + + /** + * {@inheritdoc} + */ + public function createRequest(RequestInterface $psrHttpMessageRequest) + { + // TODO: Implement createRequest() method. + } + + /** + * {@inheritdoc} + */ + public function createResponse(ResponseInterface $psrHttpMessageResponse) + { + // TODO: Implement createResponse() method. + } +} diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index 4c0f482..5567afe 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -12,7 +12,7 @@ * * @author Kévin Dunglas */ -class HttpFoundationFactory +interface HttpFoundationFactoryInterface { /** * Creates a Symfony Request from a PSR-7 one. @@ -21,10 +21,7 @@ class HttpFoundationFactory * * @return Request */ - public function createRequest(RequestInterface $psrHttpMessageRequest) - { - // TODO - } + public function createRequest(RequestInterface $psrHttpMessageRequest); /** * Creates a Symfony Response from a PSR-7 one. @@ -33,8 +30,5 @@ public function createRequest(RequestInterface $psrHttpMessageRequest) * * @return Response */ - public function createResponse(ResponseInterface $psrHttpMessageResponse) - { - // TODO - } + public function createResponse(ResponseInterface $psrHttpMessageResponse); } From 1b81ee0176a4b0a559d92d005576b79cb812b864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 23:07:56 +0200 Subject: [PATCH 05/37] Make factory methods static. Add test infra. --- Factory/DiactorosFactory.php | 4 ++-- HttpFoundationFactoryInterface.php | 4 ++-- PsrHttpMessageFactoryInterface.php | 4 ++-- Tests/Factory/DiactorosFactoryTest.php | 19 +++++++++++++++++++ Tests/Factory/HttpFoundationFactoryTest.php | 19 +++++++++++++++++++ 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Tests/Factory/DiactorosFactoryTest.php create mode 100644 Tests/Factory/HttpFoundationFactoryTest.php diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index f580364..b77a01c 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -19,7 +19,7 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface /** * {@inheritdoc} */ - public function createRequest(Request $symfonyRequest) + public static function createRequest(Request $symfonyRequest) { // TODO: Implement createRequest() method. } @@ -27,7 +27,7 @@ public function createRequest(Request $symfonyRequest) /** * {@inheritdoc} */ - public function createResponse(Response $symfonyResponse) + public static function createResponse(Response $symfonyResponse) { // TODO: Implement createResponse() method. } diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index 5567afe..e251b4e 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -21,7 +21,7 @@ interface HttpFoundationFactoryInterface * * @return Request */ - public function createRequest(RequestInterface $psrHttpMessageRequest); + public static function createRequest(RequestInterface $psrHttpMessageRequest); /** * Creates a Symfony Response from a PSR-7 one. @@ -30,5 +30,5 @@ public function createRequest(RequestInterface $psrHttpMessageRequest); * * @return Response */ - public function createResponse(ResponseInterface $psrHttpMessageResponse); + public static function createResponse(ResponseInterface $psrHttpMessageResponse); } diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php index 16d0555..1767a4c 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/PsrHttpMessageFactoryInterface.php @@ -21,7 +21,7 @@ interface PsrHttpMessageFactoryInterface * * @return RequestInterface */ - public function createRequest(Request $symfonyRequest); + public static function createRequest(Request $symfonyRequest); /** * Creates a PSR-7 Response from a Symfony one. @@ -30,5 +30,5 @@ public function createRequest(Request $symfonyRequest); * * @return ResponseInterface */ - public function createResponse(Response $symfonyResponse); + public static function createResponse(Response $symfonyResponse); } diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php new file mode 100644 index 0000000..4b4322c --- /dev/null +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -0,0 +1,19 @@ + + */ +class DiactorosFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testCreateRequest() + { + + } + + public function testCreateResponse() + { + + } +} diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php new file mode 100644 index 0000000..57f810b --- /dev/null +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -0,0 +1,19 @@ + + */ +class HttpFoundationFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testCreateRequest() + { + + } + + public function testCreateResponse() + { + + } +} From 1e3307c134f17e538ab900b4c504ba835ca3d197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 23:12:03 +0200 Subject: [PATCH 06/37] Setup Travis --- .travis.yml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d350695 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,41 @@ +language: php + +sudo: false + +matrix: + include: + - php: 5.3 + - php: 5.4 + - php: 5.5 + - php: 5.6 + - php: 5.3 + env: deps=low + - php: 5.6 + env: deps=high + - php: nightly + - php: hhvm + allow_failures: + - php: nightly + - php: hhvm + fast_finish: true + +env: + global: + - deps=no + - SYMFONY_DEPRECATIONS_HELPER=weak + +before_install: + - composer self-update + - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi; + - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; + - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi; + - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi; + # Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built + - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi; + +install: + - if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi; + - if [ "$deps" = "no" ]; then composer --prefer-source install; fi; + +script: + - phpunit From 7e7fbf66a12a6c57b4de3c6367e8b87176da4b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 23:13:38 +0200 Subject: [PATCH 07/37] Add missing static keywords --- Factory/HttpFoundationFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 59e7b09..7570f4e 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -19,7 +19,7 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface /** * {@inheritdoc} */ - public function createRequest(RequestInterface $psrHttpMessageRequest) + public static function createRequest(RequestInterface $psrHttpMessageRequest) { // TODO: Implement createRequest() method. } @@ -27,7 +27,7 @@ public function createRequest(RequestInterface $psrHttpMessageRequest) /** * {@inheritdoc} */ - public function createResponse(ResponseInterface $psrHttpMessageResponse) + public static function createResponse(ResponseInterface $psrHttpMessageResponse) { // TODO: Implement createResponse() method. } From 43d4c48ed499682f4625a4df151271f26097543b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 21 May 2015 23:31:07 +0200 Subject: [PATCH 08/37] Use ServerRequestInterface --- Factory/DiactorosFactory.php | 8 ++++++-- Factory/HttpFoundationFactory.php | 13 ++++++++----- HttpFoundationFactoryInterface.php | 6 +++--- PsrHttpMessageFactoryInterface.php | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index b77a01c..e71d7f4 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -21,7 +21,9 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface */ public static function createRequest(Request $symfonyRequest) { - // TODO: Implement createRequest() method. + return new ServerRequest( + + ); } /** @@ -29,6 +31,8 @@ public static function createRequest(Request $symfonyRequest) */ public static function createResponse(Response $symfonyResponse) { - // TODO: Implement createResponse() method. + return new DiactorosResponse( + + ); } } diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 7570f4e..f3b9a1a 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -2,7 +2,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Factory; -use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; use Symfony\Component\HttpFoundation\Request; @@ -15,13 +15,14 @@ */ class HttpFoundationFactory implements HttpFoundationFactoryInterface { - /** * {@inheritdoc} */ - public static function createRequest(RequestInterface $psrHttpMessageRequest) + public static function createRequest(ServerRequestInterface $psrHttpMessageRequest) { - // TODO: Implement createRequest() method. + return new Request( + + ); } /** @@ -29,6 +30,8 @@ public static function createRequest(RequestInterface $psrHttpMessageRequest) */ public static function createResponse(ResponseInterface $psrHttpMessageResponse) { - // TODO: Implement createResponse() method. + return new Response( + + ); } } diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index e251b4e..0a7db59 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -2,7 +2,7 @@ namespace Symfony\Bridge\PsrHttpMessage; -use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,11 +17,11 @@ interface HttpFoundationFactoryInterface /** * Creates a Symfony Request from a PSR-7 one. * - * @param RequestInterface $psrHttpMessageRequest + * @param ServerRequestInterface $psrHttpMessageRequest * * @return Request */ - public static function createRequest(RequestInterface $psrHttpMessageRequest); + public static function createRequest(ServerRequestInterface $psrHttpMessageRequest); /** * Creates a Symfony Response from a PSR-7 one. diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php index 1767a4c..2ad26ba 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/PsrHttpMessageFactoryInterface.php @@ -2,7 +2,7 @@ namespace Symfony\Bridge\PsrHttpMessage; -use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -19,7 +19,7 @@ interface PsrHttpMessageFactoryInterface * * @param Request $symfonyRequest * - * @return RequestInterface + * @return ServerRequestInterface */ public static function createRequest(Request $symfonyRequest); From bb43a07e5ac4974ac4dde930766fcfd521650df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 00:49:36 +0200 Subject: [PATCH 09/37] Basic HttpFoundationFactory::createRequest implementation --- Factory/DiactorosFactory.php | 4 +- Factory/HttpFoundationFactory.php | 19 ++- HttpFoundationFactoryInterface.php | 4 +- PsrHttpMessageFactoryInterface.php | 4 +- Tests/Factory/HttpFoundationFactoryTest.php | 40 +++++++ Tests/Fixtures/Message.php | 84 +++++++++++++ Tests/Fixtures/ServerRequest.php | 124 ++++++++++++++++++++ Tests/Fixtures/Stream.php | 86 ++++++++++++++ 8 files changed, 356 insertions(+), 9 deletions(-) create mode 100644 Tests/Fixtures/Message.php create mode 100644 Tests/Fixtures/ServerRequest.php create mode 100644 Tests/Fixtures/Stream.php diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index e71d7f4..6142a93 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -19,7 +19,7 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface /** * {@inheritdoc} */ - public static function createRequest(Request $symfonyRequest) + public function createRequest(Request $symfonyRequest) { return new ServerRequest( @@ -29,7 +29,7 @@ public static function createRequest(Request $symfonyRequest) /** * {@inheritdoc} */ - public static function createResponse(Response $symfonyResponse) + public function createResponse(Response $symfonyResponse) { return new DiactorosResponse( diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index f3b9a1a..f9fdf94 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -18,17 +18,30 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface /** * {@inheritdoc} */ - public static function createRequest(ServerRequestInterface $psrHttpMessageRequest) + public function createRequest(ServerRequestInterface $psrHttpMessageRequest) { - return new Request( + $parsedBody = $psrHttpMessageRequest->getParsedBody(); + $request = is_array($parsedBody) ? $parsedBody : []; + return new Request( + $psrHttpMessageRequest->getQueryParams(), + $request, + $psrHttpMessageRequest->getAttributes(), + $psrHttpMessageRequest->getCookieParams(), + array(), // TODO + $psrHttpMessageRequest->getServerParams(), + $psrHttpMessageRequest->getBody()->__toString() ); } + private function getFiles(array $uploadedFiles) + { + } + /** * {@inheritdoc} */ - public static function createResponse(ResponseInterface $psrHttpMessageResponse) + public function createResponse(ResponseInterface $psrHttpMessageResponse) { return new Response( diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index 0a7db59..064385c 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -21,7 +21,7 @@ interface HttpFoundationFactoryInterface * * @return Request */ - public static function createRequest(ServerRequestInterface $psrHttpMessageRequest); + public function createRequest(ServerRequestInterface $psrHttpMessageRequest); /** * Creates a Symfony Response from a PSR-7 one. @@ -30,5 +30,5 @@ public static function createRequest(ServerRequestInterface $psrHttpMessageReque * * @return Response */ - public static function createResponse(ResponseInterface $psrHttpMessageResponse); + public function createResponse(ResponseInterface $psrHttpMessageResponse); } diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php index 2ad26ba..31cb721 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/PsrHttpMessageFactoryInterface.php @@ -21,7 +21,7 @@ interface PsrHttpMessageFactoryInterface * * @return ServerRequestInterface */ - public static function createRequest(Request $symfonyRequest); + public function createRequest(Request $symfonyRequest); /** * Creates a PSR-7 Response from a Symfony one. @@ -30,5 +30,5 @@ public static function createRequest(Request $symfonyRequest); * * @return ResponseInterface */ - public static function createResponse(Response $symfonyResponse); + public function createResponse(Response $symfonyResponse); } diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 57f810b..602c254 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -1,15 +1,54 @@ */ class HttpFoundationFactoryTest extends \PHPUnit_Framework_TestCase { + private $factory; + + public function setup() + { + $this->factory = new HttpFoundationFactory(); + } + public function testCreateRequest() { + $serverRequest = new ServerRequest(); + $serverRequest->withQueryParams(array('url' => 'http://les-tilleuls.coop')); + $serverRequest->withParsedBody(array('url' => 'http://dunglas.fr')); + + $stdClass = new \stdClass(); + $serverRequest->withAttribute('custom', $stdClass); + + $serverRequest->withCookieParams(array('city' => 'Lille')); + $serverRequest->withServerParams(array('country' => 'France')); + $serverRequest->withBody(new Stream('The body')); + + $symfonyRequest = $this->factory->createRequest($serverRequest); + $this->assertEquals('http://les-tilleuls.coop', $symfonyRequest->query->get('url')); + $this->assertEquals('http://dunglas.fr', $symfonyRequest->request->get('url')); + $this->assertEquals($stdClass, $symfonyRequest->attributes->get('custom')); + $this->assertEquals('Lille', $symfonyRequest->cookies->get('city')); + $this->assertEquals('France', $symfonyRequest->server->get('country')); + $this->assertEquals('The body', $symfonyRequest->getContent()); + } + + public function testCreateRequestWithNonArrayParsedBody() + { + $serverRequest = new ServerRequest(); + + $serverRequest->withParsedBody(null); + $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); + + $serverRequest->withParsedBody(new \stdClass()); + $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); } public function testCreateResponse() @@ -17,3 +56,4 @@ public function testCreateResponse() } } + diff --git a/Tests/Fixtures/Message.php b/Tests/Fixtures/Message.php new file mode 100644 index 0000000..c14f3df --- /dev/null +++ b/Tests/Fixtures/Message.php @@ -0,0 +1,84 @@ + + */ +class Message implements MessageInterface +{ + private $version = '1.1'; + private $headers = array(); + private $body; + + public function __construct() + { + $this->body = new Stream(); + } + + public function getProtocolVersion() + { + return $this->version; + } + + public function withProtocolVersion($version) + { + $this->version = $version; + } + + public function getHeaders() + { + return $this->headers; + } + + public function hasHeader($name) + { + return isset($this->headers[$name]); + } + + public function getHeader($name) + { + return $this->hasHeader($name) ? $this->headers[$name] : array(); + } + + public function getHeaderLine($name) + { + return $this->hasHeader($name) ? join(',', $this->headers[$name]) : ''; + } + + public function withHeader($name, $value) + { + if (!is_array($value)) { + $value = array($value); + } + + $this->headers[$name] = $value; + } + + public function withAddedHeader($name, $value) + { + $this->headers[$name][] = $value; + } + + public function withoutHeader($name) + { + if ($this->hasHeader($name)) { + unset($this->headers[$name]); + } + } + + public function getBody() + { + return $this->body; + } + + public function withBody(StreamInterface $body) + { + $this->body = $body; + } +} diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php new file mode 100644 index 0000000..26ade63 --- /dev/null +++ b/Tests/Fixtures/ServerRequest.php @@ -0,0 +1,124 @@ + + */ +class ServerRequest extends Message implements ServerRequestInterface +{ + private $requestTarget = '/'; + private $method = 'GET'; + private $uri; + private $server = array(); + private $cookies = array(); + private $query = array(); + private $uploadedFiles = array(); + private $data = null; + private $attributes = array(); + + public function getRequestTarget() + { + return $this->requestTarget; + } + + public function withRequestTarget($requestTarget) + { + $this->requestTarget = $requestTarget; + } + + public function getMethod() + { + return $this->method; + } + + public function withMethod($method) + { + $this->method = $method; + } + + public function getUri() + { + return $this->uri; + } + + public function withUri(UriInterface $uri, $preserveHost = false) + { + $this->uri = $uri; + } + + public function getServerParams() + { + return $this->server; + } + + public function withServerParams(array $serverParams) + { + $this->server = $serverParams; + } + + public function getCookieParams() + { + return $this->cookies; + } + + public function withCookieParams(array $cookies) + { + $this->cookies = $cookies; + } + + public function getQueryParams() + { + return $this->query; + } + + public function withQueryParams(array $query) + { + $this->query = $query; + } + + public function getUploadedFiles() + { + return $this->uploadedFiles; + } + + public function withUploadedFiles(array $uploadedFiles) + { + $this->uploadedFiles = $uploadedFiles; + } + + public function getParsedBody() + { + return $this->data; + } + + public function withParsedBody($data) + { + $this->data = $data; + } + + public function getAttributes() + { + return $this->attributes; + } + + public function getAttribute($name, $default = null) + { + return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; + } + + public function withAttribute($name, $value) + { + $this->attributes[$name] = $value; + } + + public function withoutAttribute($name) + { + if ($this->getAttribute($name)) { + unset($this->attributes[$name]); + } + } +} diff --git a/Tests/Fixtures/Stream.php b/Tests/Fixtures/Stream.php new file mode 100644 index 0000000..acb13e1 --- /dev/null +++ b/Tests/Fixtures/Stream.php @@ -0,0 +1,86 @@ + + */ +class Stream implements StreamInterface +{ + private $stringContent; + + public function __construct($stringContent = '') + { + $this->stringContent = $stringContent; + } + + public function __toString() + { + return $this->stringContent; + } + + public function close() + { + } + + public function detach() + { + } + + public function getSize() + { + } + + public function tell() + { + return 0; + } + + public function eof() + { + return true; + } + + public function isSeekable() + { + return false; + } + + public function seek($offset, $whence = SEEK_SET) + { + } + + public function rewind() + { + } + + public function isWritable() + { + return false; + } + + public function write($string) + { + } + + public function isReadable() + { + return true; + } + + public function read($length) + { + return $this->stringContent; + } + + public function getContents() + { + return $this->stringContent; + } + + public function getMetadata($key = null) + { + } +} From 656318bea3a322e2007f912021090c1a5a3a926a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 00:51:13 +0200 Subject: [PATCH 10/37] Remove a short array usage --- Factory/HttpFoundationFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index f9fdf94..1e544d5 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -21,7 +21,7 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface public function createRequest(ServerRequestInterface $psrHttpMessageRequest) { $parsedBody = $psrHttpMessageRequest->getParsedBody(); - $request = is_array($parsedBody) ? $parsedBody : []; + $request = is_array($parsedBody) ? $parsedBody : array(); return new Request( $psrHttpMessageRequest->getQueryParams(), From 40c297381bb9c5cd73b752e739a86a01c43749d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 08:09:32 +0200 Subject: [PATCH 11/37] Make immutable --- Tests/Factory/HttpFoundationFactoryTest.php | 3 +-- Tests/Fixtures/ServerRequest.php | 12 +++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 602c254..c99b248 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -19,7 +19,7 @@ public function setup() public function testCreateRequest() { - $serverRequest = new ServerRequest(); + $serverRequest = new ServerRequest(array('country' => 'France')); $serverRequest->withQueryParams(array('url' => 'http://les-tilleuls.coop')); $serverRequest->withParsedBody(array('url' => 'http://dunglas.fr')); @@ -27,7 +27,6 @@ public function testCreateRequest() $serverRequest->withAttribute('custom', $stdClass); $serverRequest->withCookieParams(array('city' => 'Lille')); - $serverRequest->withServerParams(array('country' => 'France')); $serverRequest->withBody(new Stream('The body')); $symfonyRequest = $this->factory->createRequest($serverRequest); diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php index 26ade63..d902495 100644 --- a/Tests/Fixtures/ServerRequest.php +++ b/Tests/Fixtures/ServerRequest.php @@ -20,6 +20,13 @@ class ServerRequest extends Message implements ServerRequestInterface private $data = null; private $attributes = array(); + public function __construct($server = array()) + { + parent::__construct(); + + $this->server = $server; + } + public function getRequestTarget() { return $this->requestTarget; @@ -55,11 +62,6 @@ public function getServerParams() return $this->server; } - public function withServerParams(array $serverParams) - { - $this->server = $serverParams; - } - public function getCookieParams() { return $this->cookies; From a246407983db77d55c07bbdb75908ff86895d70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 08:29:51 +0200 Subject: [PATCH 12/37] Enforce immutability --- Tests/Factory/HttpFoundationFactoryTest.php | 60 ++++++++++++++++----- Tests/Fixtures/Message.php | 22 ++++---- Tests/Fixtures/ServerRequest.php | 48 +++++++++-------- 3 files changed, 83 insertions(+), 47 deletions(-) diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index c99b248..2288ac0 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -19,15 +19,21 @@ public function setup() public function testCreateRequest() { - $serverRequest = new ServerRequest(array('country' => 'France')); - $serverRequest->withQueryParams(array('url' => 'http://les-tilleuls.coop')); - $serverRequest->withParsedBody(array('url' => 'http://dunglas.fr')); - $stdClass = new \stdClass(); - $serverRequest->withAttribute('custom', $stdClass); - - $serverRequest->withCookieParams(array('city' => 'Lille')); - $serverRequest->withBody(new Stream('The body')); + $serverRequest = new ServerRequest( + '1.1', + array(), + new Stream('The body'), + '/about/kevin', + 'GET', + 'http://les-tilleuls.coop/about/kevin', + array('country' => 'France'), + array('city' => 'Lille'), + array('url' => 'http://les-tilleuls.coop'), + array(), + array('url' => 'http://dunglas.fr'), + array('custom' => $stdClass) + ); $symfonyRequest = $this->factory->createRequest($serverRequest); @@ -39,14 +45,43 @@ public function testCreateRequest() $this->assertEquals('The body', $symfonyRequest->getContent()); } - public function testCreateRequestWithNonArrayParsedBody() + public function testCreateRequestWithNullParsedBody() { - $serverRequest = new ServerRequest(); + $serverRequest = new ServerRequest( + '1.1', + array(), + new Stream(), + '/', + 'GET', + null, + array(), + array(), + array(), + array(), + null, + array() + ); - $serverRequest->withParsedBody(null); $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); + } + + public function testCreateRequestWithObjectParsedBody() + { + $serverRequest = new ServerRequest( + '1.1', + array(), + new Stream(), + '/', + 'GET', + null, + array(), + array(), + array(), + array(), + new \stdClass(), + array() + ); - $serverRequest->withParsedBody(new \stdClass()); $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); } @@ -55,4 +90,3 @@ public function testCreateResponse() } } - diff --git a/Tests/Fixtures/Message.php b/Tests/Fixtures/Message.php index c14f3df..ee49172 100644 --- a/Tests/Fixtures/Message.php +++ b/Tests/Fixtures/Message.php @@ -16,9 +16,11 @@ class Message implements MessageInterface private $headers = array(); private $body; - public function __construct() + public function __construct($version = '1.1', array $headers = array(), StreamInterface $body = null) { - $this->body = new Stream(); + $this->version = $version; + $this->headers = $headers; + $this->body = null === $body ? new Stream() : $body; } public function getProtocolVersion() @@ -28,7 +30,7 @@ public function getProtocolVersion() public function withProtocolVersion($version) { - $this->version = $version; + throw \BadMethodCallException('Not implemented.'); } public function getHeaders() @@ -53,23 +55,17 @@ public function getHeaderLine($name) public function withHeader($name, $value) { - if (!is_array($value)) { - $value = array($value); - } - - $this->headers[$name] = $value; + throw \BadMethodCallException('Not implemented.'); } public function withAddedHeader($name, $value) { - $this->headers[$name][] = $value; + throw \BadMethodCallException('Not implemented.'); } public function withoutHeader($name) { - if ($this->hasHeader($name)) { - unset($this->headers[$name]); - } + throw \BadMethodCallException('Not implemented.'); } public function getBody() @@ -79,6 +75,6 @@ public function getBody() public function withBody(StreamInterface $body) { - $this->body = $body; + throw \BadMethodCallException('Not implemented.'); } } diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php index d902495..3b5ac4c 100644 --- a/Tests/Fixtures/ServerRequest.php +++ b/Tests/Fixtures/ServerRequest.php @@ -3,6 +3,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UriInterface; /** @@ -10,21 +11,29 @@ */ class ServerRequest extends Message implements ServerRequestInterface { - private $requestTarget = '/'; - private $method = 'GET'; + private $requestTarget ; + private $method; private $uri; - private $server = array(); - private $cookies = array(); - private $query = array(); - private $uploadedFiles = array(); - private $data = null; - private $attributes = array(); + private $server; + private $cookies; + private $query; + private $uploadedFiles; + private $data; + private $attributes; - public function __construct($server = array()) + public function __construct($version = '1.1', array $headers = array(), StreamInterface $body = null, $requestTarget = '/', $method = 'GET', $uri = null, array $server = array(), array $cookies = array(), array $query = array(), array $uploadedFiles = array(), $data = null, array $attributes = array()) { - parent::__construct(); + parent::__construct($version, $headers, $body); + $this->requestTarget = $requestTarget; + $this->method = $method; + $this->uri = $uri; $this->server = $server; + $this->cookies = $cookies; + $this->query = $query; + $this->uploadedFiles = $uploadedFiles; + $this->data = $data; + $this->attributes = $attributes; } public function getRequestTarget() @@ -34,7 +43,7 @@ public function getRequestTarget() public function withRequestTarget($requestTarget) { - $this->requestTarget = $requestTarget; + throw \BadMethodCallException('Not implemented.'); } public function getMethod() @@ -44,7 +53,6 @@ public function getMethod() public function withMethod($method) { - $this->method = $method; } public function getUri() @@ -54,7 +62,7 @@ public function getUri() public function withUri(UriInterface $uri, $preserveHost = false) { - $this->uri = $uri; + throw \BadMethodCallException('Not implemented.'); } public function getServerParams() @@ -69,7 +77,7 @@ public function getCookieParams() public function withCookieParams(array $cookies) { - $this->cookies = $cookies; + throw \BadMethodCallException('Not implemented.'); } public function getQueryParams() @@ -79,7 +87,7 @@ public function getQueryParams() public function withQueryParams(array $query) { - $this->query = $query; + throw \BadMethodCallException('Not implemented.'); } public function getUploadedFiles() @@ -89,7 +97,7 @@ public function getUploadedFiles() public function withUploadedFiles(array $uploadedFiles) { - $this->uploadedFiles = $uploadedFiles; + throw \BadMethodCallException('Not implemented.'); } public function getParsedBody() @@ -99,7 +107,7 @@ public function getParsedBody() public function withParsedBody($data) { - $this->data = $data; + throw \BadMethodCallException('Not implemented.'); } public function getAttributes() @@ -114,13 +122,11 @@ public function getAttribute($name, $default = null) public function withAttribute($name, $value) { - $this->attributes[$name] = $value; + throw \BadMethodCallException('Not implemented.'); } public function withoutAttribute($name) { - if ($this->getAttribute($name)) { - unset($this->attributes[$name]); - } + throw \BadMethodCallException('Not implemented.'); } } From 77360d65b72bd78d127f2762b10881633747e182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 09:46:59 +0200 Subject: [PATCH 13/37] Uploaded file support --- Factory/DiactorosFactory.php | 18 ++++++- Factory/HttpFoundationFactory.php | 52 ++++++++++++++++++- HttpFoundationFactoryInterface.php | 17 ++++-- PsrHttpMessageFactoryInterface.php | 17 ++++-- Tests/Factory/HttpFoundationFactoryTest.php | 25 +++++++++ Tests/Fixtures/UploadedFile.php | 57 +++++++++++++++++++++ 6 files changed, 177 insertions(+), 9 deletions(-) create mode 100644 Tests/Fixtures/UploadedFile.php diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 6142a93..1160a24 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -3,10 +3,12 @@ namespace Symfony\Bridge\PsrHttpMessage\Factory; use Symfony\Bridge\PsrHttpMessage\PsrHttpMessageFactoryInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Zend\Diactoros\ServerRequest; +use Zend\Diactoros\ServerRequest as DiactorosRequest; use Zend\Diactoros\Response as DiactorosResponse; +use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; /** * Builds Psr\HttpMessage instances using the Zend Diactoros implementation. @@ -21,7 +23,7 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface */ public function createRequest(Request $symfonyRequest) { - return new ServerRequest( + return new DiactorosRequest( ); } @@ -35,4 +37,16 @@ public function createResponse(Response $symfonyResponse) ); } + + /** + * {@inheritdoc} + */ + public function createUploadedFile(UploadedFile $symfonyUploadedFile) + { + return new DiactorosUploadedFile( + null, + null, + null + ); + } } diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 1e544d5..dc67636 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -4,7 +4,9 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UploadedFileInterface; use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -28,14 +30,62 @@ public function createRequest(ServerRequestInterface $psrHttpMessageRequest) $request, $psrHttpMessageRequest->getAttributes(), $psrHttpMessageRequest->getCookieParams(), - array(), // TODO + $this->getFiles($psrHttpMessageRequest->getUploadedFiles()), $psrHttpMessageRequest->getServerParams(), $psrHttpMessageRequest->getBody()->__toString() ); } + /** + * Converts to the input array to $_FILES structure. + * + * @param array $uploadedFiles + * + * @return array + */ private function getFiles(array $uploadedFiles) { + $files = array(); + + foreach ($uploadedFiles as $key => $value) { + if ($value instanceof UploadedFileInterface) { + $files[$key] = $this->createUploadedFile($value); + } else { + $files[$key] = $this->getFiles($value); + } + } + + return $files; + } + + /** + * {@inheritdoc} + */ + public function createUploadedFile(UploadedFileInterface $psrUploadedFile) + { + $tempnam = $this->getTemporaryPath(); + $psrUploadedFile->moveTo($tempnam); + + $clientFileName = $psrUploadedFile->getClientFilename(); + + return new UploadedFile( + $tempnam, + null === $clientFileName ? '' : $clientFileName, + $psrUploadedFile->getClientMediaType(), + $psrUploadedFile->getSize(), + $psrUploadedFile->getError(), + true + ); + } + + /** + * Gets a temporary file path. + * + * @return string + */ + protected function getTemporaryPath() + { + return tempnam(sys_get_temp_dir(), uniqid('symfony', true)); } /** diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index 064385c..1af29a7 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -4,18 +4,20 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UploadedFileInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** - * Creates Symfony Request and Response from PSR-7 ones. + * Creates Symfony Request and Response instances from PSR-7 ones. * * @author Kévin Dunglas */ interface HttpFoundationFactoryInterface { /** - * Creates a Symfony Request from a PSR-7 one. + * Creates a Symfony Request instance from a PSR-7 one. * * @param ServerRequestInterface $psrHttpMessageRequest * @@ -24,7 +26,16 @@ interface HttpFoundationFactoryInterface public function createRequest(ServerRequestInterface $psrHttpMessageRequest); /** - * Creates a Symfony Response from a PSR-7 one. + * Creates Symfony UploadedFile instance from PSR-7 ones. + * + * @param UploadedFileInterface $psrUploadedFile + * + * @return UploadedFile + */ + public function createUploadedFile(UploadedFileInterface $psrUploadedFile); + + /** + * Creates a Symfony Response instance from a PSR-7 one. * * @param ResponseInterface $psrHttpMessageResponse * diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php index 31cb721..b04bc59 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/PsrHttpMessageFactoryInterface.php @@ -4,18 +4,20 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UploadedFileInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** - * Creates PSR HTTP Request and Response from Symfony ones. + * Creates PSR HTTP Request and Response instances from Symfony ones. * * @author Kévin Dunglas */ interface PsrHttpMessageFactoryInterface { /** - * Creates a PSR-7 Request from a Symfony one. + * Creates a PSR-7 Request instance from a Symfony one. * * @param Request $symfonyRequest * @@ -24,7 +26,16 @@ interface PsrHttpMessageFactoryInterface public function createRequest(Request $symfonyRequest); /** - * Creates a PSR-7 Response from a Symfony one. + * Creates a PSR-7 UploadedFile instance from a Symfony one. + * + * @param UploadedFile $symfonyUploadedFile + * + * @return UploadedFileInterface + */ + public function createUploadedFile(UploadedFile $symfonyUploadedFile); + + /** + * Creates a PSR-7 Response instance from a Symfony one. * * @param Response $symfonyResponse * diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 2288ac0..e89f61c 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -1,9 +1,11 @@ @@ -85,6 +87,29 @@ public function testCreateRequestWithObjectParsedBody() $this->assertCount(0, $this->factory->createRequest($serverRequest)->request); } + public function testCreateUploadedFile() + { + $tmpDir = sys_get_temp_dir(); + + $filePath = tempnam($tmpDir, uniqid()); + file_put_contents($filePath, 'An uploaded file.'); + + $size = filesize($filePath); + $uploadedFile = new UploadedFile($filePath, $size, UPLOAD_ERR_OK, 'myfile.txt', 'text/plain'); + + $symfonyUploadedFile = $this->factory->createUploadedFile($uploadedFile); + + $uniqid = uniqid(); + $symfonyUploadedFile->move($tmpDir, $uniqid); + + $this->assertEquals($size, $symfonyUploadedFile->getClientSize()); + $this->assertEquals(UPLOAD_ERR_OK, $symfonyUploadedFile->getError()); + $this->assertEquals('myfile.txt', $symfonyUploadedFile->getClientOriginalName()); + $this->assertEquals('txt', $symfonyUploadedFile->getClientOriginalExtension()); + $this->assertEquals('text/plain', $symfonyUploadedFile->getClientMimeType()); + $this->assertEquals('An uploaded file.', file_get_contents($tmpDir.'/'.$uniqid)); + } + public function testCreateResponse() { diff --git a/Tests/Fixtures/UploadedFile.php b/Tests/Fixtures/UploadedFile.php new file mode 100644 index 0000000..de02397 --- /dev/null +++ b/Tests/Fixtures/UploadedFile.php @@ -0,0 +1,57 @@ + + */ +class UploadedFile implements UploadedFileInterface +{ + private $filePath; + private $size; + private $error; + private $clientFileName; + private $clientMediaType; + + public function __construct($filePath, $size = null, $error = UPLOAD_ERR_OK, $clientFileName = null, $clientMediaType = null) + { + $this->filePath = $filePath; + $this->size = $size; + $this->error = $error; + $this->clientFileName = $clientFileName; + $this->clientMediaType = $clientMediaType; + } + + public function getStream() + { + throw new \RuntimeException('No stream is available.'); + } + + public function moveTo($targetPath) + { + rename($this->filePath, $targetPath); + } + + public function getSize() + { + return $this->size; + } + + public function getError() + { + return $this->error; + } + + public function getClientFilename() + { + return $this->clientFileName; + } + + public function getClientMediaType() + { + return $this->clientMediaType; + } +} From 6f5815b06e933d3008a0249c6a4183adb9e2271b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 11:02:53 +0200 Subject: [PATCH 14/37] Fix some @stof comments --- Factory/HttpFoundationFactory.php | 18 +++++++++--------- HttpFoundationFactoryInterface.php | 8 ++++---- composer.json | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index dc67636..3b1b89d 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -20,19 +20,19 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface /** * {@inheritdoc} */ - public function createRequest(ServerRequestInterface $psrHttpMessageRequest) + public function createRequest(ServerRequestInterface $psrRequest) { - $parsedBody = $psrHttpMessageRequest->getParsedBody(); + $parsedBody = $psrRequest->getParsedBody(); $request = is_array($parsedBody) ? $parsedBody : array(); return new Request( - $psrHttpMessageRequest->getQueryParams(), + $psrRequest->getQueryParams(), $request, - $psrHttpMessageRequest->getAttributes(), - $psrHttpMessageRequest->getCookieParams(), - $this->getFiles($psrHttpMessageRequest->getUploadedFiles()), - $psrHttpMessageRequest->getServerParams(), - $psrHttpMessageRequest->getBody()->__toString() + $psrRequest->getAttributes(), + $psrRequest->getCookieParams(), + $this->getFiles($psrRequest->getUploadedFiles()), + $psrRequest->getServerParams(), + $psrRequest->getBody()->__toString() ); } @@ -91,7 +91,7 @@ protected function getTemporaryPath() /** * {@inheritdoc} */ - public function createResponse(ResponseInterface $psrHttpMessageResponse) + public function createResponse(ResponseInterface $psrResponse) { return new Response( diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index 1af29a7..a066d01 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -19,11 +19,11 @@ interface HttpFoundationFactoryInterface /** * Creates a Symfony Request instance from a PSR-7 one. * - * @param ServerRequestInterface $psrHttpMessageRequest + * @param ServerRequestInterface $psrRequest * * @return Request */ - public function createRequest(ServerRequestInterface $psrHttpMessageRequest); + public function createRequest(ServerRequestInterface $psrRequest); /** * Creates Symfony UploadedFile instance from PSR-7 ones. @@ -37,9 +37,9 @@ public function createUploadedFile(UploadedFileInterface $psrUploadedFile); /** * Creates a Symfony Response instance from a PSR-7 one. * - * @param ResponseInterface $psrHttpMessageResponse + * @param ResponseInterface $psrResponse * * @return Response */ - public function createResponse(ResponseInterface $psrHttpMessageResponse); + public function createResponse(ResponseInterface $psrResponse); } diff --git a/composer.json b/composer.json index 57eae1b..43f25be 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "zendframework/zend-diactoros": "~1.0" }, "suggest": { - "zendframework/zend-diactoros": "To use the zend-diactoros adapter" + "zendframework/zend-diactoros": "To use the zend-diactoros factory" }, "autoload": { "psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" } From 52405397d57b5108ce647e6e30ddd35690503cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 22 May 2015 23:27:01 +0200 Subject: [PATCH 15/37] Add license headers --- Factory/DiactorosFactory.php | 9 +++++++++ Factory/HttpFoundationFactory.php | 9 +++++++++ HttpFoundationFactoryInterface.php | 9 +++++++++ PsrHttpMessageFactoryInterface.php | 9 +++++++++ Tests/Factory/DiactorosFactoryTest.php | 9 +++++++++ Tests/Factory/HttpFoundationFactoryTest.php | 9 +++++++++ Tests/Fixtures/Message.php | 9 +++++++++ Tests/Fixtures/ServerRequest.php | 9 +++++++++ Tests/Fixtures/Stream.php | 9 +++++++++ Tests/Fixtures/UploadedFile.php | 10 +++++++++- 10 files changed, 90 insertions(+), 1 deletion(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 1160a24..8a9fd4f 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Factory; use Symfony\Bridge\PsrHttpMessage\PsrHttpMessageFactoryInterface; diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 3b1b89d..fe6fac6 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Factory; use Psr\Http\Message\ServerRequestInterface; diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index a066d01..acdd44d 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage; use Psr\Http\Message\ServerRequestInterface; diff --git a/PsrHttpMessageFactoryInterface.php b/PsrHttpMessageFactoryInterface.php index b04bc59..c6b4ab9 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/PsrHttpMessageFactoryInterface.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage; use Psr\Http\Message\ServerRequestInterface; diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 4b4322c..6ff4cb4 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; /** diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index e89f61c..99d2cb2 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; diff --git a/Tests/Fixtures/Message.php b/Tests/Fixtures/Message.php index ee49172..b94e299 100644 --- a/Tests/Fixtures/Message.php +++ b/Tests/Fixtures/Message.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; use Psr\Http\Message\MessageInterface; diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php index 3b5ac4c..4622337 100644 --- a/Tests/Fixtures/ServerRequest.php +++ b/Tests/Fixtures/ServerRequest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; use Psr\Http\Message\ServerRequestInterface; diff --git a/Tests/Fixtures/Stream.php b/Tests/Fixtures/Stream.php index acb13e1..aeca3d8 100644 --- a/Tests/Fixtures/Stream.php +++ b/Tests/Fixtures/Stream.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; use Psr\Http\Message\StreamInterface; diff --git a/Tests/Fixtures/UploadedFile.php b/Tests/Fixtures/UploadedFile.php index de02397..4cfa98b 100644 --- a/Tests/Fixtures/UploadedFile.php +++ b/Tests/Fixtures/UploadedFile.php @@ -1,8 +1,16 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; -use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; /** From 8b4a07858e8fd6cb501400d35f1697854b128cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 23 May 2015 08:42:49 +0200 Subject: [PATCH 16/37] More unit tests for uploaded files. --- Tests/Factory/HttpFoundationFactoryTest.php | 52 ++++++++++++++++----- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 99d2cb2..6d58699 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -22,10 +22,12 @@ class HttpFoundationFactoryTest extends \PHPUnit_Framework_TestCase { private $factory; + private $tmpDir; public function setup() { $this->factory = new HttpFoundationFactory(); + $this->tmpDir = sys_get_temp_dir(); } public function testCreateRequest() @@ -41,7 +43,15 @@ public function testCreateRequest() array('country' => 'France'), array('city' => 'Lille'), array('url' => 'http://les-tilleuls.coop'), - array(), + array( + 'doc1' => $this->createUploadedFile('Doc 1', UPLOAD_ERR_OK, 'doc1.txt', 'text/plain'), + 'nested' => array( + 'docs' => array( + $this->createUploadedFile('Doc 2', UPLOAD_ERR_OK, 'doc2.txt', 'text/plain'), + $this->createUploadedFile('Doc 3', UPLOAD_ERR_OK, 'doc3.txt', 'text/plain'), + ) + ) + ), array('url' => 'http://dunglas.fr'), array('custom' => $stdClass) ); @@ -49,6 +59,9 @@ public function testCreateRequest() $symfonyRequest = $this->factory->createRequest($serverRequest); $this->assertEquals('http://les-tilleuls.coop', $symfonyRequest->query->get('url')); + $this->assertEquals('doc1.txt', $symfonyRequest->files->get('doc1')->getClientOriginalName()); + $this->assertEquals('doc2.txt', $symfonyRequest->files->get('nested[docs][0]', null, true)->getClientOriginalName()); + $this->assertEquals('doc3.txt', $symfonyRequest->files->get('nested[docs][1]', null, true)->getClientOriginalName()); $this->assertEquals('http://dunglas.fr', $symfonyRequest->request->get('url')); $this->assertEquals($stdClass, $symfonyRequest->attributes->get('custom')); $this->assertEquals('Lille', $symfonyRequest->cookies->get('city')); @@ -98,25 +111,40 @@ public function testCreateRequestWithObjectParsedBody() public function testCreateUploadedFile() { - $tmpDir = sys_get_temp_dir(); - - $filePath = tempnam($tmpDir, uniqid()); - file_put_contents($filePath, 'An uploaded file.'); - - $size = filesize($filePath); - $uploadedFile = new UploadedFile($filePath, $size, UPLOAD_ERR_OK, 'myfile.txt', 'text/plain'); - + $uploadedFile = $this->createUploadedFile('An uploaded file.', UPLOAD_ERR_OK, 'myfile.txt', 'text/plain'); $symfonyUploadedFile = $this->factory->createUploadedFile($uploadedFile); $uniqid = uniqid(); - $symfonyUploadedFile->move($tmpDir, $uniqid); + $symfonyUploadedFile->move($this->tmpDir, $uniqid); - $this->assertEquals($size, $symfonyUploadedFile->getClientSize()); + $this->assertEquals($uploadedFile->getSize(), $symfonyUploadedFile->getClientSize()); $this->assertEquals(UPLOAD_ERR_OK, $symfonyUploadedFile->getError()); $this->assertEquals('myfile.txt', $symfonyUploadedFile->getClientOriginalName()); $this->assertEquals('txt', $symfonyUploadedFile->getClientOriginalExtension()); $this->assertEquals('text/plain', $symfonyUploadedFile->getClientMimeType()); - $this->assertEquals('An uploaded file.', file_get_contents($tmpDir.'/'.$uniqid)); + $this->assertEquals('An uploaded file.', file_get_contents($this->tmpDir.'/'.$uniqid)); + } + + /** + * @expectedException \Symfony\Component\HttpFoundation\File\Exception\FileException + * @expectedExceptionMessage The file "e" could not be written on disk. + */ + public function testCreateUploadedFileWithError() + { + $uploadedFile = $this->createUploadedFile('Error.', UPLOAD_ERR_CANT_WRITE, 'e', 'text/plain'); + $symfonyUploadedFile = $this->factory->createUploadedFile($uploadedFile); + + $this->assertEquals(UPLOAD_ERR_CANT_WRITE, $symfonyUploadedFile->getError()); + + $symfonyUploadedFile->move($this->tmpDir, 'shouldFail.txt'); + } + + private function createUploadedFile($content, $error, $clientFileName, $clientMediaType) + { + $filePath = tempnam($this->tmpDir, uniqid()); + file_put_contents($filePath, $content); + + return new UploadedFile($filePath, filesize($filePath), $error, $clientFileName, $clientMediaType); } public function testCreateResponse() From 14dac4e4e980190d31c639035d889264147bc530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 23 May 2015 09:14:12 +0200 Subject: [PATCH 17/37] HttpFoundation Response factory and tests --- Factory/HttpFoundationFactory.php | 9 ++++- Tests/Factory/HttpFoundationFactoryTest.php | 15 +++++++ Tests/Fixtures/Response.php | 45 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 Tests/Fixtures/Response.php diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index fe6fac6..2b3ee8e 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -102,8 +102,13 @@ protected function getTemporaryPath() */ public function createResponse(ResponseInterface $psrResponse) { - return new Response( - + $response = new Response( + $psrResponse->getBody()->__toString(), + $psrResponse->getStatusCode(), + $psrResponse->getHeaders() ); + $response->setProtocolVersion($psrResponse->getProtocolVersion()); + + return $response; } } diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 6d58699..d0843ea 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; +use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Response; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\ServerRequest; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Stream; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\UploadedFile; @@ -149,6 +150,20 @@ private function createUploadedFile($content, $error, $clientFileName, $clientMe public function testCreateResponse() { + $response = new Response( + '1.0', + array( + 'X-Symfony' => '2.8' + ), + new Stream('The response body'), + 200 + ); + + $symfonyResponse = $this->factory->createResponse($response); + $this->assertEquals('1.0', $symfonyResponse->getProtocolVersion()); + $this->assertEquals('2.8', $symfonyResponse->headers->get('X-Symfony')); + $this->assertEquals('The response body', $symfonyResponse->getContent()); + $this->assertEquals(200, $symfonyResponse->getStatusCode()); } } diff --git a/Tests/Fixtures/Response.php b/Tests/Fixtures/Response.php new file mode 100644 index 0000000..204cc8e --- /dev/null +++ b/Tests/Fixtures/Response.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PsrHttpMessage\Tests\Fixtures; + +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; + +/** + * @author Kévin Dunglas + */ +class Response extends Message implements ResponseInterface +{ + private $statusCode; + + public function __construct($version = '1.1', array $headers = array(), StreamInterface $body = null, $statusCode) + { + parent::__construct($version, $headers, $body); + + $this->statusCode = $statusCode; + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function withStatus($code, $reasonPhrase = '') + { + throw \BadMethodCallException('Not implemented.'); + } + + public function getReasonPhrase() + { + throw \BadMethodCallException('Not implemented.'); + } +} From 8c3c90e06b29e4730b3647762b8089f10b69b44e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 23 May 2015 09:14:34 +0200 Subject: [PATCH 18/37] Fix CS --- Factory/DiactorosFactory.php | 1 - Tests/Factory/DiactorosFactoryTest.php | 2 -- Tests/Factory/HttpFoundationFactoryTest.php | 6 +++--- Tests/Fixtures/Message.php | 2 +- Tests/Fixtures/ServerRequest.php | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 8a9fd4f..cd82d24 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -26,7 +26,6 @@ */ class DiactorosFactory implements PsrHttpMessageFactoryInterface { - /** * {@inheritdoc} */ diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 6ff4cb4..cea5108 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -18,11 +18,9 @@ class DiactorosFactoryTest extends \PHPUnit_Framework_TestCase { public function testCreateRequest() { - } public function testCreateResponse() { - } } diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index d0843ea..8a7192e 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -50,8 +50,8 @@ public function testCreateRequest() 'docs' => array( $this->createUploadedFile('Doc 2', UPLOAD_ERR_OK, 'doc2.txt', 'text/plain'), $this->createUploadedFile('Doc 3', UPLOAD_ERR_OK, 'doc3.txt', 'text/plain'), - ) - ) + ), + ), ), array('url' => 'http://dunglas.fr'), array('custom' => $stdClass) @@ -153,7 +153,7 @@ public function testCreateResponse() $response = new Response( '1.0', array( - 'X-Symfony' => '2.8' + 'X-Symfony' => '2.8', ), new Stream('The response body'), 200 diff --git a/Tests/Fixtures/Message.php b/Tests/Fixtures/Message.php index b94e299..cb30ec2 100644 --- a/Tests/Fixtures/Message.php +++ b/Tests/Fixtures/Message.php @@ -59,7 +59,7 @@ public function getHeader($name) public function getHeaderLine($name) { - return $this->hasHeader($name) ? join(',', $this->headers[$name]) : ''; + return $this->hasHeader($name) ? implode(',', $this->headers[$name]) : ''; } public function withHeader($name, $value) diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php index 4622337..593e940 100644 --- a/Tests/Fixtures/ServerRequest.php +++ b/Tests/Fixtures/ServerRequest.php @@ -20,7 +20,7 @@ */ class ServerRequest extends Message implements ServerRequestInterface { - private $requestTarget ; + private $requestTarget; private $method; private $uri; private $server; From 65261eef193db91ada7f574aa1e26cd67e642186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 23 May 2015 23:39:43 +0200 Subject: [PATCH 19/37] Diactoros factory draft implementation --- Factory/DiactorosFactory.php | 41 ++++++++++++++++++++++---- Factory/HttpFoundationFactory.php | 6 ++-- Tests/Factory/DiactorosFactoryTest.php | 1 + 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index cd82d24..4f93a35 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -32,17 +32,46 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface public function createRequest(Request $symfonyRequest) { return new DiactorosRequest( - + $symfonyRequest->server->all(), + array(), + $symfonyRequest->getUri(), + $symfonyRequest->getMethod(), + $symfonyRequest->getContent(), + $symfonyRequest->server->getHeaders() ); } + /** + * Converts Symfony uploaded files array to the PSR one. + * + * @param array $uploadedFiles + * + * @return array + */ + private function getFiles(array $uploadedFiles) + { + $files = array(); + + foreach ($uploadedFiles as $key => $value) { + if ($value instanceof UploadedFile) { + $files[$key] = $this->createUploadedFile($value); + } else { + $files[$key] = $this->getFiles($value); + } + } + + return $files; + } + /** * {@inheritdoc} */ public function createResponse(Response $symfonyResponse) { return new DiactorosResponse( - + $symfonyResponse->getContent(), + $symfonyResponse->getStatusCode(), + $symfonyResponse->headers->all() ); } @@ -52,9 +81,11 @@ public function createResponse(Response $symfonyResponse) public function createUploadedFile(UploadedFile $symfonyUploadedFile) { return new DiactorosUploadedFile( - null, - null, - null + $symfonyUploadedFile->getRealPath(), + $symfonyUploadedFile->getSize(), + $symfonyUploadedFile->getError(), + $symfonyUploadedFile->getClientOriginalName(), + $symfonyUploadedFile->getClientMimeType() ); } } diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 2b3ee8e..8a1b981 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -72,13 +72,13 @@ private function getFiles(array $uploadedFiles) */ public function createUploadedFile(UploadedFileInterface $psrUploadedFile) { - $tempnam = $this->getTemporaryPath(); - $psrUploadedFile->moveTo($tempnam); + $temporaryPath = $this->getTemporaryPath(); + $psrUploadedFile->moveTo($temporaryPath); $clientFileName = $psrUploadedFile->getClientFilename(); return new UploadedFile( - $tempnam, + $temporaryPath, null === $clientFileName ? '' : $clientFileName, $psrUploadedFile->getClientMediaType(), $psrUploadedFile->getSize(), diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index cea5108..ce92002 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -10,6 +10,7 @@ */ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; +use Symfony\Component\HttpFoundation\Request; /** * @author Kévin Dunglas From 7e44bc24eab6cacdd14c3be97282cedcadf2c154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 10:49:36 +0200 Subject: [PATCH 20/37] New version of DiactorosFactory::createRequest(). Tests. --- Factory/DiactorosFactory.php | 43 +++++++------ Tests/Factory/DiactorosFactoryTest.php | 87 ++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 4f93a35..640de8a 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -15,8 +15,8 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Zend\Diactoros\ServerRequest as DiactorosRequest; use Zend\Diactoros\Response as DiactorosResponse; +use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; /** @@ -31,14 +31,19 @@ class DiactorosFactory implements PsrHttpMessageFactoryInterface */ public function createRequest(Request $symfonyRequest) { - return new DiactorosRequest( + $request = DiactorosRequestFactory::fromGlobals( $symfonyRequest->server->all(), - array(), - $symfonyRequest->getUri(), - $symfonyRequest->getMethod(), - $symfonyRequest->getContent(), - $symfonyRequest->server->getHeaders() + $symfonyRequest->query->all(), + $symfonyRequest->request->all(), + $symfonyRequest->cookies->all(), + $this->getFiles($symfonyRequest->files->all()) ); + + foreach ($symfonyRequest->attributes->all() as $key => $value) { + $request = $request->withAttribute($key, $value); + } + + return $request; } /** @@ -63,18 +68,6 @@ private function getFiles(array $uploadedFiles) return $files; } - /** - * {@inheritdoc} - */ - public function createResponse(Response $symfonyResponse) - { - return new DiactorosResponse( - $symfonyResponse->getContent(), - $symfonyResponse->getStatusCode(), - $symfonyResponse->headers->all() - ); - } - /** * {@inheritdoc} */ @@ -88,4 +81,16 @@ public function createUploadedFile(UploadedFile $symfonyUploadedFile) $symfonyUploadedFile->getClientMimeType() ); } + + /** + * {@inheritdoc} + */ + public function createResponse(Response $symfonyResponse) + { + return new DiactorosResponse( + $symfonyResponse->getContent(), + $symfonyResponse->getStatusCode(), + $symfonyResponse->headers->all() + ); + } } diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index ce92002..967c43f 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -10,6 +10,9 @@ */ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; + +use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; /** @@ -17,8 +20,92 @@ */ class DiactorosFactoryTest extends \PHPUnit_Framework_TestCase { + private $factory; + private $tmpDir; + + public function setup() + { + $this->factory = new DiactorosFactory(); + $this->tmpDir = sys_get_temp_dir(); + } + public function testCreateRequest() { + $stdClass = new \stdClass(); + $request = new Request( + array( + 'foo' => '1', + 'bar' => array('baz' => '42'), + ), + array( + 'twitter' => array( + '@dunglas' => 'Kévin Dunglas', + '@coopTilleuls' => 'Les-Tilleuls.coop', + ), + 'baz' => '2', + ), + array( + 'a1' => $stdClass, + 'a2' => array('foo' => 'bar'), + ), + array( + 'c1' => 'foo', + 'c2' => array('c3' => 'bar'), + ), + array( + 'f1' => $this->createUploadedFile('F1', 'f1.txt', 'text/plain', UPLOAD_ERR_OK), + 'foo' => array('f2' => $this->createUploadedFile('F2', 'f2.txt', 'text/plain', UPLOAD_ERR_OK)), + ), + array( + 'REQUEST_METHOD' => 'POST', + 'HTTP_X_SYMFONY' => '2.8', + ), + 'Content' + ); + + $psrRequest = $this->factory->createRequest($request); + + $queryParams = $psrRequest->getQueryParams(); + $this->assertEquals('1', $queryParams['foo']); + $this->assertEquals('42', $queryParams['bar']['baz']); + + $parsedBody = $psrRequest->getParsedBody(); + $this->assertEquals('Kévin Dunglas', $parsedBody['twitter']['@dunglas']); + $this->assertEquals('Les-Tilleuls.coop', $parsedBody['twitter']['@coopTilleuls']); + $this->assertEquals('2', $parsedBody['baz']); + + $attributes = $psrRequest->getAttributes(); + $this->assertEquals($stdClass, $attributes['a1']); + $this->assertEquals('bar', $attributes['a2']['foo']); + + $cookies = $psrRequest->getCookieParams(); + $this->assertEquals('foo', $cookies['c1']); + $this->assertEquals('bar', $cookies['c2']['c3']); + + $uploadedFiles = $psrRequest->getUploadedFiles(); + $this->assertEquals('F1', $uploadedFiles['f1']->getStream()->__toString()); + $this->assertEquals('f1.txt', $uploadedFiles['f1']->getClientFilename()); + $this->assertEquals('text/plain', $uploadedFiles['f1']->getClientMediaType()); + $this->assertEquals(UPLOAD_ERR_OK, $uploadedFiles['f1']->getError()); + + $this->assertEquals('F2', $uploadedFiles['foo']['f2']->getStream()->__toString()); + $this->assertEquals('f2.txt', $uploadedFiles['foo']['f2']->getClientFilename()); + $this->assertEquals('text/plain', $uploadedFiles['foo']['f2']->getClientMediaType()); + $this->assertEquals(UPLOAD_ERR_OK, $uploadedFiles['foo']['f2']->getError()); + + $serverParams = $psrRequest->getServerParams(); + $this->assertEquals('POST', $serverParams['REQUEST_METHOD']); + $this->assertEquals('2.8', $serverParams['HTTP_X_SYMFONY']); + $this->assertEquals('POST', $psrRequest->getMethod()); + $this->assertEquals(array('2.8'), $psrRequest->getHeader('X-Symfony')); + } + + private function createUploadedFile($content, $originalName, $mimeType, $error) + { + $path = tempnam($this->tmpDir, uniqid()); + file_put_contents($path, $content); + + return new UploadedFile($path, $originalName, $mimeType, filesize($path), $error, true); } public function testCreateResponse() From 1e480a9321f07926f34b499876e85b0a743e6bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 11:02:49 +0200 Subject: [PATCH 21/37] Rename HttpMessageFactoryInterface --- Factory/DiactorosFactory.php | 4 ++-- ...ageFactoryInterface.php => HttpMessageFactoryInterface.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename PsrHttpMessageFactoryInterface.php => HttpMessageFactoryInterface.php (97%) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 640de8a..d859a30 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -11,7 +11,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Factory; -use Symfony\Bridge\PsrHttpMessage\PsrHttpMessageFactoryInterface; +use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -24,7 +24,7 @@ * * @author Kévin Dunglas */ -class DiactorosFactory implements PsrHttpMessageFactoryInterface +class DiactorosFactory implements HttpMessageFactoryInterface { /** * {@inheritdoc} diff --git a/PsrHttpMessageFactoryInterface.php b/HttpMessageFactoryInterface.php similarity index 97% rename from PsrHttpMessageFactoryInterface.php rename to HttpMessageFactoryInterface.php index c6b4ab9..ac0b497 100644 --- a/PsrHttpMessageFactoryInterface.php +++ b/HttpMessageFactoryInterface.php @@ -23,7 +23,7 @@ * * @author Kévin Dunglas */ -interface PsrHttpMessageFactoryInterface +interface HttpMessageFactoryInterface { /** * Creates a PSR-7 Request instance from a Symfony one. From 9127c843e8beb002f659b2a548aacfdd9d19112e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 11:04:01 +0200 Subject: [PATCH 22/37] Update LICENSE copyright year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 0b3292c..43028bc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2014 Fabien Potencier +Copyright (c) 2004-2015 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From b3600681217e29e3a57d2e67c6ec337de5a33a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 18:59:23 +0200 Subject: [PATCH 23/37] Better stream handling in DiactorosFactory::createRequest --- Factory/DiactorosFactory.php | 10 ++++++++++ Tests/Factory/DiactorosFactoryTest.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index d859a30..eaa611c 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Response; use Zend\Diactoros\Response as DiactorosResponse; use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; +use Zend\Diactoros\Stream as DiactorosStream; use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; /** @@ -31,6 +32,13 @@ class DiactorosFactory implements HttpMessageFactoryInterface */ public function createRequest(Request $symfonyRequest) { + try { + $stream = new DiactorosStream($symfonyRequest->getContent(true)); + } catch (\LogicException $e) { + $stream = new DiactorosStream('php://temp', 'wb+'); + $stream->write($symfonyRequest->getContent()); + } + $request = DiactorosRequestFactory::fromGlobals( $symfonyRequest->server->all(), $symfonyRequest->query->all(), @@ -39,6 +47,8 @@ public function createRequest(Request $symfonyRequest) $this->getFiles($symfonyRequest->files->all()) ); + $request = $request->withBody($stream); + foreach ($symfonyRequest->attributes->all() as $key => $value) { $request = $request->withAttribute($key, $value); } diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 967c43f..abc8b60 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -65,6 +65,8 @@ public function testCreateRequest() $psrRequest = $this->factory->createRequest($request); + $this->assertEquals('Content', $psrRequest->getBody()->__toString()); + $queryParams = $psrRequest->getQueryParams(); $this->assertEquals('1', $queryParams['foo']); $this->assertEquals('42', $queryParams['bar']['baz']); From 4d11665791617a9d91f49bfb2601fd6f1c973b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 19:22:18 +0200 Subject: [PATCH 24/37] New DiactorosFactory::createResponse implementation. Tests. --- Factory/DiactorosFactory.php | 28 +++++++++++++++++--------- Tests/Factory/DiactorosFactoryTest.php | 11 ++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index eaa611c..9d0b86b 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -32,13 +32,6 @@ class DiactorosFactory implements HttpMessageFactoryInterface */ public function createRequest(Request $symfonyRequest) { - try { - $stream = new DiactorosStream($symfonyRequest->getContent(true)); - } catch (\LogicException $e) { - $stream = new DiactorosStream('php://temp', 'wb+'); - $stream->write($symfonyRequest->getContent()); - } - $request = DiactorosRequestFactory::fromGlobals( $symfonyRequest->server->all(), $symfonyRequest->query->all(), @@ -47,6 +40,13 @@ public function createRequest(Request $symfonyRequest) $this->getFiles($symfonyRequest->files->all()) ); + try { + $stream = new DiactorosStream($symfonyRequest->getContent(true)); + } catch (\LogicException $e) { + $stream = new DiactorosStream('php://temp', 'wb+'); + $stream->write($symfonyRequest->getContent()); + } + $request = $request->withBody($stream); foreach ($symfonyRequest->attributes->all() as $key => $value) { @@ -97,10 +97,20 @@ public function createUploadedFile(UploadedFile $symfonyUploadedFile) */ public function createResponse(Response $symfonyResponse) { - return new DiactorosResponse( - $symfonyResponse->getContent(), + $stream = new DiactorosStream('php://temp', 'wb+'); + $stream->write($symfonyResponse->getContent()); + + $response = new DiactorosResponse( + $stream, $symfonyResponse->getStatusCode(), $symfonyResponse->headers->all() ); + + $protocolVersion = $symfonyResponse->getProtocolVersion(); + if ('1.1' !== $protocolVersion) { + $response = $response->withProtocolVersion($protocolVersion); + } + + return $response; } } diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index abc8b60..85f40bd 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -14,6 +14,7 @@ use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; /** * @author Kévin Dunglas @@ -112,5 +113,15 @@ private function createUploadedFile($content, $originalName, $mimeType, $error) public function testCreateResponse() { + $response = new Response( + 'Response content.', + 202, + array('X-Symfony' => array('2.8')) + ); + + $psrResponse = $this->factory->createResponse($response); + $this->assertEquals('Response content.', $psrResponse->getBody()->__toString()); + $this->assertEquals(202, $psrResponse->getStatusCode()); + $this->assertEquals(array('2.8'), $psrResponse->getHeader('X-Symfony')); } } From e129154703ce0bbc03b803bbeec02958fa29433e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 24 May 2015 22:04:04 +0200 Subject: [PATCH 25/37] StreamedResponse support --- Factory/DiactorosFactory.php | 13 ++++++++++++- Tests/Factory/DiactorosFactoryTest.php | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 9d0b86b..4732463 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; use Zend\Diactoros\Response as DiactorosResponse; use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; use Zend\Diactoros\Stream as DiactorosStream; @@ -98,7 +99,17 @@ public function createUploadedFile(UploadedFile $symfonyUploadedFile) public function createResponse(Response $symfonyResponse) { $stream = new DiactorosStream('php://temp', 'wb+'); - $stream->write($symfonyResponse->getContent()); + if ($symfonyResponse instanceof StreamedResponse) { + ob_start(function ($buffer) use ($stream) { + $stream->write($buffer); + + return false; + }); + $symfonyResponse->sendContent(); + ob_end_clean(); + } else { + $stream->write($symfonyResponse->getContent()); + } $response = new DiactorosResponse( $stream, diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 85f40bd..2fd9659 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; /** * @author Kévin Dunglas @@ -124,4 +125,19 @@ public function testCreateResponse() $this->assertEquals(202, $psrResponse->getStatusCode()); $this->assertEquals(array('2.8'), $psrResponse->getHeader('X-Symfony')); } + + public function testCreateResponseFromStreamed() + { + $response = new StreamedResponse(function () { + echo "Line 1\n"; + flush(); + + echo "Line 2\n"; + flush(); + }); + + $psrResponse = $this->factory->createResponse($response); + + $this->assertEquals("Line 1\nLine 2\n", $psrResponse->getBody()->__toString()); + } } From 91a13dc66909b64758a7fb62426888c0b38ec0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 25 May 2015 09:15:51 +0200 Subject: [PATCH 26/37] Fix BadMethodCallException --- Tests/Fixtures/Message.php | 10 +++++----- Tests/Fixtures/Response.php | 4 ++-- Tests/Fixtures/ServerRequest.php | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Tests/Fixtures/Message.php b/Tests/Fixtures/Message.php index cb30ec2..5cd0999 100644 --- a/Tests/Fixtures/Message.php +++ b/Tests/Fixtures/Message.php @@ -39,7 +39,7 @@ public function getProtocolVersion() public function withProtocolVersion($version) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getHeaders() @@ -64,17 +64,17 @@ public function getHeaderLine($name) public function withHeader($name, $value) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function withAddedHeader($name, $value) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function withoutHeader($name) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getBody() @@ -84,6 +84,6 @@ public function getBody() public function withBody(StreamInterface $body) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } } diff --git a/Tests/Fixtures/Response.php b/Tests/Fixtures/Response.php index 204cc8e..70717d5 100644 --- a/Tests/Fixtures/Response.php +++ b/Tests/Fixtures/Response.php @@ -35,11 +35,11 @@ public function getStatusCode() public function withStatus($code, $reasonPhrase = '') { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getReasonPhrase() { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } } diff --git a/Tests/Fixtures/ServerRequest.php b/Tests/Fixtures/ServerRequest.php index 593e940..63b8c06 100644 --- a/Tests/Fixtures/ServerRequest.php +++ b/Tests/Fixtures/ServerRequest.php @@ -52,7 +52,7 @@ public function getRequestTarget() public function withRequestTarget($requestTarget) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getMethod() @@ -71,7 +71,7 @@ public function getUri() public function withUri(UriInterface $uri, $preserveHost = false) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getServerParams() @@ -86,7 +86,7 @@ public function getCookieParams() public function withCookieParams(array $cookies) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getQueryParams() @@ -96,7 +96,7 @@ public function getQueryParams() public function withQueryParams(array $query) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getUploadedFiles() @@ -106,7 +106,7 @@ public function getUploadedFiles() public function withUploadedFiles(array $uploadedFiles) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getParsedBody() @@ -116,7 +116,7 @@ public function getParsedBody() public function withParsedBody($data) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function getAttributes() @@ -131,11 +131,11 @@ public function getAttribute($name, $default = null) public function withAttribute($name, $value) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } public function withoutAttribute($name) { - throw \BadMethodCallException('Not implemented.'); + throw new \BadMethodCallException('Not implemented.'); } } From ef384ae537a3418b97fb197528a4134c6459d91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 26 May 2015 00:05:39 +0200 Subject: [PATCH 27/37] Throw an exception if Zend Diactoros isn't installed. --- Factory/DiactorosFactory.php | 8 ++++++++ Tests/Fixtures/Response.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 4732463..d931d7f 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -28,6 +28,13 @@ */ class DiactorosFactory implements HttpMessageFactoryInterface { + public function __construct() + { + if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { + throw new \RuntimeException('Zend Diactoros must be installed ot use the DiactorosFactory.'); + } + } + /** * {@inheritdoc} */ @@ -105,6 +112,7 @@ public function createResponse(Response $symfonyResponse) return false; }); + $symfonyResponse->sendContent(); ob_end_clean(); } else { diff --git a/Tests/Fixtures/Response.php b/Tests/Fixtures/Response.php index 70717d5..0fd85c2 100644 --- a/Tests/Fixtures/Response.php +++ b/Tests/Fixtures/Response.php @@ -21,7 +21,7 @@ class Response extends Message implements ResponseInterface { private $statusCode; - public function __construct($version = '1.1', array $headers = array(), StreamInterface $body = null, $statusCode) + public function __construct($version = '1.1', array $headers = array(), StreamInterface $body = null, $statusCode = 200) { parent::__construct($version, $headers, $body); From bcfa6982f3a3b2d8dda20a430528ada644e4fbf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 26 May 2015 08:13:45 +0200 Subject: [PATCH 28/37] Fix Travis --- .travis.yml | 7 +++---- Factory/DiactorosFactory.php | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index d350695..010a995 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,9 @@ sudo: false matrix: include: - - php: 5.3 - - php: 5.4 - php: 5.5 - php: 5.6 - - php: 5.3 + - php: 5.5 env: deps=low - php: 5.6 env: deps=high @@ -28,7 +26,6 @@ before_install: - composer self-update - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi; - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; - - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi; - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi; # Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi; @@ -36,6 +33,8 @@ before_install: install: - if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi; - if [ "$deps" = "no" ]; then composer --prefer-source install; fi; + - if [ "$deps" = "high" ]; then composer --prefer-source update; fi; + - if [ "$deps" = "low" ]; then composer --prefer-source --prefer-lowest --prefer-stable update; fi; script: - phpunit diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index d931d7f..810d095 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -31,7 +31,7 @@ class DiactorosFactory implements HttpMessageFactoryInterface public function __construct() { if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { - throw new \RuntimeException('Zend Diactoros must be installed ot use the DiactorosFactory.'); + throw new \RuntimeException('Zend Diactoros must be installed to use the DiactorosFactory.'); } } From 8a2bd7bca314eb5c899f10392bf48802faaffc2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 11:01:20 +0200 Subject: [PATCH 29/37] Remove dev dependency to Zend Diactoros --- .travis.yml | 5 ++++- Tests/Factory/DiactorosFactoryTest.php | 4 ++++ composer.json | 3 +-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 010a995..39e7eb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,11 @@ sudo: false matrix: include: + - php: 5.3 + - php: 5.4 - php: 5.5 - php: 5.6 - - php: 5.5 + - php: 5.3 env: deps=low - php: 5.6 env: deps=high @@ -31,6 +33,7 @@ before_install: - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi; install: + - if [[ "$TRAVIS_PHP_VERSION" != "5.3" ]] && [[ "$TRAVIS_PHP_VERSION" != "5.4" ]]; then composer require --no-update zendframework/zend-diactoros; fi; - if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi; - if [ "$deps" = "no" ]; then composer --prefer-source install; fi; - if [ "$deps" = "high" ]; then composer --prefer-source update; fi; diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 2fd9659..4fc6e4e 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -27,6 +27,10 @@ class DiactorosFactoryTest extends \PHPUnit_Framework_TestCase public function setup() { + if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { + $this->markTestSkipped('Zend Diactoros is not installed.'); + } + $this->factory = new DiactorosFactory(); $this->tmpDir = sys_get_temp_dir(); } diff --git a/composer.json b/composer.json index 43f25be..ae75a1e 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,7 @@ "symfony/http-foundation": "~2.3" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7", - "zendframework/zend-diactoros": "~1.0" + "symfony/phpunit-bridge": "~2.7" }, "suggest": { "zendframework/zend-diactoros": "To use the zend-diactoros factory" From f41f3e4d3b5dc372f1f5e7ae2e287106d0d45db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 11:39:37 +0200 Subject: [PATCH 30/37] New DiactorosFactory implementation --- Factory/DiactorosFactory.php | 39 ++++++++++++++------- Factory/HttpFoundationFactory.php | 8 +++-- HttpFoundationFactoryInterface.php | 11 ------ HttpMessageFactoryInterface.php | 11 ------ Tests/Factory/HttpFoundationFactoryTest.php | 14 ++++++-- composer.json | 2 +- 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 810d095..f6831ad 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Zend\Diactoros\Response as DiactorosResponse; +use Zend\Diactoros\ServerRequest; use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; use Zend\Diactoros\Stream as DiactorosStream; use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; @@ -40,22 +41,30 @@ public function __construct() */ public function createRequest(Request $symfonyRequest) { - $request = DiactorosRequestFactory::fromGlobals( - $symfonyRequest->server->all(), - $symfonyRequest->query->all(), - $symfonyRequest->request->all(), - $symfonyRequest->cookies->all(), - $this->getFiles($symfonyRequest->files->all()) - ); + $server = DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all()); + $headers = $symfonyRequest->headers->all(); try { - $stream = new DiactorosStream($symfonyRequest->getContent(true)); + $body = new DiactorosStream($symfonyRequest->getContent(true)); } catch (\LogicException $e) { - $stream = new DiactorosStream('php://temp', 'wb+'); - $stream->write($symfonyRequest->getContent()); + $body = new DiactorosStream('php://temp', 'wb+'); + $body->write($symfonyRequest->getContent()); } - $request = $request->withBody($stream); + $request = new ServerRequest( + $server, + DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all())), + DiactorosRequestFactory::marshalUriFromServer($server, $headers), + $symfonyRequest->getMethod(), + $body, + $headers + ); + + $request = $request + ->withCookieParams($symfonyRequest->cookies->all()) + ->withQueryParams($symfonyRequest->query->all()) + ->withParsedBody($symfonyRequest->request->all()) + ; foreach ($symfonyRequest->attributes->all() as $key => $value) { $request = $request->withAttribute($key, $value); @@ -87,9 +96,13 @@ private function getFiles(array $uploadedFiles) } /** - * {@inheritdoc} + * Creates a PSR-7 UploadedFile instance from a Symfony one. + * + * @param UploadedFile $symfonyUploadedFile + * + * @return UploadedFileInterface */ - public function createUploadedFile(UploadedFile $symfonyUploadedFile) + private function createUploadedFile(UploadedFile $symfonyUploadedFile) { return new DiactorosUploadedFile( $symfonyUploadedFile->getRealPath(), diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 8a1b981..8fa9c42 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -68,9 +68,13 @@ private function getFiles(array $uploadedFiles) } /** - * {@inheritdoc} + * Creates Symfony UploadedFile instance from PSR-7 ones. + * + * @param UploadedFileInterface $psrUploadedFile + * + * @return UploadedFile */ - public function createUploadedFile(UploadedFileInterface $psrUploadedFile) + private function createUploadedFile(UploadedFileInterface $psrUploadedFile) { $temporaryPath = $this->getTemporaryPath(); $psrUploadedFile->moveTo($temporaryPath); diff --git a/HttpFoundationFactoryInterface.php b/HttpFoundationFactoryInterface.php index acdd44d..32ec456 100644 --- a/HttpFoundationFactoryInterface.php +++ b/HttpFoundationFactoryInterface.php @@ -13,8 +13,6 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UploadedFileInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -34,15 +32,6 @@ interface HttpFoundationFactoryInterface */ public function createRequest(ServerRequestInterface $psrRequest); - /** - * Creates Symfony UploadedFile instance from PSR-7 ones. - * - * @param UploadedFileInterface $psrUploadedFile - * - * @return UploadedFile - */ - public function createUploadedFile(UploadedFileInterface $psrUploadedFile); - /** * Creates a Symfony Response instance from a PSR-7 one. * diff --git a/HttpMessageFactoryInterface.php b/HttpMessageFactoryInterface.php index ac0b497..1367c8c 100644 --- a/HttpMessageFactoryInterface.php +++ b/HttpMessageFactoryInterface.php @@ -13,8 +13,6 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UploadedFileInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -34,15 +32,6 @@ interface HttpMessageFactoryInterface */ public function createRequest(Request $symfonyRequest); - /** - * Creates a PSR-7 UploadedFile instance from a Symfony one. - * - * @param UploadedFile $symfonyUploadedFile - * - * @return UploadedFileInterface - */ - public function createUploadedFile(UploadedFile $symfonyUploadedFile); - /** * Creates a PSR-7 Response instance from a Symfony one. * diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 8a7192e..9e611e3 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; +use Psr\Http\Message\UploadedFileInterface; use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Response; use Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\ServerRequest; @@ -113,7 +114,7 @@ public function testCreateRequestWithObjectParsedBody() public function testCreateUploadedFile() { $uploadedFile = $this->createUploadedFile('An uploaded file.', UPLOAD_ERR_OK, 'myfile.txt', 'text/plain'); - $symfonyUploadedFile = $this->factory->createUploadedFile($uploadedFile); + $symfonyUploadedFile = $this->callCreateUploadedFile($uploadedFile); $uniqid = uniqid(); $symfonyUploadedFile->move($this->tmpDir, $uniqid); @@ -133,7 +134,7 @@ public function testCreateUploadedFile() public function testCreateUploadedFileWithError() { $uploadedFile = $this->createUploadedFile('Error.', UPLOAD_ERR_CANT_WRITE, 'e', 'text/plain'); - $symfonyUploadedFile = $this->factory->createUploadedFile($uploadedFile); + $symfonyUploadedFile = $this->callCreateUploadedFile($uploadedFile); $this->assertEquals(UPLOAD_ERR_CANT_WRITE, $symfonyUploadedFile->getError()); @@ -148,6 +149,15 @@ private function createUploadedFile($content, $error, $clientFileName, $clientMe return new UploadedFile($filePath, filesize($filePath), $error, $clientFileName, $clientMediaType); } + private function callCreateUploadedFile(UploadedFileInterface $uploadedFile) + { + $reflection = new \ReflectionClass($this->factory); + $createUploadedFile = $reflection->getMethod('createUploadedFile'); + $createUploadedFile->setAccessible(true); + + return $createUploadedFile->invokeArgs($this->factory, array($uploadedFile)); + } + public function testCreateResponse() { $response = new Response( diff --git a/composer.json b/composer.json index ae75a1e..6f87655 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "symfony/phpunit-bridge": "~2.7" }, "suggest": { - "zendframework/zend-diactoros": "To use the zend-diactoros factory" + "zendframework/zend-diactoros": "To use the Zend Diactoros factory" }, "autoload": { "psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" } From 9c6f18095e9624018f6c77167ee56201b6b19c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 14:50:07 +0200 Subject: [PATCH 31/37] Added cookies support --- Factory/DiactorosFactory.php | 13 +++- Factory/HttpFoundationFactory.php | 78 +++++++++++++++++++++ Tests/Factory/DiactorosFactoryTest.php | 4 ++ Tests/Factory/HttpFoundationFactoryTest.php | 29 +++++++- 4 files changed, 122 insertions(+), 2 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index f6831ad..0ef7126 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -132,10 +132,21 @@ public function createResponse(Response $symfonyResponse) $stream->write($symfonyResponse->getContent()); } + $headers = $symfonyResponse->headers->all(); + + $cookies = $symfonyResponse->headers->getCookies(); + if (!empty($cookies)) { + $headers['Set-Cookie'] = array(); + + foreach ($cookies as $coookie) { + $headers['Set-Cookie'][] = $coookie->__toString(); + } + } + $response = new DiactorosResponse( $stream, $symfonyResponse->getStatusCode(), - $symfonyResponse->headers->all() + $headers ); $protocolVersion = $symfonyResponse->getProtocolVersion(); diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 8fa9c42..42537af 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -15,6 +15,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UploadedFileInterface; use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -113,6 +114,83 @@ public function createResponse(ResponseInterface $psrResponse) ); $response->setProtocolVersion($psrResponse->getProtocolVersion()); + foreach ($psrResponse->getHeader('Set-Cookie') as $cookie) { + $response->headers->setCookie($this->createCookie($cookie)); + } + return $response; } + + /** + * Creates a Cookie instance from a cookie string. + * + * Some snippets have been taken from the Guzzle project: https://github.com/guzzle/guzzle/blob/5.3/src/Cookie/SetCookie.php#L34 + * + * @param string $cookie + * + * @return Cookie + * + * @BadMethodCallException + */ + private function createCookie($cookie) + { + foreach (explode(';', $cookie) as $part) { + $part = trim($part); + + $data = explode('=', $part, 2); + $name = $data[0]; + $value = isset($data[1]) ? trim($data[1], " \n\r\t\0\x0B\"") : null; + + if (!isset($cookieName)) { + $cookieName = $name; + $cookieValue = $value; + + continue; + } + + if ('expires' === strtolower($name) && null !== $value) { + $cookieExpire = new \DateTime($value); + + continue; + } + + if ('path' === strtolower($name) && null !== $value) { + $cookiePath = $value; + + continue; + } + + if ('domain' === strtolower($name) && null !== $value) { + $cookieDomain = $value; + + continue; + } + + if ('secure' === strtolower($name)) { + $cookieSecure = true; + + continue; + } + + if ('httponly' === strtolower($name)) { + $cookieHttpOnly = true; + + continue; + } + } + + if (!isset($cookieName)) { + throw new \BadMethodCallException('The value of the Set-Cookie header is malformed.'); + } + + return new Cookie( + $cookieName, + $cookieValue, + isset($cookieExpire) ? $cookieExpire : 0, + isset($cookiePath) ? $cookiePath : '/', + isset($cookieDomain) ? $cookieDomain : null, + isset($cookieSecure), + isset($cookieHttpOnly) + ); + } } diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index 4fc6e4e..e5f2149 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -123,11 +124,14 @@ public function testCreateResponse() 202, array('X-Symfony' => array('2.8')) ); + $response->headers->setCookie(new Cookie('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT'))); $psrResponse = $this->factory->createResponse($response); $this->assertEquals('Response content.', $psrResponse->getBody()->__toString()); $this->assertEquals(202, $psrResponse->getStatusCode()); $this->assertEquals(array('2.8'), $psrResponse->getHeader('X-Symfony')); + var_dump($psrResponse->getHeader('Set-Cookie')[0]); + $this->assertEquals(array('city=Lille; expires=Wed, 13-Jan-2021 22:23:01 GMT; path=/; httponly'), $psrResponse->getHeader('Set-Cookie')); } public function testCreateResponseFromStreamed() diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 9e611e3..f24cea6 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -163,7 +163,13 @@ public function testCreateResponse() $response = new Response( '1.0', array( - 'X-Symfony' => '2.8', + 'X-Symfony' => array('2.8'), + 'Set-Cookie' => array( + 'theme=light', + 'test', + 'ABC=AeD; Domain=dunglas.fr; Path=/kevin; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly', + + ), ), new Stream('The response body'), 200 @@ -173,6 +179,27 @@ public function testCreateResponse() $this->assertEquals('1.0', $symfonyResponse->getProtocolVersion()); $this->assertEquals('2.8', $symfonyResponse->headers->get('X-Symfony')); + + $cookies = $symfonyResponse->headers->getCookies(); + $this->assertEquals('theme', $cookies[0]->getName()); + $this->assertEquals('light', $cookies[0]->getValue()); + $this->assertEquals(0, $cookies[0]->getExpiresTime()); + $this->assertEquals(null, $cookies[0]->getDomain()); + $this->assertEquals('/', $cookies[0]->getPath()); + $this->assertEquals(false, $cookies[0]->isSecure()); + $this->assertEquals(false, $cookies[0]->isHttpOnly()); + + $this->assertEquals('test', $cookies[1]->getName()); + $this->assertEquals(null, $cookies[1]->getValue()); + + $this->assertEquals('ABC', $cookies[2]->getName()); + $this->assertEquals('AeD', $cookies[2]->getValue()); + $this->assertEquals(strtotime('Wed, 13 Jan 2021 22:23:01 GMT'), $cookies[2]->getExpiresTime()); + $this->assertEquals('dunglas.fr', $cookies[2]->getDomain()); + $this->assertEquals('/kevin', $cookies[2]->getPath()); + $this->assertEquals(true, $cookies[2]->isSecure()); + $this->assertEquals(true, $cookies[2]->isHttpOnly()); + $this->assertEquals('The response body', $symfonyResponse->getContent()); $this->assertEquals(200, $symfonyResponse->getStatusCode()); } From 7d8bdc875e1e9f682ef60bbd3ce6dd0058443e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 14:51:27 +0200 Subject: [PATCH 32/37] PHPUnit optimizations --- Tests/Factory/HttpFoundationFactoryTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index f24cea6..3fe3095 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -184,21 +184,21 @@ public function testCreateResponse() $this->assertEquals('theme', $cookies[0]->getName()); $this->assertEquals('light', $cookies[0]->getValue()); $this->assertEquals(0, $cookies[0]->getExpiresTime()); - $this->assertEquals(null, $cookies[0]->getDomain()); + $this->assertNull($cookies[0]->getDomain()); $this->assertEquals('/', $cookies[0]->getPath()); - $this->assertEquals(false, $cookies[0]->isSecure()); - $this->assertEquals(false, $cookies[0]->isHttpOnly()); + $this->assertFalse($cookies[0]->isSecure()); + $this->assertFalse($cookies[0]->isHttpOnly()); $this->assertEquals('test', $cookies[1]->getName()); - $this->assertEquals(null, $cookies[1]->getValue()); + $this->assertNull($cookies[1]->getValue()); $this->assertEquals('ABC', $cookies[2]->getName()); $this->assertEquals('AeD', $cookies[2]->getValue()); $this->assertEquals(strtotime('Wed, 13 Jan 2021 22:23:01 GMT'), $cookies[2]->getExpiresTime()); $this->assertEquals('dunglas.fr', $cookies[2]->getDomain()); $this->assertEquals('/kevin', $cookies[2]->getPath()); - $this->assertEquals(true, $cookies[2]->isSecure()); - $this->assertEquals(true, $cookies[2]->isHttpOnly()); + $this->assertTrue($cookies[2]->isSecure()); + $this->assertTrue($cookies[2]->isHttpOnly()); $this->assertEquals('The response body', $symfonyResponse->getContent()); $this->assertEquals(200, $symfonyResponse->getStatusCode()); From eacce8fb754437e2eadd57a1048ab0194fc35109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 14:53:25 +0200 Subject: [PATCH 33/37] Remove crap. --- Factory/HttpFoundationFactory.php | 4 ++-- Tests/Factory/DiactorosFactoryTest.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 42537af..6062b5d 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -33,11 +33,11 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface public function createRequest(ServerRequestInterface $psrRequest) { $parsedBody = $psrRequest->getParsedBody(); - $request = is_array($parsedBody) ? $parsedBody : array(); + $parsedBody = is_array($parsedBody) ? $parsedBody : array(); return new Request( $psrRequest->getQueryParams(), - $request, + $parsedBody, $psrRequest->getAttributes(), $psrRequest->getCookieParams(), $this->getFiles($psrRequest->getUploadedFiles()), diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index e5f2149..cffab52 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -130,7 +130,6 @@ public function testCreateResponse() $this->assertEquals('Response content.', $psrResponse->getBody()->__toString()); $this->assertEquals(202, $psrResponse->getStatusCode()); $this->assertEquals(array('2.8'), $psrResponse->getHeader('X-Symfony')); - var_dump($psrResponse->getHeader('Set-Cookie')[0]); $this->assertEquals(array('city=Lille; expires=Wed, 13-Jan-2021 22:23:01 GMT; path=/; httponly'), $psrResponse->getHeader('Set-Cookie')); } From 7012db5c596703171477c690c9b369a8f0370a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 15:04:01 +0200 Subject: [PATCH 34/37] Enhanced headers support --- Factory/HttpFoundationFactory.php | 5 ++++- Tests/Factory/HttpFoundationFactoryTest.php | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 6062b5d..9926fd0 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -35,7 +35,7 @@ public function createRequest(ServerRequestInterface $psrRequest) $parsedBody = $psrRequest->getParsedBody(); $parsedBody = is_array($parsedBody) ? $parsedBody : array(); - return new Request( + $request = new Request( $psrRequest->getQueryParams(), $parsedBody, $psrRequest->getAttributes(), @@ -44,6 +44,9 @@ public function createRequest(ServerRequestInterface $psrRequest) $psrRequest->getServerParams(), $psrRequest->getBody()->__toString() ); + $request->headers->replace($psrRequest->getHeaders()); + + return $request; } /** diff --git a/Tests/Factory/HttpFoundationFactoryTest.php b/Tests/Factory/HttpFoundationFactoryTest.php index 3fe3095..412e287 100644 --- a/Tests/Factory/HttpFoundationFactoryTest.php +++ b/Tests/Factory/HttpFoundationFactoryTest.php @@ -37,7 +37,10 @@ public function testCreateRequest() $stdClass = new \stdClass(); $serverRequest = new ServerRequest( '1.1', - array(), + array( + 'X-Dunglas-API-Platform' => '1.0', + 'X-data' => array('a', 'b'), + ), new Stream('The body'), '/about/kevin', 'GET', @@ -69,6 +72,8 @@ public function testCreateRequest() $this->assertEquals('Lille', $symfonyRequest->cookies->get('city')); $this->assertEquals('France', $symfonyRequest->server->get('country')); $this->assertEquals('The body', $symfonyRequest->getContent()); + $this->assertEquals('1.0', $symfonyRequest->headers->get('X-Dunglas-API-Platform')); + $this->assertEquals(array('a', 'b'), $symfonyRequest->headers->get('X-data', null, false)); } public function testCreateRequestWithNullParsedBody() From b887c36e349fdb827c56dd822e3cee09d037b419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 16:08:15 +0200 Subject: [PATCH 35/37] CS fixes --- Factory/DiactorosFactory.php | 4 ++-- Factory/HttpFoundationFactory.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 0ef7126..1f4fbae 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -138,8 +138,8 @@ public function createResponse(Response $symfonyResponse) if (!empty($cookies)) { $headers['Set-Cookie'] = array(); - foreach ($cookies as $coookie) { - $headers['Set-Cookie'][] = $coookie->__toString(); + foreach ($cookies as $cookie) { + $headers['Set-Cookie'][] = $cookie->__toString(); } } diff --git a/Factory/HttpFoundationFactory.php b/Factory/HttpFoundationFactory.php index 9926fd0..2c356fd 100644 --- a/Factory/HttpFoundationFactory.php +++ b/Factory/HttpFoundationFactory.php @@ -133,7 +133,7 @@ public function createResponse(ResponseInterface $psrResponse) * * @return Cookie * - * @BadMethodCallException + * @throws \InvalidArgumentException */ private function createCookie($cookie) { @@ -183,7 +183,7 @@ private function createCookie($cookie) } if (!isset($cookieName)) { - throw new \BadMethodCallException('The value of the Set-Cookie header is malformed.'); + throw new \InvalidArgumentException('The value of the Set-Cookie header is malformed.'); } return new Cookie( From ca2ea3bfb02a979dc50c78bd66e5fe8dcb8c039d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 May 2015 23:53:51 +0200 Subject: [PATCH 36/37] BinaryFileResponse support --- Factory/DiactorosFactory.php | 27 +++++++++++++++----------- Tests/Factory/DiactorosFactoryTest.php | 14 +++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Factory/DiactorosFactory.php b/Factory/DiactorosFactory.php index 1f4fbae..31726f1 100644 --- a/Factory/DiactorosFactory.php +++ b/Factory/DiactorosFactory.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Factory; use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -54,7 +55,7 @@ public function createRequest(Request $symfonyRequest) $request = new ServerRequest( $server, DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all())), - DiactorosRequestFactory::marshalUriFromServer($server, $headers), + $symfonyRequest->getUri(), $symfonyRequest->getMethod(), $body, $headers @@ -118,18 +119,22 @@ private function createUploadedFile(UploadedFile $symfonyUploadedFile) */ public function createResponse(Response $symfonyResponse) { - $stream = new DiactorosStream('php://temp', 'wb+'); - if ($symfonyResponse instanceof StreamedResponse) { - ob_start(function ($buffer) use ($stream) { - $stream->write($buffer); + if ($symfonyResponse instanceof BinaryFileResponse) { + $stream = new DiactorosStream($symfonyResponse->getFile()->getPathname(), 'r'); + } else { + $stream = new DiactorosStream('php://temp', 'wb+'); + if ($symfonyResponse instanceof StreamedResponse) { + ob_start(function ($buffer) use ($stream) { + $stream->write($buffer); - return false; - }); + return false; + }); - $symfonyResponse->sendContent(); - ob_end_clean(); - } else { - $stream->write($symfonyResponse->getContent()); + $symfonyResponse->sendContent(); + ob_end_clean(); + } else { + $stream->write($symfonyResponse->getContent()); + } } $headers = $symfonyResponse->headers->all(); diff --git a/Tests/Factory/DiactorosFactoryTest.php b/Tests/Factory/DiactorosFactoryTest.php index cffab52..a4c32bd 100644 --- a/Tests/Factory/DiactorosFactoryTest.php +++ b/Tests/Factory/DiactorosFactoryTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\PsrHttpMessage\Tests\Factory; use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; +use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; @@ -65,6 +66,7 @@ public function testCreateRequest() ), array( 'REQUEST_METHOD' => 'POST', + 'HTTP_HOST' => 'dunglas.fr', 'HTTP_X_SYMFONY' => '2.8', ), 'Content' @@ -147,4 +149,16 @@ public function testCreateResponseFromStreamed() $this->assertEquals("Line 1\nLine 2\n", $psrResponse->getBody()->__toString()); } + + public function testCreateResponseFromBinaryFile() + { + $path = tempnam($this->tmpDir, uniqid()); + file_put_contents($path, 'Binary'); + + $response = new BinaryFileResponse($path); + + $psrResponse = $this->factory->createResponse($response); + + $this->assertEquals('Binary', $psrResponse->getBody()->__toString()); + } } From 577e6330860082a1d9393e8938c049bf48a4fe0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 28 May 2015 12:24:48 +0200 Subject: [PATCH 37/37] Support Symfony 3.0 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6f87655..2086398 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,10 @@ "require": { "php": ">=5.3.3", "psr/http-message": "~1.0", - "symfony/http-foundation": "~2.3" + "symfony/http-foundation": "~2.3|~3.0" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { "zendframework/zend-diactoros": "To use the Zend Diactoros factory" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy