Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -937,20 +937,11 @@ private static function handle(?array $routes = null, bool $quitAfterRun = false
$uri = $uri ?? static::getCurrentUri();
$routeToHandle = static::findRoute($routes, $uri, $quitAfterRun);

// hacky solution to handle middleware catching all middleware with pattern (.*?)
$routesToRun = array_filter($routeToHandle, function ($route) use ($uri) {
return $route['route']['pattern'] === $uri || $route['route']['pattern'] === '/.*' || implode('/', $route['params'] ?? []) === ltrim($uri, '/');
});

if (empty($routesToRun)) {
$routesToRun = $routeToHandle;
}

foreach ($routesToRun as $currentRoute) {
foreach ($routeToHandle as $currentRoute) {
static::invoke($currentRoute['handler'], $currentRoute['params']);
}

return count($routesToRun);
return count($routeToHandle);
}

private static function invoke($handler, $params = [])
Expand Down
91 changes: 91 additions & 0 deletions tests/middleware.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,94 @@ class StaticTestClassMid

expect(app()->request()->next('data'))->toBe('grouped in-route named middleware');
});

/**
* Router::reset() only exists on v5.x; restore every static property
* of the router to its declared default so each test starts clean.
*/
function resetRouterState(): void
{
$class = new \ReflectionClass(\Leaf\Router::class);

foreach ($class->getDefaultProperties() as $name => $default) {
$property = $class->getProperty($name);

if ($property->isStatic()) {
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$property->setValue(null, $default);
}
}
}

test('group middleware runs for dynamic routes inside the group', function () {
// https://github.com/leafsphp/leaf/issues/316 + #327
resetRouterState();
app()->setBasePath('/');
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_URI'] = '/practices/42/submit';

app()->registerMiddleware('mid316', function () {
app()->response()->next([
'data' => 'group middleware on dynamic route',
]);
});

app()->group('/practices', ['middleware' => 'mid316', function () {
app()->get('/{id}/submit', function () {});
}]);

app()->run();

expect(app()->request()->next('data'))->toBe('group middleware on dynamic route');
});

test('in-route middleware runs for dynamic routes inside a group', function () {
resetRouterState();
app()->setBasePath('/');
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_URI'] = '/teams/7';

app()->registerMiddleware('mid327', function () {
app()->response()->next([
'data' => 'in-route middleware on dynamic route',
]);
});

app()->group('/teams', function () {
app()->get('/{id}', ['middleware' => 'mid327', function () {}]);
});

app()->run();

expect(app()->request()->next('data'))->toBe('in-route middleware on dynamic route');
});

test('dynamic group middleware still runs when a catch-all middleware exists', function () {
// the reported scenario: auth.required on a group + any global middleware
resetRouterState();
app()->setBasePath('/');
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_URI'] = '/practices/42/submit';

$ran = ['global' => false, 'group' => false];

app()->use(function () use (&$ran) {
$ran['global'] = true;
});

app()->registerMiddleware('mid316b', function () use (&$ran) {
$ran['group'] = true;
});

app()->group('/practices', ['middleware' => 'mid316b', function () {
app()->get('/{id}/submit', function () {});
}]);

app()->run();

expect($ran['global'])->toBeTrue()
->and($ran['group'])->toBeTrue();
});
Loading