Skip to content

Commit

Permalink
Merge pull request #8980 from kenjis/fix-AutoRouterImproved-translate…
Browse files Browse the repository at this point in the history
…UriToCamelCase

fix: [Auto Routing Improved] Default Method Fallback does not work with `$translateUriToCamelCase`
  • Loading branch information
kenjis authored Jun 24, 2024
2 parents ab64aeb + d474187 commit eaa4339
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
23 changes: 18 additions & 5 deletions system/Router/AutoRouterImproved.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private function searchFirstController(): bool
$segment = array_shift($segments);
$controllerPos++;

$class = $this->translateURIDashes($segment);
$class = $this->translateURI($segment);

// as soon as we encounter any segment that is not PSR-4 compliant, stop searching
if (! $this->isValidSegment($class)) {
Expand Down Expand Up @@ -209,7 +209,7 @@ private function searchLastDefaultController(): bool
}

$namespaces = array_map(
fn ($segment) => $this->translateURIDashes($segment),
fn ($segment) => $this->translateURI($segment),
$segments
);

Expand Down Expand Up @@ -307,7 +307,7 @@ public function getRoute(string $uri, string $httpVerb): array

$method = '';
if ($methodParam !== null) {
$method = $httpVerb . $this->translateURIDashes($methodParam);
$method = $httpVerb . $this->translateURI($methodParam);

$this->checkUriForMethod($method);
}
Expand Down Expand Up @@ -519,7 +519,17 @@ private function checkUriForMethod(string $method): void
return;
}

if (! in_array($method, get_class_methods($this->controller), true)) {
if (
// For example, if `getSomeMethod()` exists in the controller, only
// the URI `controller/some-method` should be accessible. But if a
// visitor navigates to the URI `controller/somemethod`, `getSomemethod()`
// will be checked, and `method_exists()` will return true because
// method names in PHP are case-insensitive.
method_exists($this->controller, $method)
// But we do not permit `controller/somemethod`, so check the exact
// method name.
&& ! in_array($method, get_class_methods($this->controller), true)
) {
throw new PageNotFoundException(
'"' . $this->controller . '::' . $method . '()" is not found.'
);
Expand All @@ -536,7 +546,10 @@ private function isValidSegment(string $segment): bool
return (bool) preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/', $segment);
}

private function translateURIDashes(string $segment): string
/**
* Translates URI segment to CamelCase or replaces `-` with `_`.
*/
private function translateURI(string $segment): string
{
if ($this->translateUriToCamelCase) {
if (strtolower($segment) !== $segment) {
Expand Down
22 changes: 22 additions & 0 deletions tests/system/Router/AutoRouterImprovedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,28 @@ public function testAutoRouteFallbackToDefaultMethod(): void
], $router->getPos());
}

public function testAutoRouteFallbackToDefaultMethodWithTranslateUriToCamelCase(): void
{
$config = config(Routing::class);
$config->translateUriToCamelCase = true;
Factories::injectMock('config', Routing::class, $config);

$router = $this->createNewAutoRouter();

[$directory, $controller, $method, $params]
= $router->getRoute('index/15', Method::GET);

$this->assertNull($directory);
$this->assertSame('\\' . Index::class, $controller);
$this->assertSame('getIndex', $method);
$this->assertSame(['15'], $params);
$this->assertSame([
'controller' => 0,
'method' => null,
'params' => 1,
], $router->getPos());
}

public function testAutoRouteFallbackToDefaultControllerOneParam(): void
{
$router = $this->createNewAutoRouter();
Expand Down

0 comments on commit eaa4339

Please sign in to comment.