আজকের ক্লাসে আমাদের permission নিয়ে আলোচনা করা হবে যদিও এর আগেও কিছু আলোচনা করা হয়েছে। যেহেতু এটা একটা lms project সুতরাং এখানে permission এর অনেক বিষয় আছে যেগুলো থেকে আমরা অনেক ভালো ধারনা নিতে পারব।
আমরা কি কি করবো আজকেরর ক্লাসে ।
-বিভিন্ন রোল আলাদা আলাদা ভাবে তৈরি করে সেগুলো কে access দেব।
-ভিন্ন ভিন্ন ইউজারের ভিন্ন ভিন্ন পেইজ থাকবে এবং অন্য ইউজার এখানে ভিজিটর হিসেবে ভিসিট করতে পারবে কিন্তু কোন অপারেশন চালাতে পারবে না।
-role-management সুপার admin বিভিন্ন রোল তৈরি করতে পারবে।
-আরো অনেক কিছু যা আমরা প্রজেক্ট করতে করতে আলোচনা করব।
তো প্রথমেই আমরা একটা controller তৈরি করব ।
php artisan make:controller UserController -resource
এবার আমরা একটা রাউট তৈরি করব আমাদের web.php file এ
Route::resource('user', UserController::class);
এবং আমাদের Lead যে ফোল্ডার টা আছে সেটা duplicate করে সেটার নাম User দেব।
এবার কাজ আমাদের controller এর মধ্যে।
controller এর মধ্যে আমরা প্রথমেই
index
create
edit
এই function গুলোর মধ্যে permisson_check যে function লিখেছিলাম সেটা দিয়ে চেক করব।
public function index()
{
//
permission_check('user-management');
return view('user.index');
}
public function create()
{
//
permission_check('user-management');
return view('user.create');
}
public function edit($id)
{
//
permission_check('user-management');
return view('user.edit');
}
এবার আমাদের এটা যেহেতু livewire এ dynamic হবে তাই আমাদের একটা UserIndex লাগবে।
php artisan livewire:make UserIndex
আমাদের userIndex তৈরি হয়ে গেলে আমরা আমাদের navigation file এ profile এর নিচে users নামের একটা বাটন দেব যেটা কেবল super-admin এর কাছেই visible থাকবে ।
@can ('user-management')
<x-dropdown-link :href="route('user.index')">
{{ __('Users') }}
</x-dropdown-link>
@endcan
এবার আমাদের user folder এর মধ্যে index file টা আছে সেখানে Roles & add new user এর বাটন দেব।
এবার আমাদের form handling userfield এ একটা livewire components লাগবে।
php artisan livewire:make UserCreate
এবং আমাদের user এর মধ্যে index file টা কে copy করে আমরা সেটাকে create.blade.php তৈরি করব এবং আমরা এখানে যা যা add করতে চাই সেগুলো লিখবো।
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Users') }}
</h2>
<a class="lms-btn" href="{{route('user.index')}}">Back</a>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<livewire:user-create />
</div>
</div>
</div>
</div>
</x-app-layout>
এবার আমাদের role management এর জন্য একটা controller প্রয়োজন
php artisan make:controller RoleController --resource
এবার আমাদের user এর মধ্যে একটা ফোল্ডার তৈরি করতে হবে role name এর এবং এখানে আমরা আমাদের user folder এর ফাইল গুলো কপি করব ।
এবার আমাদের RoleController এর মধ্যে function গুলোতে আমাদের ভিউ গুলো দিয়ে দিতে হবে।
public function index()
{
//
return view('user.role.index');
}
public function create()
{
//
return view('user.role.create');
}
public function edit($id)
{
//
return view('user.role.edit');
}
এবার এগুলো dynamic করার জন্য আমরা আমাদের livewire components তৈরি করব।
php artisan livewire:make RoleIndex
php artisan livewire:make RoleCreate
php artisan livewire:make RoleEdit
এবং ফাইলগুলো তে রাউট ভাল ভাবে সেট করে দেব।
role folder এর index
<x-app-layout>
<x-slot name="header">
<div class="flex items-center justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Roles') }}
</h2>
<div class="flex items-center">
<a class="lms-btn" href="{{route('role.create')}}">Add new role</a>
</div>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<livewire:role-index />
</div>
</div>
</div>
</div>
</x-app-layout>
এবার আমরা আমাদের livewire এর roleindex file এর টেবিল এর মার্ক আপ দিয়ে সেটা dynamic করব।
<div>
<table class="w-full table-auto">
<tr>
<th class="border px-4 py-2 text-left">Name</th>
<th class="border px-4 py-2 text-left">Permissions</th>
<th class="border px-4 py-2">Actions</th>
</tr>
@foreach($roles as $role)
<tr>
<td class="border px-4 py-2">{{$role->name}}</td>
<td class="border px-4 py-2">
@foreach($role->permissions as $permission)
<span class="px-2 py-1 bg-blue-400 text-white rounded text-sm">{{$permission->name}}</span>
@endforeach
</td>
<td class="border px-4 py-2 text-center">
<div class="flex items-center justify-center">
<a class="mr-1" href="{{route('role.edit', $role->id)}}">
@include('components.icons.edit')
</a>
<form class="ml-1" onsubmit="return confirm('Are you sure?');" wire:submit.prevent="roleDelete({{$role->id}})">
<button type="submit">
@include('components.icons.trash')
</button>
</form>
</div>
</td>
</tr>
@endforeach
</table>
</div>
এবং আমাদের RoleIndex.php file এর মধ্যে আমরা কোড লিখবো রোল গুলো শো করানোর জন্য।
public function render()
{
$roles = Role::where('name', '!=', 'Super Admin')->get();
return view('livewire.role-index', [
'roles' => $roles
]);
}
এবার রোলের জন্য আমাদের role-create file এ আমাদের কোড লিখতে হবে।
<form wire:submit.prevent="formSubmit">
<div class="mb-4">
<label for="name" class="lms-label">Name</label>
<input wire:model.lazy="name" id="name" type="text" class="lms-input">
@error('name')
<div class="text-red-500 text-sm mt-2">{{ $message }}</div>
@enderror
</div>
<h3 class="font-semibold mb-2">Permissions</h3>
<div class="flex flex-wrap -mx-4">
@foreach($permissions as $permission)
<div class="w-1/3 px-4 mb-4">
<label class="inline-flex items-center">
<input wire:model.lazy="selectedPermissions" type="checkbox" class="form-checkbox" value="{{$permission->name}}">
<span class="ml-2">{{$permission->name}}</span>
</label>
</div>
@endforeach
@error('selectedPermissions')
<div class="text-red-500 text-sm mt-2 px-4 mb-4">{{ $message }}</div>
@enderror
</div>
@include('components.wire-loading-btn')
</form>
এবং এখন আমরা আমাদের RoleCreate.php file এ প্রয়োজনীয় কোড করতে হবে।
public $selectedPermissions = [];
public $name;
public function render()
{
$permissions = Permission::all();
return view('livewire.role-create', [
'permissions' => $permissions
]);
}
protected $rules = [
'name' => 'required|unique:roles,name',
'selectedPermissions' => 'required|array|min:1',
];
public function formSubmit() {
$this->validate();
$role = Role::create(['name' => $this->name]);
$role->syncPermissions($this->selectedPermissions);
flash()->addSuccess('Role created successfully');
return redirect()->route('role.index');
}
এখানে আমরা কয়েকটি কাজ করেছি।
প্রথমেই আমরা $selectedPermissions কে array এর মধ্যে নিয়েছি।
এবং আমাদের যে name use করেছিলাম সেটাকেও এখানে public করেছি।
এরপর আমরা $permissions variable এ সব permisson গুলো কে নিয়েছি।
এবং permissions নামের variable এ পাঠিয়েছি।
এরপর আমরা validate করেছি। $rules কে protected করে।
এবং finally আমরা আমাদের যে ম্থড নাম formSubmit দিয়েছিলাম সেটাকে function এর নাম দিয়ে আমাদের role তৈরি করার প্রসেস গুলো করে flasher add করে দিয়েছি।
এবার আসি আমাদের ইউজার create এ কিইভাবে আমরা সেটা করতে পারি।
প্রথমেই আমাদে যে user-create view file টা আছে সেখানে আমাদের user make করতে কি কি লাগে সেগুলো কোড করতে হবে।
<form wire:submit.prevent="submitForm">
<div class="flex -mx-4 mb-4">
<div class="flex-1 px-4">
<label for="name" class="lms-label">Name</label>
<input wire:model.lazy="name" id="name" type="text" class="lms-input">
@error('name')
<div class="text-red-500 text-sm mt-2">{{ $message }}</div>
@enderror
</div>
<div class="flex-1 px-4">
<label for="email" class="lms-label">Email</label>
<input wire:model.lazy="email" id="email" type="email" class="lms-input">
@error('email')
<div class="text-red-500 text-sm mt-2">{{ $message }}</div>
@enderror
</div>
<div class="flex-1 px-4">
<label for="password" class="lms-label">Password</label>
<input wire:model.lazy="password" id="password" type="password" class="lms-input">
@error('password')
<div class="text-red-500 text-sm mt-2">{{ $message }}</div>
@enderror
</div>
</div>
<div class="mb-4">
<label for="role" class="lms-label">Role</label>
<select wire:model.lazy="role" id="role" class="lms-input">
<option value="">Select role</option>
@foreach($roles as $role)
<option value="{{$role->id}}">{{$role->name}}</option>
@endforeach
</select>
@error('role')
<div class="text-red-500 text-sm mt-2">{{ $message }}</div>
@enderror
</div>
@include('components.wire-loading-btn')
</form>
এরপর আমাদের যে livewire Controller টা আছে সেখানে আমাদের ভিউ ফাইল এর রিকোয়ারমেন্ট অনুযায়ী কোড করতে হবে।
public $name;
public $email;
public $password;
public $role;
protected $rules = [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:6',
'role' => 'required',
];
public function render()
{
$roles = Role::all();
return view('livewire.user-create', [
'roles' => $roles
]);
}
public function submitForm() {
$this->validate();
$user = User::create([
'name' => $this->name,
'email' => $this->email,
'password' => Hash::make($this->password),
]);
$user->assignRole($this->role);
flash()->addSuccess('User created successfully');
return redirect()->route('user.index');
}
আশা করি বিষয় গুলো ক্লিয়ার হয়েছেন।একবার না বুঝতে পারলে বার বার পড়েন এবং আমাদের যে ভিডিও টিউটোরিয়াল গুলো আছে সেগুলো দেখেন।
আশা করি বুঝতে পারবেন।এখন হয়তো প্রজেক্ট টা অনেকের ই মাথার ওপর দিয়ে যাবে কারন অনেক advance বিষয় গুলো এখানে রয়েছে তবে ভয় না পেয়ে লেগে থাকলে এখান থেকে অনেক কিছু শেখা সম্ভব। কোড মনে থাকবে না এটা সাভাবিক বিষয় কিন্তু আপনাকে প্রসেস জানতে হবে ।
সে অনুযায়ী practice করতে হবে যেমন টা আমি ব্লগে লিখেছি সেই প্রসেস গুলো মনে রাখবেন আশা করি সব ক্লিয়ার হয়ে যাবে।
Happy Learning
Rakibul Islam