diff --git a/src/Router.php b/src/Router.php index 208801c..977aea7 100644 --- a/src/Router.php +++ b/src/Router.php @@ -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 = []) diff --git a/tests/middleware.test.php b/tests/middleware.test.php index 8c66fbb..a524bed 100644 --- a/tests/middleware.test.php +++ b/tests/middleware.test.php @@ -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(); +});