Skip to content

Commit 432e4e0

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.6
2 parents b805b16 + eaa4339 commit 432e4e0

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

system/Router/AutoRouterImproved.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ private function searchFirstController(): bool
162162
$segment = array_shift($segments);
163163
$controllerPos++;
164164

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

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

211211
$namespaces = array_map(
212-
fn ($segment) => $this->translateURIDashes($segment),
212+
fn ($segment) => $this->translateURI($segment),
213213
$segments
214214
);
215215

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

308308
$method = '';
309309
if ($methodParam !== null) {
310-
$method = $httpVerb . $this->translateURIDashes($methodParam);
310+
$method = $httpVerb . $this->translateURI($methodParam);
311311

312312
$this->checkUriForMethod($method);
313313
}
@@ -519,7 +519,17 @@ private function checkUriForMethod(string $method): void
519519
return;
520520
}
521521

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

539-
private function translateURIDashes(string $segment): string
549+
/**
550+
* Translates URI segment to CamelCase or replaces `-` with `_`.
551+
*/
552+
private function translateURI(string $segment): string
540553
{
541554
if ($this->translateUriToCamelCase) {
542555
if (strtolower($segment) !== $segment) {

tests/system/Router/AutoRouterImprovedTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,28 @@ public function testAutoRouteFallbackToDefaultMethod(): void
277277
], $router->getPos());
278278
}
279279

280+
public function testAutoRouteFallbackToDefaultMethodWithTranslateUriToCamelCase(): void
281+
{
282+
$config = config(Routing::class);
283+
$config->translateUriToCamelCase = true;
284+
Factories::injectMock('config', Routing::class, $config);
285+
286+
$router = $this->createNewAutoRouter();
287+
288+
[$directory, $controller, $method, $params]
289+
= $router->getRoute('index/15', Method::GET);
290+
291+
$this->assertNull($directory);
292+
$this->assertSame('\\' . Index::class, $controller);
293+
$this->assertSame('getIndex', $method);
294+
$this->assertSame(['15'], $params);
295+
$this->assertSame([
296+
'controller' => 0,
297+
'method' => null,
298+
'params' => 1,
299+
], $router->getPos());
300+
}
301+
280302
public function testAutoRouteFallbackToDefaultControllerOneParam(): void
281303
{
282304
$router = $this->createNewAutoRouter();

0 commit comments

Comments
 (0)