web-dev-qa-db-ja.com

シングルLaravel複数のコントローラーのルート

複数のユーザータイプがあるプロジェクトを作成しています。 superadmin、admin、managersなど。ユーザーが認証されると、システムはユーザータイプをチェックし、それぞれのコントローラーに送信します。このためのミドルウェアは正常に機能しています。

したがって、マネージャーが http://example.com/dashboard に移動すると、マネージャーダッシュボードが表示され、管理者が同じリンクに移動すると、管理ダッシュボードが表示されます。 。

以下のルートグループは個別に正常に機能しますが、一緒に配置すると最後のルートグループのみが機能します。

/*****  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のようなルートの名前を変更できることは知っていますが、クリーンなルートを実現する他の方法があるかどうか疑問に思いました。誰かが回避策を知っていますか?

BTW私はLARAVEL 5.1を使用しています

どんな助けでも大歓迎です:)

12
omer Farooq

私が考えることができる最善の解決策は、ユーザーのすべてのページを管理する1つのコントローラーを作成することです。

ルート.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');  
    }
}
3
Alex Kyriakidis

これは、ルートアクションのnamespaceuses、および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);
    }
}

このように、最終的な名前空間プレフィックスなしで各ルートを1回だけ登録する必要があります。

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'に変換し、役割固有のミドルウェアを適用します。

7
nCrazed