DiactorosFactory.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bridge\PsrHttpMessage\Factory;
  11. @trigger_error(sprintf('The "%s" class is deprecated since symfony/psr-http-message-bridge 1.2, use PsrHttpFactory instead.', DiactorosFactory::class), E_USER_DEPRECATED);
  12. use Psr\Http\Message\UploadedFileInterface;
  13. use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
  14. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  15. use Symfony\Component\HttpFoundation\File\UploadedFile;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpFoundation\StreamedResponse;
  19. use Zend\Diactoros\Response as DiactorosResponse;
  20. use Zend\Diactoros\ServerRequest;
  21. use Zend\Diactoros\ServerRequestFactory as DiactorosRequestFactory;
  22. use Zend\Diactoros\Stream as DiactorosStream;
  23. use Zend\Diactoros\UploadedFile as DiactorosUploadedFile;
  24. /**
  25. * Builds Psr\HttpMessage instances using the Zend Diactoros implementation.
  26. *
  27. * @author Kévin Dunglas <dunglas@gmail.com>
  28. *
  29. * @deprecated since symfony/psr-http-message-bridge 1.2, use PsrHttpFactory instead
  30. */
  31. class DiactorosFactory implements HttpMessageFactoryInterface
  32. {
  33. public function __construct()
  34. {
  35. if (!class_exists('Zend\Diactoros\ServerRequestFactory')) {
  36. throw new \RuntimeException('Zend Diactoros must be installed to use the DiactorosFactory.');
  37. }
  38. }
  39. /**
  40. * {@inheritdoc}
  41. */
  42. public function createRequest(Request $symfonyRequest)
  43. {
  44. $server = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeServer')
  45. ? DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all())
  46. : \Zend\Diactoros\normalizeServer($symfonyRequest->server->all());
  47. $headers = $symfonyRequest->headers->all();
  48. $body = new DiactorosStream($symfonyRequest->getContent(true));
  49. $files = method_exists('Zend\Diactoros\ServerRequestFactory', 'normalizeFiles')
  50. ? DiactorosRequestFactory::normalizeFiles($this->getFiles($symfonyRequest->files->all()))
  51. : \Zend\Diactoros\normalizeUploadedFiles($this->getFiles($symfonyRequest->files->all()));
  52. $request = new ServerRequest(
  53. $server,
  54. $files,
  55. $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getRequestUri(),
  56. $symfonyRequest->getMethod(),
  57. $body,
  58. $headers
  59. );
  60. $request = $request
  61. ->withCookieParams($symfonyRequest->cookies->all())
  62. ->withQueryParams($symfonyRequest->query->all())
  63. ->withParsedBody($symfonyRequest->request->all())
  64. ->withRequestTarget($symfonyRequest->getRequestUri())
  65. ;
  66. foreach ($symfonyRequest->attributes->all() as $key => $value) {
  67. $request = $request->withAttribute($key, $value);
  68. }
  69. return $request;
  70. }
  71. /**
  72. * Converts Symfony uploaded files array to the PSR one.
  73. *
  74. * @param array $uploadedFiles
  75. *
  76. * @return array
  77. */
  78. private function getFiles(array $uploadedFiles)
  79. {
  80. $files = [];
  81. foreach ($uploadedFiles as $key => $value) {
  82. if (null === $value) {
  83. $files[$key] = new DiactorosUploadedFile(null, 0, UPLOAD_ERR_NO_FILE, null, null);
  84. continue;
  85. }
  86. if ($value instanceof UploadedFile) {
  87. $files[$key] = $this->createUploadedFile($value);
  88. } else {
  89. $files[$key] = $this->getFiles($value);
  90. }
  91. }
  92. return $files;
  93. }
  94. /**
  95. * Creates a PSR-7 UploadedFile instance from a Symfony one.
  96. *
  97. * @param UploadedFile $symfonyUploadedFile
  98. *
  99. * @return UploadedFileInterface
  100. */
  101. private function createUploadedFile(UploadedFile $symfonyUploadedFile)
  102. {
  103. return new DiactorosUploadedFile(
  104. $symfonyUploadedFile->getRealPath(),
  105. (int) $symfonyUploadedFile->getSize(),
  106. $symfonyUploadedFile->getError(),
  107. $symfonyUploadedFile->getClientOriginalName(),
  108. $symfonyUploadedFile->getClientMimeType()
  109. );
  110. }
  111. /**
  112. * {@inheritdoc}
  113. */
  114. public function createResponse(Response $symfonyResponse)
  115. {
  116. if ($symfonyResponse instanceof BinaryFileResponse) {
  117. $stream = new DiactorosStream($symfonyResponse->getFile()->getPathname(), 'r');
  118. } else {
  119. $stream = new DiactorosStream('php://temp', 'wb+');
  120. if ($symfonyResponse instanceof StreamedResponse) {
  121. ob_start(function ($buffer) use ($stream) {
  122. $stream->write($buffer);
  123. return '';
  124. });
  125. $symfonyResponse->sendContent();
  126. ob_end_clean();
  127. } else {
  128. $stream->write($symfonyResponse->getContent());
  129. }
  130. }
  131. $headers = $symfonyResponse->headers->all();
  132. if (!isset($headers['Set-Cookie']) && !isset($headers['set-cookie'])) {
  133. $cookies = $symfonyResponse->headers->getCookies();
  134. if (!empty($cookies)) {
  135. $headers['Set-Cookie'] = [];
  136. foreach ($cookies as $cookie) {
  137. $headers['Set-Cookie'][] = $cookie->__toString();
  138. }
  139. }
  140. }
  141. $response = new DiactorosResponse(
  142. $stream,
  143. $symfonyResponse->getStatusCode(),
  144. $headers
  145. );
  146. $protocolVersion = $symfonyResponse->getProtocolVersion();
  147. if ('1.1' !== $protocolVersion) {
  148. $response = $response->withProtocolVersion($protocolVersion);
  149. }
  150. return $response;
  151. }
  152. }