otifsolutions / aclmenu
An ACL Menu Package that includes User Roles, Permissions, Db based Menu Items, rights and permission based menu items
Installs: 1 370
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 1
Open Issues: 0
README
Requirements
PHP 5 > 5.3.0
Laravel > 5.0
How to install the library
Install via Composer
Using Composer (Recommended)
Either run the following command in the root directory of your project:
composer require otifsolutions/aclmenu
Usage
-
Create User Role ( via Seeder )
UserRole::updateOrCreate( ['id' => 1],[ 'name' => 'ADMIN' ]);
-
Create Menu Items for Created
UserRole
.$id = UserRole::Where(['name' => 'ADMIN'])->get('id'); MenuItem::updateOrCreate( ['id' => 1], [ 'order_number'=> 1, 'parent_id' => null, 'icon' => 'feather icon-home', 'name' => 'dashboard', 'route' => '/dashboard', 'generate_permission' => 'ALL' ]) ->user_roles() ->sync($id);
$id
is id of user role that is admin.Option type Description order_number
INT Number to show the item in sequence. parent_id
INT Id of any item as a parent menu item. icon
Varchar Icon of created menu item. name
Varchar Show the name of created menu item. route
Varchar Route access the intended page. generate_permission
isENUM
type of granted permission to the User Role, that are 'ALL', 'MANAGE_ONLY', 'READ_ONLY'.
Option Description All Allow user role to create, read, update, delete. MANAGE_ONLY Allow user role manage. READ_ONLY show that User can only read. -
- User role and permissions are created.
- Sync the permissions against menu items, so that user can have permissions to access the menu items.
{ $userRole = UserRole::where(['name' => 'ADMIN'])->first(); $permissions = Permission::whereIn('menu_item_id',$userRole->menu_items()->pluck('id'))->pluck('id'); $userRole->permissions()->sync($permissions); }
-
Register the artisan command in database seeder in App/Database/Seeder/DatabaseSeeder.php;
Artisan::call('aclmenu:refresh');
Seeder run in this sequence.
$this->call(UserRolesTableSeeder::class); $this->call(MenuItemsTableSeeder::class); $this->call(UserTableSeeder::class); $this->call(TeamsTableSeeder::class); Artisan::call('aclmenu:refresh'); $this->call(DefaultUserPermissionsSync::class);
-
Run the seeder to implement the changes
php artisan db:seed
aclmenu:refresh
- This command seeds data in
Permission
model after checking the permission inMeuItem
model. - Possible permissions are 'All', "READ" and "MANAGE_ONLY".
- Default permission is
READ
.
ACLUserTrait
-
Use
OTIFSolutions\ACLMenu\Traits\ACLUserTrait
inUser
model -
Following methods are used in this trait
Method relation Description user_role one-to-many (Inverse) This method returns user role from UserRole
model to which user belongs.group one-to-many (Inverse) This method returns group from UserRoleGroup
model to which user belongs.parent_team one-to-many (Inverse) This method returns parent_team from Team
model to which it belongs.child_team one-to-one This method returns user who created the team.
-
team
This method returns the user who created the team or parent_team.
-
hasPermission
This method checks if the user has permission or not to access the page.
if (!Auth::user()->hasPermission('READ', '/dashboard')) return 'error'; return view('dashboard');
- Returns
True
if condition is true otherwise returnfalse
. - Two Attributes are passed when calling the method.
- One is
permissionTypeString
, possible values are READ, CREATE, UPDATE, or DELETE. - If no permissionTypeString is passed, READ is considered default.
- Another attribute is
permission
, which is the route of page. - If no permission is passed, current permission is stored in session.
- Returns
-
hasPermissionMenuItem
- This method checks if the user has permission or not to access the menu item.
- Id of menu item is passed
menu_item_id
. - Boolean value is returned. Possible values ar true or false.
-
getTeamOwnerAttribute
This method returns team owner from the team. return
$this['team']['owner']
Config
-
Returns
redirect_url
if user is unauthorized e.g./
if ($request->user() == null) return redirect(config('laravelacl.redirect_url'));
-
It has a path of laravel
config.php
which returns the user from model.'models' => [ 'user' => config('auth.providers.users.model') ]
-
Use this code to use config.
config('laravelacl.models.user')
Middleware
-
Middleware handles the incoming request.
-
Middleware is set on route. such as
Route::get('/dashboard', [DashboardController::class, 'dashboard'])->middleware('role:dashboard');
-
If route has permission, intended page will be returned otherwise user is redirected.
How Middleware Works
-
If
Auth::User
not found, homepage is returned. e.g./
-
If permission is null
-
Get the current path info for the request.
$permission = $request->path();
-
Current permission is stored in the session using current path.
\Session::put('current_permission', $permission);
-
MODELS
-
MenuItem
Methode relation Description children one-to-many This method returns submenu items from MenuItem
model. One menuitem can have one or more child items.permissions one-to-many This method returns list of permissions from Permission
model. One menuitem can have one or more permissions.user_roles many-To-many This method returns list of user_roles that belong to MenuItem
. -
Permission
Method relation Description menu_item one-to-many (Inverse) This method return menuitem from MenuItem
model that belongs to permission.type one-to-many (Inverse) This method return permission type which belongs to permission. -
PermissionType
- permission types has been created through seeder.
- These types are "READ", "CREATE", "UPDATE", "DELETE" and "MANAGE".
-
Team
Method relation Description owner one-to-many(Inverse) This method returns user who creates the team. A team can have only one owner. permissions belongToMany This method returns list of permissions from Permission
model that belongs toTeam
.members one-to-many This method returns list of members. A team can have one or more members. user_roles one-to-many This method returns list of user_roles from UserRole
model. Team can have one or more user roles. -
User Role
Method relation Description permissions belongsToMany This method returns list of permissions
fromPermission
model that belong to user_role.menu_items belongsToMany This method returns list of menu_items from MenuItem
belong with user_role.team one-to-many (Inverse) This method returns team which belongs to user role. users one-to-many This method returns list of users from User
model. A user role can one or more users.groups belongsToMany This method returns groups that belong to UserRoleGroup. -
UserRoleGroup
Method relation Description users one-to-many This method returns list of users object. One user role group can have one or more users. user_roles belongsToMany This method returns list of user_roles from UserRole
that belong withUserRoleGroup
model.Teams
Step. 1
-
Team is created with a
user_id
.Team::updateOrCreate(['user_id' => 1]);
Step. 2
- Team owner creates user role.
Step. 3
-
Owner assigns the permission to the created user role.
-
Owner can assign the permission which are accessible by him.
-
Permission
is fetched fromPermission
model to assign permission, -
When owner assigns the permissions, these permissions will sync using following code.
$userRole->permissions()->sync($request['permissions']);
Step. 4
- Team members can be added by using the created user role.
Sidebar Creation
- Use the following class for side bar.
<aside class="sidenav bg-white navbar navbar-vertical navbar-expand-xs border-0 border-radius-xl my-3 fixed-start ms-4 " id="sidenav-main"> <div class="sidenav-header"> <div class="main-menu menu-fixed menu-dark menu-accordion menu-shadow" data-scroll-to-active="true"> <div class="navbar-header bg-white"> <ul class="nav navbar-nav flex-row"> <li class="nav-item mr-auto"> <a class="navbar-brand" href="{{ url('/dashboard') }}"> <div class="brand-logo"></div> <h2 class="brand-text mb-0">Your Project Name</h2> </a> </li> <li class="nav-item nav-toggle"> <a class="nav-link modern-nav-toggle pr-0" data-toggle="collapse" id="sidebar_collapse"><i class="feather icon-x d-block d-xl-none font-medium-4 black toggle-icon"></i><i class="toggle-icon feather icon-disc font-medium-4 d-none d-xl-block collapse-toggle-icon black" data-ticon="icon-disc"></i></a> </li> </ul> </div> <div class="main-menu-content mt-2"> Content of sidebar </div> </div> </div> </aside>
Content of sidebar
-
Sidebar is created using the permissions which are assigned.
-
If the user_role is authenticated.
- Loop begins and checks if user has permission to access the menuitem.
- Name of menu item appears on the sidebar.
-
Request::is
checks if the incoming request matches to the menuitem route then item becomes active.Request::is(strtolower(str_replace('/','',$menuItem['route'])))
-
If any menu item has submenu item, it will be opened after matching the request.
-
If user has permission to access menuitem, the loop starts and matching submenu item becomes active.
<ul class="navigation navigation-main" id="main-menu-navigation" data-menu="menu-navigation"> @if(Auth::user()['user_role']) @foreach(Auth::user()['user_role']->menu_items()->orderBy('order_number', 'ASC')->get() as $menuItem) @if (Auth::user()->hasPermissionMenuItem($menuItem['id'])) @if ($menuItem['show_on_sidebar']) @if($menuItem['heading']) <li class="navigation-header"> {{$menuItem['heading']}} </li> @endif @if (count($menuItem['children']) == 0) @if($menuItem['parent_id'] === 0) <li class="nav-item {{ Request::is(strtolower(str_replace('/','',$menuItem['route']))) || Request::is(strtolower(str_replace('/','',$menuItem['route'])).'/*')?'active':'' }}"> <a href="{{ url($menuItem['route']) }}"> <i class="{{ $menuItem['icon'] }}"></i> <span class="menu-title" data-i18n="{{ $menuItem['name'] }}">{{ $menuItem['name'] }}</span> </a> </li> @endif @else <li class="nav-item has-sub {{ Request::is(strtolower(str_replace(' ','_',str_replace('/','',$menuItem['route']))).'/*') && (Auth::user()->sidebar_collapse == 0)? 'open' :'' }}"> <a href="#"><i class="{{ $menuItem['icon'] }}"></i> <span class="menu-title" data-i18n="{{ $menuItem['name'] }}">{{ $menuItem['name'] }}</span> </a> <ul class="menu-content"> @foreach($menuItem['children'] as $child) @if (Auth::user()->hasPermissionMenuItem($child['id'])) <li class="nav-item {{ Request::is(strtolower(str_replace(' ','_',$child['name']))) || Request::is('*/'.strtolower(str_replace(' ','_',$child['name'])))?'active':'' }}"> <a href="{{ url($child['route']) }}"><i class="{{ $child['icon'] }}"></i><span class="menu-item" data-i18n="{{ $child['name'] }}">{{ $child['name'] }}</span></a> </li> @endif @endforeach </ul> </li> @endif @endif @endif @endforeach @endif </ul>