RequestServiceProvider.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. /**
  3. * @package Grav\Common\Service
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Service;
  9. use Grav\Common\Uri;
  10. use JsonException;
  11. use Nyholm\Psr7\Factory\Psr17Factory;
  12. use Nyholm\Psr7Server\ServerRequestCreator;
  13. use Pimple\Container;
  14. use Pimple\ServiceProviderInterface;
  15. use function explode;
  16. use function fopen;
  17. use function function_exists;
  18. use function in_array;
  19. use function is_array;
  20. use function strtolower;
  21. use function trim;
  22. /**
  23. * Class RequestServiceProvider
  24. * @package Grav\Common\Service
  25. */
  26. class RequestServiceProvider implements ServiceProviderInterface
  27. {
  28. /**
  29. * @param Container $container
  30. * @return void
  31. */
  32. public function register(Container $container)
  33. {
  34. $container['request'] = function () {
  35. $psr17Factory = new Psr17Factory();
  36. $creator = new ServerRequestCreator(
  37. $psr17Factory, // ServerRequestFactory
  38. $psr17Factory, // UriFactory
  39. $psr17Factory, // UploadedFileFactory
  40. $psr17Factory // StreamFactory
  41. );
  42. $server = $_SERVER;
  43. if (false === isset($server['REQUEST_METHOD'])) {
  44. $server['REQUEST_METHOD'] = 'GET';
  45. }
  46. $method = $server['REQUEST_METHOD'];
  47. $headers = function_exists('getallheaders') ? getallheaders() : $creator::getHeadersFromServer($_SERVER);
  48. $post = null;
  49. if (in_array($method, ['POST', 'PUT', 'PATCH', 'DELETE'])) {
  50. foreach ($headers as $headerName => $headerValue) {
  51. if ('content-type' !== strtolower($headerName)) {
  52. continue;
  53. }
  54. $contentType = strtolower(trim(explode(';', $headerValue, 2)[0]));
  55. switch ($contentType) {
  56. case 'application/x-www-form-urlencoded':
  57. case 'multipart/form-data':
  58. $post = $_POST;
  59. break 2;
  60. case 'application/json':
  61. case 'application/vnd.api+json':
  62. try {
  63. $json = file_get_contents('php://input');
  64. $post = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
  65. if (!is_array($post)) {
  66. $post = null;
  67. }
  68. } catch (JsonException $e) {
  69. $post = null;
  70. }
  71. break 2;
  72. }
  73. }
  74. }
  75. // Remove _url from ngnix routes.
  76. $get = $_GET;
  77. unset($get['_url']);
  78. if (isset($server['QUERY_STRING'])) {
  79. $query = $server['QUERY_STRING'];
  80. if (strpos($query, '_url=') !== false) {
  81. parse_str($query, $query);
  82. unset($query['_url']);
  83. $server['QUERY_STRING'] = http_build_query($query);
  84. }
  85. }
  86. return $creator->fromArrays($server, $headers, $_COOKIE, $get, $post, $_FILES, fopen('php://input', 'rb') ?: null);
  87. };
  88. $container['route'] = $container->factory(function () {
  89. return clone Uri::getCurrentRoute();
  90. });
  91. }
  92. }