Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Bridge\PsrHttpMessage\Factory; Chris@0: Chris@17: use Psr\Http\Message\UploadedFileInterface; Chris@0: use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; Chris@0: use Symfony\Component\HttpFoundation\BinaryFileResponse; Chris@0: use Symfony\Component\HttpFoundation\File\UploadedFile; Chris@0: use Symfony\Component\HttpFoundation\Request; Chris@0: use Symfony\Component\HttpFoundation\Response; Chris@0: use Symfony\Component\HttpFoundation\StreamedResponse; Chris@0: use Zend\Diactoros\Response as DiactorosResponse; Chris@0: use Zend\Diactoros\ServerRequest; Chris@0: use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory; Chris@0: use Zend\Diactoros\Stream as DiactorosStream; Chris@0: use Zend\Diactoros\UploadedFile as DiactorosUploadedFile; Chris@0: Chris@0: /** Chris@0: * Builds Psr\HttpMessage instances using the Zend Diactoros implementation. Chris@0: * Chris@0: * @author Kévin Dunglas Chris@0: */ Chris@0: class DiactorosFactory implements HttpMessageFactoryInterface Chris@0: { Chris@0: public function __construct() Chris@0: { Chris@0: if (!class_exists('Zend\Diactoros\ServerRequestFactory')) { Chris@0: throw new \RuntimeException('Zend Diactoros must be installed to use the DiactorosFactory.'); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function createRequest(Request $symfonyRequest) Chris@0: { Chris@18: $server = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeServer') Chris@18: ? DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all()) Chris@18: : \Zend\Diactoros\normalizeServer($symfonyRequest->server->all()); Chris@0: $headers = $symfonyRequest->headers->all(); Chris@0: Chris@0: if (PHP_VERSION_ID < 50600) { Chris@0: $body = new DiactorosStream('php://temp', 'wb+'); Chris@0: $body->write($symfonyRequest->getContent()); Chris@0: } else { Chris@0: $body = new DiactorosStream($symfonyRequest->getContent(true)); Chris@0: } Chris@0: Chris@18: $files = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeFiles') Chris@18: ? DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all())) Chris@18: : \Zend\Diactoros\normalizeUploadedFiles($this->getFiles($symfonyRequest->files->all())); Chris@18: Chris@0: $request = new ServerRequest( Chris@0: $server, Chris@18: $files, Chris@12: $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getRequestUri(), Chris@0: $symfonyRequest->getMethod(), Chris@0: $body, Chris@0: $headers Chris@0: ); Chris@0: Chris@0: $request = $request Chris@0: ->withCookieParams($symfonyRequest->cookies->all()) Chris@0: ->withQueryParams($symfonyRequest->query->all()) Chris@0: ->withParsedBody($symfonyRequest->request->all()) Chris@12: ->withRequestTarget($symfonyRequest->getRequestUri()) Chris@0: ; Chris@0: Chris@0: foreach ($symfonyRequest->attributes->all() as $key => $value) { Chris@0: $request = $request->withAttribute($key, $value); Chris@0: } Chris@0: Chris@0: return $request; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Converts Symfony uploaded files array to the PSR one. Chris@0: * Chris@0: * @param array $uploadedFiles Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: private function getFiles(array $uploadedFiles) Chris@0: { Chris@0: $files = array(); Chris@0: Chris@0: foreach ($uploadedFiles as $key => $value) { Chris@0: if (null === $value) { Chris@0: $files[$key] = new DiactorosUploadedFile(null, 0, UPLOAD_ERR_NO_FILE, null, null); Chris@0: continue; Chris@0: } Chris@0: if ($value instanceof UploadedFile) { Chris@0: $files[$key] = $this->createUploadedFile($value); Chris@0: } else { Chris@0: $files[$key] = $this->getFiles($value); Chris@0: } Chris@0: } Chris@0: Chris@0: return $files; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates a PSR-7 UploadedFile instance from a Symfony one. Chris@0: * Chris@0: * @param UploadedFile $symfonyUploadedFile Chris@0: * Chris@0: * @return UploadedFileInterface Chris@0: */ Chris@0: private function createUploadedFile(UploadedFile $symfonyUploadedFile) Chris@0: { Chris@0: return new DiactorosUploadedFile( Chris@0: $symfonyUploadedFile->getRealPath(), Chris@17: (int) $symfonyUploadedFile->getSize(), Chris@0: $symfonyUploadedFile->getError(), Chris@0: $symfonyUploadedFile->getClientOriginalName(), Chris@0: $symfonyUploadedFile->getClientMimeType() Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function createResponse(Response $symfonyResponse) Chris@0: { Chris@0: if ($symfonyResponse instanceof BinaryFileResponse) { Chris@0: $stream = new DiactorosStream($symfonyResponse->getFile()->getPathname(), 'r'); Chris@0: } else { Chris@0: $stream = new DiactorosStream('php://temp', 'wb+'); Chris@0: if ($symfonyResponse instanceof StreamedResponse) { Chris@0: ob_start(function ($buffer) use ($stream) { Chris@0: $stream->write($buffer); Chris@0: Chris@17: return ''; Chris@0: }); Chris@0: Chris@0: $symfonyResponse->sendContent(); Chris@0: ob_end_clean(); Chris@0: } else { Chris@0: $stream->write($symfonyResponse->getContent()); Chris@0: } Chris@0: } Chris@0: Chris@0: $headers = $symfonyResponse->headers->all(); Chris@18: if (!isset($headers['Set-Cookie']) && !isset($headers['set-cookie'])) { Chris@17: $cookies = $symfonyResponse->headers->getCookies(); Chris@17: if (!empty($cookies)) { Chris@17: $headers['Set-Cookie'] = array(); Chris@17: foreach ($cookies as $cookie) { Chris@17: $headers['Set-Cookie'][] = $cookie->__toString(); Chris@17: } Chris@0: } Chris@0: } Chris@0: Chris@0: $response = new DiactorosResponse( Chris@0: $stream, Chris@0: $symfonyResponse->getStatusCode(), Chris@0: $headers Chris@0: ); Chris@0: Chris@0: $protocolVersion = $symfonyResponse->getProtocolVersion(); Chris@0: if ('1.1' !== $protocolVersion) { Chris@0: $response = $response->withProtocolVersion($protocolVersion); Chris@0: } Chris@0: Chris@0: return $response; Chris@0: } Chris@0: }