多个控制器的单个 Laravel 路由

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31368433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:56:02  来源:igfitidea点击:

Single Laravel Route for multiple controllers

phplaravellaravel-5laravel-routing

提问by omer Farooq

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 to the respective controller. The middle ware for this is working fine.

我正在创建一个我有多种用户类型的项目,例如。superadmin、admin、managers 等。一旦用户通过身份验证,系统会检查用户类型并将其发送到相应的控制器。用于此的中间件工作正常。

So when manager goes to http://example.com/dashboardhe will see the managers dashboard while when admin goes to the same link he can see the admin dashboard.

因此,当经理转到http://example.com/dashboard 时,他将看到经理仪表板,而当管理员转到同一链接时,他可以看到管理仪表板。

The below route groups work fine individually but when placed together only the last one works.

下面的路线组单独工作正常,但放在一起时只有最后一个工作。

/*****  Routes.php  ****/
 // SuperAdmin Routes
    Route::group(['middleware' => 'App\Http\Middleware\SuperAdminMiddleware'], function () {
        Route::get('dashboard', 'SuperAdmin\dashboard@index'); // SuperAdmin Dashboard
        Route::get('users', 'SuperAdmin\manageUsers@index'); // SuperAdmin Users
    });

 // Admin Routes
    Route::group(['middleware' => 'App\Http\Middleware\AdminMiddleware'], function () {
        Route::get('dashboard', 'Admin\dashboard@index'); // Admin Dashboard
        Route::get('users', 'Admin\manageUsers@index'); // Admin Users
    });

I know we can rename the routes like superadmin/dashboard and admin/dashboard but i was wondering if there is any other way to achieve the clean route. Does anyone know of any anywork arounds ?

我知道我们可以重命名像 superadmin/dashboard 和 admin/dashboard 这样的路由,但我想知道是否还有其他方法可以实现干净的路由。有谁知道任何工作?

BTW i am using LARAVEL 5.1

顺便说一句,我正在使用 LARAVEL 5.1

Any help is appreciated :)

任何帮助表示赞赏:)

采纳答案by Alex Kyriakidis

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.php 文件中的示例:

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

your PagesController.php file:

你的 PagesController.php 文件:

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');  
    }
}

回答by nCrazed

You can do this with a Before Middlewarethat overrides the route action's namespace, usesand controllerattributes:

您可以使用覆盖路由操作的,和属性的 Before Middleware执行此操作:namespaceusescontroller

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 roleattribute as well as apply the role specific middleware.

中间件将转换'dashboard@index''Admin\dashboard@index''SuperAdmin\dashboard@index'取决于当前用户的role属性,并应用特定于角色的中间件。