From 89adbcfe9b30e53f3802522c72ce2cefba35bddb Mon Sep 17 00:00:00 2001 From: William Desportes Date: Fri, 20 Jan 2023 13:12:22 +0400 Subject: [PATCH] Fix PSR-7 implementation for GET and test implementation for POST Signed-off-by: William Desportes --- .../Http/Factory/ServerRequestFactory.php | 23 ++++-- phpstan-baseline.neon | 5 ++ .../Http/Factory/ServerRequestFactoryTest.php | 81 ++++++++++++++++++- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/libraries/classes/Http/Factory/ServerRequestFactory.php b/libraries/classes/Http/Factory/ServerRequestFactory.php index 360fb56db2..62d2941ca7 100644 --- a/libraries/classes/Http/Factory/ServerRequestFactory.php +++ b/libraries/classes/Http/Factory/ServerRequestFactory.php @@ -94,27 +94,38 @@ class ServerRequestFactory /** @var ServerRequestInterface $serverRequest */ $serverRequest = LaminasServerRequestFactory::fromGlobals(); } else { - $serverRequest = self::createServerRequestFromGlobals(); + $creator = new self(); + $serverRequest = self::createServerRequestFromGlobals($creator); } return new ServerRequest($serverRequest); } - private static function createServerRequestFromGlobals(): ServerRequestInterface + /** + * @return array + */ + protected function getallheaders(): array + { + /** @var array $headers */ + $headers = function_exists('getallheaders') ? getallheaders() : []; + + return $headers; + } + + private static function createServerRequestFromGlobals(self $creator): ServerRequestInterface { - $creator = new self(); $serverRequest = $creator->serverRequestFactory->createServerRequest( $_SERVER['REQUEST_METHOD'] ?? 'GET', $creator->createUriFromGlobals($_SERVER), $_SERVER ); - /** @var array $headers */ - $headers = function_exists('getallheaders') ? getallheaders() : []; - foreach ($headers as $name => $value) { + foreach ($creator->getallheaders() as $name => $value) { $serverRequest = $serverRequest->withAddedHeader($name, $value); } + $serverRequest = $serverRequest->withQueryParams($_GET); + if ($serverRequest->getMethod() !== 'POST') { return $serverRequest; } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6484d54093..a0466e914f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -10560,6 +10560,11 @@ parameters: count: 1 path: test/classes/Http/Factory/ServerRequestFactoryTest.php + - + message: "#^Parameter \\#1 \\$serverRequest of class PhpMyAdmin\\\\Http\\\\ServerRequest constructor expects Psr\\\\Http\\\\Message\\\\ServerRequestInterface, mixed given\\.$#" + count: 1 + path: test/classes/Http/Factory/ServerRequestFactoryTest.php + - message: "#^Method PhpMyAdmin\\\\Tests\\\\ImportTest\\:\\:provDetectType\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 diff --git a/test/classes/Http/Factory/ServerRequestFactoryTest.php b/test/classes/Http/Factory/ServerRequestFactoryTest.php index 6f7227bbf7..afe20d4297 100644 --- a/test/classes/Http/Factory/ServerRequestFactoryTest.php +++ b/test/classes/Http/Factory/ServerRequestFactoryTest.php @@ -8,6 +8,7 @@ use GuzzleHttp\Psr7\HttpFactory as GuzzleHttpFactory; use Laminas\Diactoros\ServerRequestFactory as LaminasServerRequestFactory; use Nyholm\Psr7\Factory\Psr17Factory as NyholmPsr17Factory; use PhpMyAdmin\Http\Factory\ServerRequestFactory; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; use Psr\Http\Message\ServerRequestFactoryInterface; use Slim\Psr7\Factory\ServerRequestFactory as SlimServerRequestFactory; @@ -72,19 +73,20 @@ class ServerRequestFactoryTest extends AbstractTestCase * * @dataProvider dataProviderPsr7Implementations */ - public function testPsr7Implementation(string $className, string $humanName): void + public function testPsr7ImplementationGet(string $className, string $humanName): void { $this->testOrSkip($className, $humanName); $_GET['foo'] = 'bar'; + $_GET['blob'] = 'baz'; $_SERVER['QUERY_STRING'] = 'foo=bar&blob=baz'; $_SERVER['REQUEST_URI'] = '/test-page.php'; - $_SERVER['REQUEST_METHOD'] = 'PATCH'; + $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['HTTP_HOST'] = 'phpmyadmin.local'; $request = ServerRequestFactory::createFromGlobals(); $this->assertSame( - 'PATCH', + 'GET', $request->getMethod() ); $this->assertSame( @@ -112,6 +114,79 @@ class ServerRequestFactoryTest extends AbstractTestCase ], $request->getQueryParams()); } + public function testCreateServerRequestFromGlobals(): void + { + $_GET['foo'] = 'bar'; + $_GET['blob'] = 'baz'; + $_POST['input1'] = 'value1'; + $_POST['input2'] = 'value2'; + $_POST['input3'] = ''; + $_SERVER['QUERY_STRING'] = 'foo=bar&blob=baz'; + $_SERVER['REQUEST_URI'] = '/test-page.php'; + $_SERVER['REQUEST_METHOD'] = 'POST'; + $_SERVER['HTTP_HOST'] = 'phpmyadmin.local'; + + $creator = $this->getMockBuilder(ServerRequestFactory::class) + ->setMethods(['getallheaders']) + ->getMock(); + + $creator + ->method('getallheaders') + ->willReturn(['Content-Type' => 'application/x-www-form-urlencoded']); + + $serverRequest = $this->callFunction( + $creator, + ServerRequestFactory::class, + 'createServerRequestFromGlobals', + [$creator] + ); + + $request = new ServerRequest($serverRequest); + + $this->assertSame( + ['application/x-www-form-urlencoded'], + $request->getHeader('Content-Type') + ); + $this->assertSame( + 'POST', + $request->getMethod() + ); + $this->assertSame( + 'http://phpmyadmin.local/test-page.php?foo=bar&blob=baz', + $request->getUri()->__toString() + ); + $this->assertTrue( + $request->isPost() + ); + $this->assertSame( + 'default', + $request->getParam('not-exists', 'default') + ); + $this->assertSame( + 'bar', + $request->getParam('foo') + ); + $this->assertSame( + 'baz', + $request->getParam('blob') + ); + $this->assertSame([ + 'foo' => 'bar', + 'blob' => 'baz', + ], $request->getQueryParams()); + + $this->assertSame([ + 'input1' => 'value1', + 'input2' => 'value2', + 'input3' => '', + ], $request->getParsedBody()); + + $this->assertNull($request->getParsedBodyParam('foo')); + $this->assertSame('value1', $request->getParsedBodyParam('input1')); + $this->assertSame('value2', $request->getParsedBodyParam('input2')); + $this->assertSame('', $request->getParsedBodyParam('input3', 'default')); + } + /** * @phpstan-param class-string $className *