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.
So when manager goes to http://example.com/dashboard he will see the managers dashboard while when admin goes to the same link he can see the admin 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 ?
BTW i am using LARAVEL 5.1
Any help is appreciated :)
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.