.
Create a Fresh Laravel Project
Composer create-project Laravel/Laravel ProjectName
Make a database and connect with your Laravel project in .ENV File
Run migration
php artisan migrate
Now Installing Laravel Breeze
composer require laravel/breeze –dev
php artisan breeze:install
//Enter “blade”
//Yes
//0
Php artisan migrate
Npm install
Npm run dev
Now Start Work on Spatie for Roles and Permissions
Composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
Now Run Any OF Following Command
Php artisan optimize:clear
OR
Php artisan config:clear
Now
Php artisan migrate
Step 6:
Now Making Permission Start From Here
Php artisan make:controller PermissionController
Now in PermissionsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Spatie\Permission\Models\Permission;
class PermissionController extends Controller
{
// This Method Will Show Permission Page
public function index()
{
$permissions=Permission::orderBy('created_at','DESC')->paginate(2);
return view('Permission.list',[
'permissions'=>$permissions
]);
}
// This Method Will Show Create Permission Page
public function create()
{
return view('permission.create');
}
// This Method Will Store Permission
public function store(Request $request)
{
$validator=Validator::make($request->all(),[
'name'=>'required|unique:permissions|min:3',
]);
if($validator->passes())
{
Permission::create([
'name'=>$request->name
]);
return redirect()->route('permissions.index')->with('success','Permission Added Successfully');
}
else
{
return redirect()->route('permissions.create')->withInput()->withErrors($validator);
}
}
// This Method Will find updated Record
public function edit($id)
{
$permission=Permission::findOrFail($id);
return view('Permission.edit',[
'permission'=>$permission
]);
}
// This Method Will update Permission
public function update($id,Request $request)
{
$permission=Permission::findOrFail($id);
$validator=Validator::make($request->all(),[
'name'=>'required|min:3|unique:permissions,name,'.$id.',id',
]);
if($validator->passes())
{
$permission->name=$request->name;
$permission->save();
return redirect()->route('permissions.index')->with('success','Permission Updated Successfully');
}
else
{
return redirect()->route('permissions.edit',$id)->withInput()->withErrors($validator);
}
}
// This Method Will Destroy Permission
public function destroy(Request $request)
{
$id=$request->id;
$permission=Permission::find($id);
if($permission == null)
{
session()->flash('error','Permission not found');
return response()->json([
'status'=>false
]);
}
$permission->delete();
session()->flash('success','Permission Deleted Successfully');
return response()->json([
'status'=>true
]);
}}
Now Goto Resources>View and Make Folder Permissions and Make the Following Files init
Create.blade.php
List.blade.php
Edit.blade.php
Now Creare.blade.php code
Now in Create.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{--{{ __('Permissions') }}--}}
Permissions/Create
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('permissions.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">
<form action="{{route('permissions.store')}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name')}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
And list.blade.php code
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Permissions') }}
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('permissions.create')}}">Create Permission</a>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<x-message></x-message>
<table class="w-full">
<thead class="bg-gray-50">
<tr class="border-b">
<td class="px-6 py-3 text-left" width="60">#</td>
<td class="px-6 py-3 text-left">Name</td>
<td class="px-6 py-3 text-left" width="180" >Created</td>
<td class="px-6 py-3 text-center" width="180">Action</td>
</tr>
</thead>
<tbody class="bg-white">
@if($permissions->isNotEmpty())
@foreach($permissions as $permission)
<tr class="border-b">
<td class="px-6 py-3 text-left">{{$permission->id}}</td>
<td class="px-6 py-3 text-left">{{$permission->name}}</td>
<td class="px-6 py-3 text-left">
{{--{{$permission->created_at}}--}}
{{--And We Can Get Date in our desire format--}}
{{\Carbon\Carbon::parse($permission->created_at)->format('d M, Y')}}
</td>
<td class="px-6 py-3 text-center">
<a href="{{route('permissions.edit',$permission->id)}}" class="bg-slate-700 text-sm rounded-md text-white px-3 py-2 hover:bg-slate-600">Edit</a>
<a href="javascript:void(0);" onclick="deletePerission({{$permission->id}})" class="bg-red-700 text-sm rounded-md text-white px-3 py-2 hover:bg-red-600">Delete</a>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
{{$permissions->links()}}
</div>
</div>
<x-slot name="script">
{{--JS Code Come Here--}}
<script type="text/javascript">
function deletePerission(id){
if(confirm("Are you sure you want to delete?")){
$.ajax({
url:'{{route('permissions.destroy')}}',
type:'delete',
data:{id:id},
dataType:'json',
headers:{
'x-csrf-token' : '{{csrf_token()}}'
},
success:function(response){
window.location.href='{{route('permissions.index')}}';
}
});
}
}
</script>
</x-slot>
</x-app-layout>
Edit.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{--{{ __('Permissions') }}--}}
Permissions/Edit
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('permissions.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">
<form action="{{route('permissions.update',$permission->id)}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name',$permission->name)}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<button class="bg-slate-700 hover:bg-slate-600 text-sm rounded-md text-white px-5 py-3">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Now Roles Controller
Php artisan make:controller RolesController - r
Roles Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class RoleController extends Controller
{
// This Method Will Show Permission Page
public function index()
{
$roles=Role::orderBy('name','ASC')->paginate(10);
return view('roles.list',[
'roles'=>$roles
]);
}
// This Method Will Show Create Permission Page
public function create()
{
$permissions=Permission::orderBy('name','desc')->get();
return view('Roles.create',[
'permissions'=>$permissions
]);
}
// This Method Will Store Permission
public function store(Request $request)
{
$validator=Validator::make($request->all(),[
'name'=>'required|unique:roles|min:3',
]);
if($validator->passes())
{
$role = Role::create([
'name'=>$request->name
]);
if(!empty($request->permission)){
foreach ($request->permission as $name){
$role->givePermissionTo($name);
}
}
return redirect()->route('roles.index')->with('success','Role Added Successfully');
}
else
{
return redirect()->route('roles.create')->withInput()->withErrors($validator);
}
}
// This Method Will find updated Record
public function edit($id)
{
$role=Role::findOrFail($id);
$haspermissions = $role->permissions->pluck('name');
$permissions=Permission::orderBy('name','ASC')->get();
return view('Roles.edit',[
'permissions'=>$permissions,
'haspermissions'=>$haspermissions,
'role'=>$role
]);
}
// This Method Will update Permission
public function update($id,Request $request)
{
$role=Role::findOrFail($id);
$validator=Validator::make($request->all(),[
'name'=>'required|min:3|unique:roles,name,'.$id.',id',
]);
if($validator->passes())
{
$role->name=$request->name;
$role->save();
if(!empty($request->permission)){
$role->syncPermissions($request->permission);
}
else{
$role->syncPermissions([]);
}
return redirect()->route('roles.index')->with('success','Role Updated Successfully');
}
else
{
return redirect()->route('roles.edit',$id)->withInput()->withErrors($validator);
}
}
// This Method Will Destroy Permission
public function destroy(Request $request)
{
$id=$request->id;
$role= Role::find($id);
if($role == null){
session()->flash('error','Role Not Found');
return response()->json([
'status'=>false
]);
}
$role->delete();
session()->flash('success','Role Deleted successfully');
return response()->json([
'status'=>true
]);
}
}
Roles Folder all blades
List.blade
Create.blade
Edit.blade
Create.Blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Role/Create
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('permissions.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">
<form action="{{route('roles.store')}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name')}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="grid grid-cols-4 mb-3">
@if($permissions->isNotEmpty())
@foreach($permissions as $permission)
<div class="mt-3">
<input type="checkbox" id="permission-{{$permission->id}}" class="rounded" name="permission[]"
value="{{$permission->name}}">
<label for="permission-{{$permission->id}}">{{$permission->name}}</label>
</div>
@endforeach
@endif
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
List.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Roles') }}
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('roles.create')}}">Create Roles</a>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<x-message></x-message>
<table class="w-full">
<thead class="bg-gray-50">
<tr class="border-b">
<td class="px-6 py-3 text-left" width="60">#</td>
<td class="px-6 py-3 text-left">Name</td>
<td class="px-6 py-3 text-left">Permissions</td>
<td class="px-6 py-3 text-left" width="180" >Created</td>
<td class="px-6 py-3 text-center" width="180">Action</td>
</tr>
</thead>
<tbody class="bg-white">
@if($roles->isNotEmpty())
@foreach($roles as $role)
<tr class="border-b">
<td class="px-6 py-3 text-left">{{$role->id}}</td>
<td class="px-6 py-3 text-left">{{$role->name}}</td>
<td class="px-6 py-3 text-left">
{{$role->permissions->pluck('name')->implode(', ')}}
</td>
<td class="px-6 py-3 text-left">
{{--{{$role->created_at}}--}}
{{--And We Can Get Date in our desire format--}}
{{\Carbon\Carbon::parse($role->created_at)->format('d M, Y')}}
</td>
<td class="px-6 py-3 text-center">
<a href="{{route('roles.edit',$role->id)}}" class="bg-slate-700 hover:bg-slate-500 text-sm rounded-md text-white px-3 py-2 hover:bg-slate-600">Edit</a>
<a href="javascript:void(0);" onclick="deleteRole({{$role->id}})" class="bg-red-700 text-sm rounded-md text-white px-3 py-2 hover:bg-red-600">Delete</a>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
{{$roles->links()}}
</div>
</div>
<x-slot name="script">
{{--JS Code Come Here--}}
<script type="text/javascript">
function deleteRole(id){
if(confirm("Are you sure you want to delete?")){
$.ajax({
url:'{{route('roles.destroy')}}',
type:'delete',
data:{id:id},
dataType:'json',
headers:{ 'x-csrf-token' : '{{csrf_token()}}'
},
success:function(response){
window.location.href='{{route('roles.index')}}';
}
});
}
}
</script>
</x-slot>
</x-app-layout>
Edit.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Role/Edit
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('roles.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">
<form action="{{route('roles.update',$role->id)}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name',$role->name)}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="grid grid-cols-4 mb-3">
@if($permissions->isNotEmpty())
@foreach($permissions as $permission)
<div class="mt-3">
<input {{ ($haspermissions->contains($permission->name)) ? 'checked' : '' }} type="checkbox" id="permission-{{$permission->id}}" class="rounded" name="permission[]"
value="{{$permission->name}}">
<label for="permission-{{$permission->id}}">{{$permission->name}}</label>
</div>
@endforeach
@endif
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Now go to resources component and make a file message.blade.php
@if(Session::has('success'))
<div class="bg-green-200 border-green-600 p-4 mb-3 rounded-sm shadow-sm">
{{Session::get('success')}}
</div>
@endif
@if(Session::has('error'))
<div class="bg-red-200 border-red-600 p-4 mb-3 rounded-sm shadow-sm">
{{Session::get('red')}}
</div>
@endif
Now in App.blade.php
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
@isset($script)
{{$script}}
@endisset
</html>
Article Module Start From Here
Make a Article Module and Migration
php artisan make:model Article -m
Now in Article Migration
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('text')->nullable();
$table->string('author');
$table->timestamps();
Now Make Article Controller
php artisan make:controller ArticleController –r
And Article Model
protected $fillable = [
'title',
'text',
'author',
];
Now make a Folder Article in Resources and create following files
List.blade
Create.blade
Edit.blade
Create.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{--{{ __('Permissions') }}--}}
Article/Create
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('articles.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">
<form action="{{route('articles.store')}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Title</label>
<div class="my-3">
<input value="{{old('title')}}" name="title" placeholder="title" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('title')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<label for="" class="text-lg font-medium">Content</label>
<div class="my-3">
<textarea name="text" placeholder="Content" id="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">{{old('text')}}</textarea>
</div>
<label for="" class="text-lg font-medium">Author</label>
<div class="my-3">
<input value="{{old('author')}}" name="author" placeholder="Author" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('author')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
List.blade
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Articles') }}
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('articles.create')}}">Create Article</a>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<x-message></x-message>
<table class="w-full">
<thead class="bg-gray-50">
<tr class="border-b">
<td class="px-6 py-3 text-left" width="60">#</td>
<td class="px-6 py-3 text-left">Title</td>
<td class="px-6 py-3 text-left">Author</td>
<td class="px-6 py-3 text-left" width="180" >Created</td>
<td class="px-6 py-3 text-center" width="180">Action</td>
</tr>
</thead>
<tbody class="bg-white">
@if($articles->isNotEmpty())
@foreach($articles as $article)
<tr class="border-b">
<td class="px-6 py-3 text-left">{{$article->id}}</td>
<td class="px-6 py-3 text-left">{{$article->title}}</td>
<td class="px-6 py-3 text-left">{{$article->author}}</td>
<td class="px-6 py-3 text-left">
{{--{{$permission->created_at}}--}}
{{--And We Can Get Date in our desire format--}}
{{\Carbon\Carbon::parse($article->created_at)->format('d M, Y')}}
</td>
<td class="px-6 py-3 text-center">
<a href="{{route('articles.edit',$article->id)}}" class="bg-slate-700 text-sm rounded-md text-white px-3 py-2 hover:bg-slate-600">Edit</a>
<a href="javascript:void(0);" onclick="deleteArticle({{$article->id}})" class="bg-red-700 text-sm rounded-md text-white px-3 py-2 hover:bg-red-600">Delete</a>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
{{$articles->links()}}
</div>
</div>
<x-slot name="script">
{{--JS Code Come Here--}}
<script type="text/javascript">
function deleteArticle(id){
if(confirm("Are you sure you want to delete?")){
$.ajax({
url:'{{route('articles.destroy')}}',
type:'delete',
data:{id:id},
dataType:'json',
headers:{
'x-csrf-token' : '{{csrf_token()}}'
},
success:function(response){
window.location.href='{{route('articles.index')}}';
}
});
}
}
</script>
</x-slot>
</x-app-layout>
Edit.Blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Article/Edit
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('articles.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">
<form action="{{route('articles.update',$article->id)}}" method="post">
@csrf
<div>
<label for="" class="text-lg font-medium">Title</label>
<div class="my-3">
<input value="{{old('title',$article->title)}}" name="title" placeholder="title" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('title')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<label for="" class="text-lg font-medium">Content</label>
<div class="my-3">
<textarea name="text" placeholder="Content" id="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">{{old('text',$article->text)}}</textarea>
</div>
<label for="" class="text-lg font-medium">Author</label>
<div class="my-3">
<input value="{{old('author',$article->author)}}" name="author" placeholder="Author" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('author')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Article Controller
<?php
namespace App\Http\Controllers;
use App\Models\Article;
//use Dotenv\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ArticleController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$articles=Article::latest()->paginate(25);
return view('article.list',[
'articles'=>$articles
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('Article.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$validator=Validator::make($request->all(),[
'title'=>'required|min:5',
'author'=>'required|min:5',
]);
if($validator->passes()){
$article=new Article();
$article->title=$request->title;
$article->text=$request->text;
$article->author=$request->author;
$article->save();
return redirect()->route('articles.index')->with('success','Article Added Successfully');
}
else
{
return redirect()->route('articles.create')->withInput()->withErrors($validator);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$article=Article::findOrFail($id);
return view('article.edit',[
'article'=>$article
]);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$article=Article::findOrFail($id);
$validator=Validator::make($request->all(),[
'title'=>'required|min:5',
'author'=>'required|min:5',
]);
if($validator->passes())
{
$article->title=$request->title;
$article->text=$request->text;
$article->author=$request->author;
$article->save();
return redirect()->route('articles.index')->with('success','Article Updated Successfully');
}
else
{
return redirect()->route('articles.edit',$id)->withInput()->withErrors($validator);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Request $request)
{
$id=$request->id;
$article=Article::find($id);
if($article == null)
{
session()->flash('error','Article not found');
return response()->json([
'status'=>false
]);
}
$article->delete();
session()->flash('success','Article Deleted Successfully');
return response()->json([
'status'=>true
]);
}
}
Now In Users Model and Assigining Roles to User
php artisan make:controller UserController –r
in User Model
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, HasRoles;//Just add HasRoles Here
UserController
<?php
namespace App\Http\Controllers;
use App\Models\User;
//use Dotenv\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Role;
use Illuminate\Support\Facades\Validator;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
class UserController extends Controller implements HasMiddleware
{
public static function middleware(): array
{
return[
new Middleware('permission:view users', only: ['index']),
new Middleware('permission:edit users', only: ['edit']),
/*new Middleware('permission:create users', only: ['create']),*/
/*new Middleware('permission:delete users', only: ['destroy']),*/
];
}
/**
* Display a listing of the resource.
*/
public function index()
{
$users=User::latest()->paginate(10);
return view('Users.list',[
'users'=>$users
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$roles = Role::orderBy('name','ASC')->get();
return view('Users.create',[
'roles'=>$roles
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$validator=Validator::make($request->all(),[
'name'=>'required|min:3',
'email'=>'required|email|unique:users,email',
'password'=>'required|min:5|same:confirm_password',
'confirm_password'=>'required'
]);
if($validator->fails())
{
return redirect()->route('users.create')->withInput()->withErrors($validator);
}
$user=new User();
$user->name=$request->name;
$user->email=$request->email;
$user->password=Hash::make($request->password);
$user->save();
$user->syncRoles($request->role);
return redirect()->route('users.index')->with('success','User Created Successfully');
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$user = User::findOrFail($id);
$roles=Role::orderBy('name','ASC')->get();
$hasRoles=$user->roles->pluck('id');
return view('users.edit',[
'user'=>$user,
'roles'=>$roles,
'hasRoles'=>$hasRoles
]);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$user= User::findOrFail($id);
$validator=Validator::make($request->all(),[
'name'=>'required|min:3',
'email'=>'required|email|unique:users,email,'.$id.',id'
]);
if($validator->fails())
{
return redirect()->route('users.edit',$id)->withInput()->withErrors($validator);
}
$user->name=$request->name;
$user->email=$request->email;
$user->save();
$user->syncRoles($request->role);
return redirect()->route('users.index')->with('success','User Updated Successfully');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Request $request)
{
$user=User::find($request->id);
if($user == null)
{
session()->flash('error','User not found');
return response()->json([
'status'=>false
]);
}
$user->delete();
session()->flash('success','User Deleted Successfully');
return response()->json([
'status'=>true
]);
}
}
And Now Make a Folder User and Following Files
List.blade
Create.blade
Edit.blade
List.blade
<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="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('users.create')}}">Create User</a>
</div>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<x-message></x-message>
<table class="w-full">
<thead class="bg-gray-50">
<tr class="border-b">
<td class="px-6 py-3 text-left" width="60">#</td>
<td class="px-6 py-3 text-left">Name</td>
<td class="px-6 py-3 text-left">Email</td>
<td class="px-6 py-3 text-left">Roles</td>
<td class="px-6 py-3 text-left" width="180" >Created</td>
<td class="px-6 py-3 text-center" width="180">Action</td>
</tr>
</thead>
<tbody class="bg-white">
@if($users->isNotEmpty())
@foreach($users as $user)
<tr class="border-b">
<td class="px-6 py-3 text-left">{{$user->id}}</td>
<td class="px-6 py-3 text-left">{{$user->name}}</td>
<td class="px-6 py-3 text-left">{{$user->email}}</td>
<td class="px-6 py-3 text-left">{{$user->roles->pluck('name')->implode(', ')}}</td>
<td class="px-6 py-3 text-left">
{{--And We Can Get Date in our desire format--}}
{{\Carbon\Carbon::parse($user->created_at)->format('d M, Y')}}
</td>
<td class="px-6 py-3 text-center">
<a href="{{route('users.edit',$user->id)}}" class="bg-slate-700 hover:bg-slate-500 text-sm rounded-md text-white px-3 py-2 hover:bg-slate-600">Edit</a>
<a href="javascript:void(0);" onclick="deleteUser({{$user->id}})" class="bg-red-700 text-sm rounded-md text-white px-3 py-2 hover:bg-red-600">Delete</a>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
{{$users->links()}}
</div>
</div>
<x-slot name="script">
{{--JS Code Come Here--}}
<script type="text/javascript">
function deleteUser(id){
if(confirm("Are you sure you want to delete?")){
$.ajax({
url:'{{route('users.destroy')}}',
type:'delete',
data:{id:id},
dataType:'json',
headers:{
'x-csrf-token' : '{{csrf_token()}}'
},
success:function(response){
window.location.href='{{route('users.index')}}';
}
});
}
}
</script>
</x-slot>
</x-app-layout>
Edit.blade.php
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
User/Edit
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('users.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">
<form action="{{route('users.update',$user->id)}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name',$user->name)}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="my-3">
<input value="{{old('email',$user->email)}}" name="email" placeholder="Enter Email" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('email')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="grid grid-cols-4 mb-3">
@if($roles->isNotEmpty())
@foreach($roles as $role)
<div class="mt-3">
<input {{$hasRoles->contains($role->id) ? 'checked' : ''}} type="checkbox" id="role-{{$role->id}}" class="rounded" name="role[]"
value="{{$role->name}}">
<label for="role-{{$role->id}}">{{$role->name}}</label>
</div>
@endforeach
@endif
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Create.blade
<x-app-layout>
<x-slot name="header">
<div class="flex justify-between">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
User/Create
</h2>
<a class="bg-slate-700 text-sm rounded-md text-white px-3 py-2" href="{{route('users.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">
<form action="{{route('users.store')}}" method="post" >
@csrf
<div>
<label for="" class="text-lg font-medium">Name</label>
<div class="my-3">
<input value="{{old('name')}}" name="name" placeholder="Enter Name" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('name')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="my-3">
<input value="{{old('email')}}" name="email" placeholder="Enter Email" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('email')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="my-3">
<input value="{{old('password')}}" name="password" placeholder="Enter Password" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('password')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="my-3">
<input value="{{old('confirm_password')}}" name="confirm_password" placeholder="Enter Confirm Password" type="text" class="border-grey-300 shadow-sm w-1/2 rounded-lg">
@error('confirm_password')
<p class="text-red-400 font-medium">{{$message}}</p>
@enderror
</div>
<div class="grid grid-cols-4 mb-3">
@if($roles->isNotEmpty())
@foreach($roles as $role)
<div class="mt-3">
<input type="checkbox" id="role-{{$role->id}}" class="rounded" name="role[]"
value="{{$role->name}}">
<label for="role-{{$role->id}}">{{$role->name}}</label>
</div>
@endforeach
@endif
</div>
<button class="bg-slate-700 text-sm rounded-md text-white px-5 py-3">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Now Goto Bootstrap→app.php and add the following lines of code
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
})
In Article Controller
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
class ArticleController extends Controller implements HasMiddleware(Just imoplement Has Middleware)
public static function middleware(): array
{
return[
new Middleware('permission:view articles', only: ['index']),
new Middleware('permission:edit articles', only: ['edit']),
new Middleware('permission:create articles', only: ['create']),
new Middleware('permission:delete articles', only: ['destroy']),
];
}
Now Use the Same in Every Controller Where you want to give permission
Now Working on links the link hide which permission is not given like if you did not have access to delete post so the delete post link must not be shown you
@can('view permission')
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('permissions.index')" :active="request()->routeIs('permissions.index')">
{{ __('Permissions') }}
</x-nav-link>
</div>
@endcan
Now i you want to check show user role
{{Auth::user()->name}}({{Auth::user()->roles->pluck(‘Name’)->implode(‘, ‘)}})
Now if we want to make a super admin so we dont need to give permission to super admin it will get all access automatically
Goto App→Providers→AppServiceProvider
Gate::before(function ($user,$ability){
return $user->hasRole('superadmin') ? true :null;
});
Now make a role superadmin and he has access to all assets
Web.php
<?php
use App\Http\Controllers\PermissionController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\ArticleController;
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
// Permissions
Route::get('/permissions', [PermissionController::class, 'index'])->name('permissions.index');
Route::get('/permissions/create', [PermissionController::class, 'create'])->name('permissions.create');
Route::post('/permissions', [PermissionController::class, 'store'])->name('permissions.store');
Route::get('/permissions/{id}/edit', [PermissionController::class, 'edit'])->name('permissions.edit');
Route::post('/permissions/{id}', [PermissionController::class, 'update'])->name('permissions.update');
Route::delete('/permissions/delete', [PermissionController::class, 'destroy'])->name('permissions.destroy');
// Roles
Route::get('/roles', [RoleController::class, 'index'])->name('roles.index');
Route::get('/roles/create', [RoleController::class, 'create'])->name('roles.create');
Route::post('/roles', [RoleController::class, 'store'])->name('roles.store');
Route::get('/roles/{id}/edit', [RoleController::class, 'edit'])->name('roles.edit');
Route::post('/roles/{id}', [RoleController::class, 'update'])->name('roles.update');
Route::delete('/roles/delete', [RoleController::class, 'destroy'])->name('roles.destroy');
// Article
Route::get('/articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('/articles/create', [ArticleController::class, 'create'])->name('articles.create');
Route::post('/articles', [ArticleController::class, 'store'])->name('articles.store');
Route::get('/articles/{id}/edit', [ArticleController::class, 'edit'])->name('articles.edit');
Route::post('/articles/{id}', [ArticleController::class, 'update'])->name('articles.update');
Route::delete('/articles/delete', [ArticleController::class, 'destroy'])->name('articles.destroy');
/*Users Routes*/
Route::get('/users', [userController::class, 'index'])->name('users.index');
Route::get('/users/create', [userController::class, 'create'])->name('users.create');
Route::post('/users', [userController::class, 'store'])->name('users.store');
Route::get('/users/{id}/edit', [userController::class, 'edit'])->name('users.edit');
Route::post('/users/{id}', [userController::class, 'update'])->name('users.update');
Route::delete('/users/delete', [userController::class, 'destroy'])->name('users.destroy');
});
require __DIR__.'/auth.php';
Resources→Views→Layout→navigation.blade
@can('view permission')
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('permissions.index')" :active="request()->routeIs('permissions.index')">
{{ __('Permissions') }}
</x-nav-link>
</div>
@endcan
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('roles.index')" :active="request()->routeIs('roles.index')">
{{ __('Roles') }}
</x-nav-link>
</div>
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('articles.index')" :active="request()->routeIs('articles.index')">
{{ __('Articles') }}
</x-nav-link>
</div>
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('users.index')" :active="request()->routeIs('users.index')">
{{ __('Users') }}
</x-nav-link>
</div>