From 772bea8aba1276c83faf0c49887dd99e1df8cbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 May 2026 13:32:18 +0200 Subject: [PATCH 1/5] parma alias + tests --- src/Http/Http.php | 14 ++++- tests/HttpTest.php | 130 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/src/Http/Http.php b/src/Http/Http.php index 74965fc..eb1acb3 100755 --- a/src/Http/Http.php +++ b/src/Http/Http.php @@ -699,11 +699,21 @@ protected function getArguments(Hook $hook, array $values, array $requestParams) { $arguments = []; foreach ($hook->getParams() as $key => $param) { // Get value from route or request object - $existsInRequest = \array_key_exists($key, $requestParams); + $actualKey = $key; + if (!\array_key_exists($key, $requestParams) && !empty($param['aliases'])) { + foreach ($param['aliases'] as $alias) { + if (\array_key_exists($alias, $requestParams)) { + $actualKey = $alias; + break; + } + } + } + + $existsInRequest = \array_key_exists($actualKey, $requestParams); $existsInValues = \array_key_exists($key, $values); $paramExists = $existsInRequest || $existsInValues; - $arg = $existsInRequest ? $requestParams[$key] : $param['default']; + $arg = $existsInRequest ? $requestParams[$actualKey] : $param['default']; if (\is_callable($arg) && !\is_string($arg)) { $arg = \call_user_func_array($arg, array_values($this->getResources($param['injections']))); } diff --git a/tests/HttpTest.php b/tests/HttpTest.php index 6535df0..e846018 100755 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -11,6 +11,7 @@ use Utopia\Http\Adapter\FPM\Response; use Utopia\Http\Adapter\FPM\Server; use Utopia\Http\Tests\UtopiaFPMRequestTest; +use Utopia\Servers\Hook; use Utopia\Validator\Text; final class HttpTest extends TestCase @@ -290,6 +291,135 @@ public function testCanAddAndExecuteHooks(): void $this->assertSame('x-def', $result); } + public function testCanResolveParamAliases(): void + { + $this->http + ->error() + ->inject('error') + ->action(function ($error) { + echo 'error-' . $error->getMessage(); + }); + + // Alias resolves when canonical key is absent + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias', 'xLegacy']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['xAlias' => 'from-alias']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('from-alias', $result); + + // Canonical key wins when both are present + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['x' => 'canonical', 'xAlias' => 'aliased']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('canonical', $result); + + // First matching alias wins when multiple are present + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias1', 'xAlias2']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['xAlias2' => 'second', 'xAlias1' => 'first']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('first', $result); + + // Falls back to default when neither canonical nor any alias is present + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['unrelated' => 'value']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('x-def', $result); + + // Required param throws when neither canonical nor any alias is present + $route = new Route('GET', '/path'); + $route + ->param('x', '', new Text(200), 'x param', false) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['unrelated' => 'value']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('error-Param "x" is not optional.', $result); + + // Validation runs against the aliased value and reports the canonical key + $route = new Route('GET', '/path'); + $route + ->param('x', '', new Text(1, min: 0), 'x param', false) + ->action(function ($x) { + echo $x; + }); + $this->setParamAliases($route, 'x', ['xAlias']); + + ob_start(); + $request = new UtopiaFPMRequestTest(); + $request::_setParams(['xAlias' => 'too-long']); + $this->http->execute($route, $request, new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('error-Invalid `x` param: Value must be a valid string and no longer than 1 chars', $result); + } + + /** + * @param array $aliases + */ + private function setParamAliases(Hook $hook, string $key, array $aliases): void + { + $reflection = new \ReflectionProperty(Hook::class, 'params'); + $params = $reflection->getValue($hook); + $params[$key]['aliases'] = $aliases; + $reflection->setValue($hook, $params); + } + public function testAllowRouteOverrides(): void { Http::setAllowOverride(false); From ffa12f2958ce54f9e157d0182c25a3b9bfbd5401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 May 2026 13:41:52 +0200 Subject: [PATCH 2/5] Simplify implementation --- composer.json | 2 +- composer.lock | 27 ++++++++++++++++++--------- tests/HttpTest.php | 30 ++++++------------------------ 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/composer.json b/composer.json index 5675f8c..2cb7c09 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "require": { "php": ">=8.3", "utopia-php/di": "0.3.*", - "utopia-php/servers": "0.3.*", + "utopia-php/servers": "dev-feat-param-aliases as 0.3.x-dev", "utopia-php/compression": "0.1.*", "utopia-php/telemetry": "0.2.*", "utopia-php/validators": "0.2.*" diff --git a/composer.lock b/composer.lock index b88d836..3be789a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ffcf218a03a3c0e154ccd9029a626747", + "content-hash": "41a79801cc0c3c9b6e6fb58087c23e41", "packages": [ { "name": "brick/math", @@ -1966,16 +1966,16 @@ }, { "name": "utopia-php/servers", - "version": "0.3.0", + "version": "dev-feat-param-aliases", "source": { "type": "git", "url": "https://github.com/utopia-php/servers.git", - "reference": "235be31200df9437fc96a1c270ffef4c64fafe52" + "reference": "2cec9c78859b3efc696ca58dfe530144e9d20269" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/servers/zipball/235be31200df9437fc96a1c270ffef4c64fafe52", - "reference": "235be31200df9437fc96a1c270ffef4c64fafe52", + "url": "https://api.github.com/repos/utopia-php/servers/zipball/2cec9c78859b3efc696ca58dfe530144e9d20269", + "reference": "2cec9c78859b3efc696ca58dfe530144e9d20269", "shasum": "" }, "require": { @@ -2014,9 +2014,9 @@ ], "support": { "issues": "https://github.com/utopia-php/servers/issues", - "source": "https://github.com/utopia-php/servers/tree/0.3.0" + "source": "https://github.com/utopia-php/servers/tree/feat-param-aliases" }, - "time": "2026-03-13T11:31:42+00:00" + "time": "2026-05-04T11:39:00+00:00" }, { "name": "utopia-php/telemetry", @@ -4084,9 +4084,18 @@ "time": "2025-12-08T11:19:18+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/servers", + "version": "dev-feat-param-aliases", + "alias": "0.3.x-dev", + "alias_normalized": "0.3.9999999.9999999-dev" + } + ], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "utopia-php/servers": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/tests/HttpTest.php b/tests/HttpTest.php index e846018..b444334 100755 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -11,7 +11,6 @@ use Utopia\Http\Adapter\FPM\Response; use Utopia\Http\Adapter\FPM\Server; use Utopia\Http\Tests\UtopiaFPMRequestTest; -use Utopia\Servers\Hook; use Utopia\Validator\Text; final class HttpTest extends TestCase @@ -303,11 +302,10 @@ public function testCanResolveParamAliases(): void // Alias resolves when canonical key is absent $route = new Route('GET', '/path'); $route - ->param('x', 'x-def', new Text(200), 'x param', true) + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias', 'xLegacy']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias', 'xLegacy']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -321,11 +319,10 @@ public function testCanResolveParamAliases(): void // Canonical key wins when both are present $route = new Route('GET', '/path'); $route - ->param('x', 'x-def', new Text(200), 'x param', true) + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -339,11 +336,10 @@ public function testCanResolveParamAliases(): void // First matching alias wins when multiple are present $route = new Route('GET', '/path'); $route - ->param('x', 'x-def', new Text(200), 'x param', true) + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias1', 'xAlias2']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias1', 'xAlias2']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -357,11 +353,10 @@ public function testCanResolveParamAliases(): void // Falls back to default when neither canonical nor any alias is present $route = new Route('GET', '/path'); $route - ->param('x', 'x-def', new Text(200), 'x param', true) + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -375,11 +370,10 @@ public function testCanResolveParamAliases(): void // Required param throws when neither canonical nor any alias is present $route = new Route('GET', '/path'); $route - ->param('x', '', new Text(200), 'x param', false) + ->param('x', '', new Text(200), 'x param', false, aliases: ['xAlias']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -393,11 +387,10 @@ public function testCanResolveParamAliases(): void // Validation runs against the aliased value and reports the canonical key $route = new Route('GET', '/path'); $route - ->param('x', '', new Text(1, min: 0), 'x param', false) + ->param('x', '', new Text(1, min: 0), 'x param', false, aliases: ['xAlias']) ->action(function ($x) { echo $x; }); - $this->setParamAliases($route, 'x', ['xAlias']); ob_start(); $request = new UtopiaFPMRequestTest(); @@ -409,17 +402,6 @@ public function testCanResolveParamAliases(): void $this->assertSame('error-Invalid `x` param: Value must be a valid string and no longer than 1 chars', $result); } - /** - * @param array $aliases - */ - private function setParamAliases(Hook $hook, string $key, array $aliases): void - { - $reflection = new \ReflectionProperty(Hook::class, 'params'); - $params = $reflection->getValue($hook); - $params[$key]['aliases'] = $aliases; - $reflection->setValue($hook, $params); - } - public function testAllowRouteOverrides(): void { Http::setAllowOverride(false); From a59317c6c39119d67f62782a0cc18f962f2e6de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 May 2026 13:47:19 +0200 Subject: [PATCH 3/5] implement e2e tests --- tests/HttpTest.php | 234 ++++++++++++++++++++++++++------------------- 1 file changed, 134 insertions(+), 100 deletions(-) diff --git a/tests/HttpTest.php b/tests/HttpTest.php index b444334..743a505 100755 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -299,107 +299,141 @@ public function testCanResolveParamAliases(): void echo 'error-' . $error->getMessage(); }); - // Alias resolves when canonical key is absent - $route = new Route('GET', '/path'); - $route - ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias', 'xLegacy']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['xAlias' => 'from-alias']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('from-alias', $result); - - // Canonical key wins when both are present - $route = new Route('GET', '/path'); - $route - ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['x' => 'canonical', 'xAlias' => 'aliased']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('canonical', $result); - - // First matching alias wins when multiple are present - $route = new Route('GET', '/path'); - $route - ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias1', 'xAlias2']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['xAlias2' => 'second', 'xAlias1' => 'first']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('first', $result); + $savedGet = $_GET; + $savedPost = $_POST; + $savedMethod = $_SERVER['REQUEST_METHOD'] ?? null; - // Falls back to default when neither canonical nor any alias is present - $route = new Route('GET', '/path'); - $route - ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['unrelated' => 'value']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('x-def', $result); - - // Required param throws when neither canonical nor any alias is present - $route = new Route('GET', '/path'); - $route - ->param('x', '', new Text(200), 'x param', false, aliases: ['xAlias']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['unrelated' => 'value']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('error-Param "x" is not optional.', $result); - - // Validation runs against the aliased value and reports the canonical key - $route = new Route('GET', '/path'); - $route - ->param('x', '', new Text(1, min: 0), 'x param', false, aliases: ['xAlias']) - ->action(function ($x) { - echo $x; - }); - - ob_start(); - $request = new UtopiaFPMRequestTest(); - $request::_setParams(['xAlias' => 'too-long']); - $this->http->execute($route, $request, new Response()); - $result = ob_get_contents(); - ob_end_clean(); - - $this->assertSame('error-Invalid `x` param: Value must be a valid string and no longer than 1 chars', $result); + try { + // GET request: alias resolves from $_GET when canonical key is absent + $_GET = ['xAlias' => 'from-alias']; + $_SERVER['REQUEST_METHOD'] = 'GET'; + + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias', 'xLegacy']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('from-alias', $result); + + // GET request: canonical key wins when both are present in $_GET + $_GET = ['x' => 'canonical', 'xAlias' => 'aliased']; + + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('canonical', $result); + + // GET request: first matching alias wins when multiple are present in $_GET + $_GET = ['xAlias2' => 'second', 'xAlias1' => 'first']; + + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias1', 'xAlias2']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('first', $result); + + // GET request: falls back to default when neither canonical nor any alias is in $_GET + $_GET = ['unrelated' => 'value']; + + $route = new Route('GET', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('x-def', $result); + + // GET request: required param throws when neither canonical nor any alias is in $_GET + $_GET = ['unrelated' => 'value']; + + $route = new Route('GET', '/path'); + $route + ->param('x', '', new Text(200), 'x param', false, aliases: ['xAlias']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('error-Param "x" is not optional.', $result); + + // GET request: validation runs against the aliased value and reports the canonical key + $_GET = ['xAlias' => 'too-long']; + + $route = new Route('GET', '/path'); + $route + ->param('x', '', new Text(1, min: 0), 'x param', false, aliases: ['xAlias']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('error-Invalid `x` param: Value must be a valid string and no longer than 1 chars', $result); + + // POST request: alias resolves from $_POST body + $_GET = []; + $_POST = ['xAlias' => 'posted-alias']; + $_SERVER['REQUEST_METHOD'] = 'POST'; + + $route = new Route('POST', '/path'); + $route + ->param('x', 'x-def', new Text(200), 'x param', true, aliases: ['xAlias']) + ->action(function ($x) { + echo $x; + }); + + ob_start(); + $this->http->execute($route, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('posted-alias', $result); + } finally { + $_GET = $savedGet; + $_POST = $savedPost; + if ($savedMethod === null) { + unset($_SERVER['REQUEST_METHOD']); + } else { + $_SERVER['REQUEST_METHOD'] = $savedMethod; + } + } } public function testAllowRouteOverrides(): void From 4439705c8c2e81af826f4b6d694469c9ebc84a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 May 2026 13:52:49 +0200 Subject: [PATCH 4/5] fix url param aliases --- src/Http/Http.php | 22 ++++++++++++++++------ tests/HttpTest.php | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/Http/Http.php b/src/Http/Http.php index eb1acb3..e059a91 100755 --- a/src/Http/Http.php +++ b/src/Http/Http.php @@ -699,25 +699,35 @@ protected function getArguments(Hook $hook, array $values, array $requestParams) { $arguments = []; foreach ($hook->getParams() as $key => $param) { // Get value from route or request object - $actualKey = $key; + $requestKey = $key; if (!\array_key_exists($key, $requestParams) && !empty($param['aliases'])) { foreach ($param['aliases'] as $alias) { if (\array_key_exists($alias, $requestParams)) { - $actualKey = $alias; + $requestKey = $alias; break; } } } - $existsInRequest = \array_key_exists($actualKey, $requestParams); - $existsInValues = \array_key_exists($key, $values); + $valuesKey = $key; + if (!\array_key_exists($key, $values) && !empty($param['aliases'])) { + foreach ($param['aliases'] as $alias) { + if (\array_key_exists($alias, $values)) { + $valuesKey = $alias; + break; + } + } + } + + $existsInRequest = \array_key_exists($requestKey, $requestParams); + $existsInValues = \array_key_exists($valuesKey, $values); $paramExists = $existsInRequest || $existsInValues; - $arg = $existsInRequest ? $requestParams[$actualKey] : $param['default']; + $arg = $existsInRequest ? $requestParams[$requestKey] : $param['default']; if (\is_callable($arg) && !\is_string($arg)) { $arg = \call_user_func_array($arg, array_values($this->getResources($param['injections']))); } - $value = $existsInValues ? $values[$key] : $arg; + $value = $existsInValues ? $values[$valuesKey] : $arg; if (!$param['skipValidation']) { if (!$paramExists && !$param['optional']) { diff --git a/tests/HttpTest.php b/tests/HttpTest.php index 743a505..2836f40 100755 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -425,6 +425,48 @@ public function testCanResolveParamAliases(): void ob_end_clean(); $this->assertSame('posted-alias', $result); + + // URL path: alias resolves the placeholder name to the canonical param key + $_GET = []; + $_POST = []; + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['REQUEST_URI'] = '/users/abc-123'; + + $route = Http::get('/users/:userId') + ->param('user_id', '', new Text(200), 'user id', false, aliases: ['userId']) + ->action(function ($user_id) { + echo $user_id; + }); + + $matched = $this->http->match(new Request()); + $this->assertSame($route, $matched); + + ob_start(); + $this->http->execute($matched, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('abc-123', $result); + + // URL path value beats request param when both are present (path-level override) + $_GET = ['user_id' => 'from-query']; + $_SERVER['REQUEST_URI'] = '/users-2/from-path'; + + $route = Http::get('/users-2/:userId') + ->param('user_id', '', new Text(200), 'user id', false, aliases: ['userId']) + ->action(function ($user_id) { + echo $user_id; + }); + + $matched = $this->http->match(new Request()); + $this->assertSame($route, $matched); + + ob_start(); + $this->http->execute($matched, new Request(), new Response()); + $result = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('from-path', $result); } finally { $_GET = $savedGet; $_POST = $savedPost; From 258e3267c0fadb8f8a8d5377a35896e706336169 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Tue, 5 May 2026 10:04:11 +0530 Subject: [PATCH 5/5] Use stable servers 0.4.0 --- composer.json | 2 +- composer.lock | 27 +++++++++------------------ 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index 2cb7c09..3517ba0 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "require": { "php": ">=8.3", "utopia-php/di": "0.3.*", - "utopia-php/servers": "dev-feat-param-aliases as 0.3.x-dev", + "utopia-php/servers": "0.4.0", "utopia-php/compression": "0.1.*", "utopia-php/telemetry": "0.2.*", "utopia-php/validators": "0.2.*" diff --git a/composer.lock b/composer.lock index 3be789a..f617c48 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "41a79801cc0c3c9b6e6fb58087c23e41", + "content-hash": "288cea8b8a10ec454331ba22f82753fa", "packages": [ { "name": "brick/math", @@ -1966,16 +1966,16 @@ }, { "name": "utopia-php/servers", - "version": "dev-feat-param-aliases", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/utopia-php/servers.git", - "reference": "2cec9c78859b3efc696ca58dfe530144e9d20269" + "reference": "7db346ef377503efe0acafe0791085270cd9ed70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/servers/zipball/2cec9c78859b3efc696ca58dfe530144e9d20269", - "reference": "2cec9c78859b3efc696ca58dfe530144e9d20269", + "url": "https://api.github.com/repos/utopia-php/servers/zipball/7db346ef377503efe0acafe0791085270cd9ed70", + "reference": "7db346ef377503efe0acafe0791085270cd9ed70", "shasum": "" }, "require": { @@ -2014,9 +2014,9 @@ ], "support": { "issues": "https://github.com/utopia-php/servers/issues", - "source": "https://github.com/utopia-php/servers/tree/feat-param-aliases" + "source": "https://github.com/utopia-php/servers/tree/0.4.0" }, - "time": "2026-05-04T11:39:00+00:00" + "time": "2026-05-05T04:08:30+00:00" }, { "name": "utopia-php/telemetry", @@ -4084,18 +4084,9 @@ "time": "2025-12-08T11:19:18+00:00" } ], - "aliases": [ - { - "package": "utopia-php/servers", - "version": "dev-feat-param-aliases", - "alias": "0.3.x-dev", - "alias_normalized": "0.3.9999999.9999999-dev" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/servers": 20 - }, + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": {