Single Laravel Route for multiple controllers

后端 未结 2 447
温柔的废话
温柔的废话 2020-12-09 05:01

I am creating a project where i have multiple user types, eg. superadmin, admin, managers etc. Once the user is authenticated, the system checks the user type and sends him

2条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-09 05:54

    You can do this with a Before Middleware that overrides the route action's namespace, uses and controller attributes:

    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Contracts\Container\Container;
    use App\Http\Middleware\AdminMiddleware;
    use App\Http\Middleware\SuperAdminMiddleware;
    
    class AdminRoutingMiddleware
    {
        /**
         * @var Container
         */
        private $container;
    
        public function __construct(Container $container)
        {
            $this->container = $container;
        }
    
        private static $ROLES = [
            'admin' => [
                'namespace' => 'Admin',
                'middleware' => AdminMiddleware::class,
            ],
            'super' => [
                'namespace' => 'SuperAdmin',
                'middleware' => SuperAdminMiddleware::class,
            ]
        ];
    
        public function handle(Request $request, Closure $next)
        {
            $action = $request->route()->getAction();
            $role = static::$ROLES[$request->user()->role];
    
            $namespace = $action['namespace'] . '\\' . $role['namespace'];
    
            $action['uses'] = str_replace($action['namespace'], $namespace, $action['uses']);
            $action['controller'] = str_replace($action['namespace'], $namespace, $action['controller']);
            $action['namespace'] = $namespace;
    
            $request->route()->setAction($action);
    
            return $this->container->make($role['middleware'])->handle($request, $next);
        }
    }
    

    This way you have to register each route only once without the final namespace prefix:

    Route::group(['middleware' => 'App\Http\Middleware\AdminRoutingMiddleware'], function () {
        Route::get('dashboard', 'dashboard@index');
        Route::get('users', 'manageUsers@index');
    });
    

    The middleware will convert 'dashboard@index' to 'Admin\dashboard@index' or 'SuperAdmin\dashboard@index' depending on current user's role attribute as well as apply the role specific middleware.

提交回复
热议问题