多个控制器的单个 Laravel 路由
Single Laravel Route for multiple controllers
我正在创建一个项目,其中我有多个用户类型,例如。 superadmin、admin、managers 等。一旦用户通过身份验证,系统就会检查用户类型并将其发送到相应的控制器。中间件工作正常。
因此,当经理转到 http://example.com/dashboard 时,他将看到经理仪表板,而当管理员转到相同的 link 时,他可以看到管理仪表板。
下面的路由组单独工作正常,但放在一起时只有最后一个工作。
/***** 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
});
我知道我们可以像 superadmin/dashboard 和 admin/dashboard 这样重命名路线,但我想知道是否还有其他方法可以实现干净的路线。有谁知道任何解决方法吗?
顺便说一句,我正在使用 LARAVEL 5.1
感谢任何帮助:)
我认为最好的解决方案是创建一个控制器来管理用户的所有页面。
routes.php 文件中的示例:
Route::get('dashboard', 'PagesController@dashboard');
Route::get('users', 'PagesController@manageUsers');
您的 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');
}
}
您可以使用覆盖路由操作的 namespace
、uses
和 controller
属性的 Before Middleware 来执行此操作:
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);
}
}
这样你只需要为每个路由注册一次而不需要最后的命名空间前缀:
Route::group(['middleware' => 'App\Http\Middleware\AdminRoutingMiddleware'], function () {
Route::get('dashboard', 'dashboard@index');
Route::get('users', 'manageUsers@index');
});
中间件将根据当前用户的 role
属性将 'dashboard@index'
转换为 'Admin\dashboard@index'
或 'SuperAdmin\dashboard@index'
,并应用角色特定的中间件。
我正在创建一个项目,其中我有多个用户类型,例如。 superadmin、admin、managers 等。一旦用户通过身份验证,系统就会检查用户类型并将其发送到相应的控制器。中间件工作正常。
因此,当经理转到 http://example.com/dashboard 时,他将看到经理仪表板,而当管理员转到相同的 link 时,他可以看到管理仪表板。
下面的路由组单独工作正常,但放在一起时只有最后一个工作。
/***** 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
});
我知道我们可以像 superadmin/dashboard 和 admin/dashboard 这样重命名路线,但我想知道是否还有其他方法可以实现干净的路线。有谁知道任何解决方法吗?
顺便说一句,我正在使用 LARAVEL 5.1
感谢任何帮助:)
我认为最好的解决方案是创建一个控制器来管理用户的所有页面。
routes.php 文件中的示例:
Route::get('dashboard', 'PagesController@dashboard');
Route::get('users', 'PagesController@manageUsers');
您的 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');
}
}
您可以使用覆盖路由操作的 namespace
、uses
和 controller
属性的 Before Middleware 来执行此操作:
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);
}
}
这样你只需要为每个路由注册一次而不需要最后的命名空间前缀:
Route::group(['middleware' => 'App\Http\Middleware\AdminRoutingMiddleware'], function () {
Route::get('dashboard', 'dashboard@index');
Route::get('users', 'manageUsers@index');
});
中间件将根据当前用户的 role
属性将 'dashboard@index'
转换为 'Admin\dashboard@index'
或 'SuperAdmin\dashboard@index'
,并应用角色特定的中间件。