Single Laravel Route for multiple controllers

后端 未结 2 439
温柔的废话
温柔的废话 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

    The best solution I can think is to create one controller that manages all the pages for the users.

    example in routes.php file:

    Route::get('dashboard', 'PagesController@dashboard');
    Route::get('users', 'PagesController@manageUsers');
    

    your PagesController.php file:

    protected $user;
    
    public function __construct()
    {
        $this->user = Auth::user();
    }
    
    public function dashboard(){
        //you have to define 'isSuperAdmin' and 'isAdmin' functions inside your user model or somewhere else
        if($this->user->isSuperAdmin()){
            $controller = app()->make('SuperAdminController');
            return $controller->callAction('dashboard');    
        }
        if($this->user->isAdmin()){
            $controller = app()->make('AdminController');
            return $controller->callAction('dashboard');    
        }
    }
    public function manageUsers(){
        if($this->user->isSuperAdmin()){
            $controller = app()->make('SuperAdminController');
            return $controller->callAction('manageUsers');  
        }
        if($this->user->isAdmin()){
            $controller = app()->make('AdminController');
            return $controller->callAction('manageUsers');  
        }
    }
    
    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题