RequestTransformer.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.3.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Http;
  16. use Cake\Utility\Hash;
  17. use Psr\Http\Message\ServerRequestInterface as PsrRequest;
  18. /**
  19. * Translate and transform from PSR7 requests into CakePHP requests.
  20. *
  21. * This is an important step for maintaining backwards compatibility
  22. * with existing CakePHP applications, which depend on the CakePHP request object.
  23. *
  24. * There is no reverse transform as the 'application' cannot return a mutated
  25. * request object.
  26. *
  27. * @internal
  28. * @deprecated 3.4.0 No longer used. Will be removed in 4.0.0
  29. */
  30. class RequestTransformer
  31. {
  32. /**
  33. * Transform a PSR7 request into a CakePHP one.
  34. *
  35. * @param \Psr\Http\Message\ServerRequestInterface $request The PSR7 request.
  36. * @return \Cake\Http\ServerRequest The transformed request.
  37. */
  38. public static function toCake(PsrRequest $request)
  39. {
  40. $post = $request->getParsedBody();
  41. $headers = [];
  42. foreach ($request->getHeaders() as $k => $value) {
  43. $name = sprintf('HTTP_%s', strtoupper(str_replace('-', '_', $k)));
  44. $headers[$name] = implode(',', $value);
  45. }
  46. $server = $headers + $request->getServerParams();
  47. $files = static::getFiles($request);
  48. if (!empty($files)) {
  49. $post = Hash::merge($post, $files);
  50. }
  51. $input = $request->getBody()->getContents();
  52. $input = $input === '' ? null : $input;
  53. return new ServerRequest([
  54. 'query' => $request->getQueryParams(),
  55. 'post' => $post,
  56. 'cookies' => $request->getCookieParams(),
  57. 'environment' => $server,
  58. 'params' => static::getParams($request),
  59. 'url' => $request->getUri()->getPath(),
  60. 'base' => $request->getAttribute('base', ''),
  61. 'webroot' => $request->getAttribute('webroot', '/'),
  62. 'session' => $request->getAttribute('session', null),
  63. 'input' => $input,
  64. ]);
  65. }
  66. /**
  67. * Extract the routing parameters out of the request object.
  68. *
  69. * @param \Psr\Http\Message\ServerRequestInterface $request The request to extract params from.
  70. * @return array The routing parameters.
  71. */
  72. protected static function getParams(PsrRequest $request)
  73. {
  74. $params = (array)$request->getAttribute('params', []);
  75. $params += [
  76. 'plugin' => null,
  77. 'controller' => null,
  78. 'action' => null,
  79. '_ext' => null,
  80. 'pass' => []
  81. ];
  82. return $params;
  83. }
  84. /**
  85. * Extract the uploaded files out of the request object.
  86. *
  87. * CakePHP expects to get arrays of file information and
  88. * not the parsed objects that PSR7 requests contain. Downsample the data here.
  89. *
  90. * @param \Psr\Http\Message\ServerRequestInterface $request The request to extract files from.
  91. * @return array The routing parameters.
  92. */
  93. protected static function getFiles($request)
  94. {
  95. return static::convertFiles([], $request->getUploadedFiles());
  96. }
  97. /**
  98. * Convert a nested array of files to arrays.
  99. *
  100. * @param array $data The data to add files to.
  101. * @param array $files The file objects to convert.
  102. * @param string $path The current array path.
  103. * @return array Converted file data
  104. */
  105. protected static function convertFiles($data, $files, $path = '')
  106. {
  107. foreach ($files as $key => $file) {
  108. $newPath = $path;
  109. if ($newPath === '') {
  110. $newPath = $key;
  111. }
  112. if ($newPath !== $key) {
  113. $newPath .= '.' . $key;
  114. }
  115. if (is_array($file)) {
  116. $data = static::convertFiles($data, $file, $newPath);
  117. } else {
  118. $data = Hash::insert($data, $newPath, static::convertFile($file));
  119. }
  120. }
  121. return $data;
  122. }
  123. /**
  124. * Convert a single file back into an array.
  125. *
  126. * @param \Psr\Http\Message\UploadedFileInterface $file The file to convert.
  127. * @return array
  128. */
  129. protected static function convertFile($file)
  130. {
  131. $error = $file->getError();
  132. $tmpName = '';
  133. if ($error === UPLOAD_ERR_OK) {
  134. $tmpName = $file->getStream()->getMetadata('uri');
  135. }
  136. return [
  137. 'name' => $file->getClientFilename(),
  138. 'type' => $file->getClientMediaType(),
  139. 'tmp_name' => $tmpName,
  140. 'error' => $error,
  141. 'size' => $file->getSize(),
  142. ];
  143. }
  144. }