Skip to content

Commit

Permalink
feature #1 Initial support (dunglas)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 2.8-dev branch (closes #1).

Discussion
----------

Initial support

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | symfony/symfony-docs#5331

- [x] Composer dependencies
- [x] Interfaces
- [x] Stub
- [x] HttpFoundationFactory implementation
- [x] DiactorosFactory implementation
- [x] StreamedResponse

Commits
-------

ca41146 Initial support
  • Loading branch information
fabpot committed May 29, 2015
2 parents 01b110b + ca41146 commit 3f8977e
Show file tree
Hide file tree
Showing 15 changed files with 1,313 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml
43 changes: 43 additions & 0 deletions .travis.yml
@@ -0,0 +1,43 @@
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 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 [[ "$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;
- if [ "$deps" = "low" ]; then composer --prefer-source --prefer-lowest --prefer-stable update; fi;

script:
- phpunit
164 changes: 164 additions & 0 deletions Factory/DiactorosFactory.php
@@ -0,0 +1,164 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\HttpMessageFactoryInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
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\ServerRequest;
use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory;
use Zend\Diactoros\Stream as DiactorosStream;
use Zend\Diactoros\UploadedFile as DiactorosUploadedFile;

/**
* Builds Psr\HttpMessage instances using the Zend Diactoros implementation.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class DiactorosFactory implements HttpMessageFactoryInterface
{
public function __construct()
{
if (!class_exists('Zend\Diactoros\ServerRequestFactory')) {
throw new \RuntimeException('Zend Diactoros must be installed to use the DiactorosFactory.');
}
}

/**
* {@inheritdoc}
*/
public function createRequest(Request $symfonyRequest)
{
$server = DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all());
$headers = $symfonyRequest->headers->all();

try {
$body = new DiactorosStream($symfonyRequest->getContent(true));
} catch (\LogicException $e) {
$body = new DiactorosStream('php://temp', 'wb+');
$body->write($symfonyRequest->getContent());
}

$request = new ServerRequest(
$server,
DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all())),
$symfonyRequest->getUri(),
$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);
}

return $request;
}

/**
* 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;
}

/**
* Creates a PSR-7 UploadedFile instance from a Symfony one.
*
* @param UploadedFile $symfonyUploadedFile
*
* @return UploadedFileInterface
*/
private function createUploadedFile(UploadedFile $symfonyUploadedFile)
{
return new DiactorosUploadedFile(
$symfonyUploadedFile->getRealPath(),
$symfonyUploadedFile->getSize(),
$symfonyUploadedFile->getError(),
$symfonyUploadedFile->getClientOriginalName(),
$symfonyUploadedFile->getClientMimeType()
);
}

/**
* {@inheritdoc}
*/
public function createResponse(Response $symfonyResponse)
{
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;
});

$symfonyResponse->sendContent();
ob_end_clean();
} else {
$stream->write($symfonyResponse->getContent());
}
}

$headers = $symfonyResponse->headers->all();

$cookies = $symfonyResponse->headers->getCookies();
if (!empty($cookies)) {
$headers['Set-Cookie'] = array();

foreach ($cookies as $cookie) {
$headers['Set-Cookie'][] = $cookie->__toString();
}
}

$response = new DiactorosResponse(
$stream,
$symfonyResponse->getStatusCode(),
$headers
);

$protocolVersion = $symfonyResponse->getProtocolVersion();
if ('1.1' !== $protocolVersion) {
$response = $response->withProtocolVersion($protocolVersion);
}

return $response;
}
}

0 comments on commit 3f8977e

Please sign in to comment.