Role Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Role extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'slug',
];
/**
* The users that belong to the Role
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
/**
* The roles that belong to the Role
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function permissions(): BelongsToMany
{
return $this->belongsToMany(Permission::class,'role_permission');
}
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['slug'] = Str::slug($value);
}
}
Role Migration
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
Permission Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Permission extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'slug',
];
/**
* The roles that belong to the Permission
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
/**
* The roles that belong to the Permission
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class,'role_permission');
}
public function setNameAttribute($value)
{
$this->attributes['name'] = $value;
$this->attributes['slug'] = Str::slug($value);
}
}
Permission Migration
Schema::create('permissions', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug');
$table->timestamps();
});
App\Services\HasPermissionsTraits.php
<?php
namespace App\Services;
use App\Permission;
use App\Role;
trait HasPermissionsTrait {
public function givePermissionsTo(... $permissions) {
$permissions = $this->getAllPermissions($permissions);
if($permissions === null) {
return $this;
}
$this->permissions()->saveMany($permissions);
return $this;
}
public function withdrawPermissionsTo( ... $permissions ) {
$permissions = $this->getAllPermissions($permissions);
$this->permissions()->detach($permissions);
return $this;
}
public function refreshPermissions( ... $permissions ) {
$this->permissions()->detach();
return $this->givePermissionsTo($permissions);
}
public function hasPermissionTo($permission) {
return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
}
public function hasPermissionThroughRole($permission) {
foreach ($permission->roles as $role){
if($this->roles->contains($role)) {
return true;
}
}
return false;
}
public function hasRole( ... $roles ) {
foreach ($roles as $role) {
if ($this->roles->contains('slug', $role)) {
return true;
}
}
return false;
}
public function roles() {
return $this->belongsToMany(Role::class,'users_roles');
}
public function permissions() {
return $this->belongsToMany(Permission::class,'users_permissions');
}
protected function hasPermission($permission) {
return (bool) $this->permissions->where('slug', $permission->slug)->count();
}
protected function getAllPermissions(array $permissions) {
return Permission::whereIn('slug',$permissions)->get();
}
}
Create custom provider
php artisan make:provider PermissionsServiceProvider
App\Providers\PermissionsServiceProvider.php
<?php
namespace App\Providers;
use App\Services;
use App\Models\Permission;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
class PermissionsServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
}
/**
* Bootstrap services.
*/
public function boot()
{
try {
Permission::get()->map(function ($permission) {
Gate::define($permission->slug, function ($user) use ($permission) {
return $user->hasPermissionTo($permission);
});
});
} catch (\Exception $e) {
report($e);
return false;
}
//Blade directives
Blade::directive('role', function ($role) {
return "if(auth()->check() && auth()->user()->hasRole({$role})) :"; //return this if statement inside php tag
});
Blade::directive('endrole', function ($role) {
return "endif;"; //return this endif statement inside php tag
});
}
}
Register our provider at Config\App.php
'providers' => ServiceProvider::defaultProviders()->merge([
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\PermissionsServiceProvider::class,
])->toArray(),
Tinker
$u = App\Models\User::where('name','Ghazali Tajuddin')->first()
= App\Models\User {#7268
id: 1,
name: "Ghazali Tajuddin",
email: "ghazali.tajuddin@gmail.com",
email_verified_at: "2023-07-27 06:24:48",
#password: "",
#remember_token: null,
created_at: "2023-07-27 06:24:48",
updated_at: null,
}
$p = App\Models\Permission::where('slug','create-neighbourhood')
->first()
= App\Models\Permission {#7274
id: 19,
name: "Create Neighbourhood",
slug: "create-neighbourhood",
created_at: "2023-07-27 06:24:49",
updated_at: "2023-07-27 06:24:49",
}
$r = App\Models\Role::where('slug','super-admin')->first()
= App\Models\Role {#7283
id: 1,
name: "Super Admin",
slug: "super-admin",
created_at: "2023-07-27 06:24:49",
updated_at: "2023-07-27 06:24:49",
}
//Attach Roles To User
$u->roles()->attach($r)
//Attach Permissions To User
$u->permissions()->attach($p)
//Test if user has permission to "create-neighbourhood" slug
$u->can('create-neighbourhood')
= true
//Test if user has role "super-admin" slug
$u->hasRole('super-admin')
= true
//Test $u
$u
= App\Models\User {#7268
id: 1,
name: "Ghazali Tajuddin",
email: "ghazali.tajuddin@gmail.com",
email_verified_at: "2023-07-27 06:24:48",
#password: "",
#remember_token: null,
created_at: "2023-07-27 06:24:48",
updated_at: null,
permissions: Illuminate\Database\Eloquent\Collection {#7288
all: [
App\Models\Permission {#7291
id: 19,
name: "Create Neighbourhood",
slug: "create-neighbourhood",
created_at: "2023-07-27 06:24:49",
updated_at: "2023-07-27 06:24:49",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#7289
user_id: 1,
permission_id: 19,
},
},
],
},
roles: Illuminate\Database\Eloquent\Collection {#7298
all: [
App\Models\Role {#7293
id: 1,
name: "Super Admin",
slug: "super-admin",
created_at: "2023-07-27 06:24:49",
updated_at: "2023-07-27 06:24:49",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#7276
user_id: 1,
role_id: 1,
},
},
],
},
}
//Get Super Admin Role
$r = App\Models\Role::where('slug','super-admin')->first()
= App\Models\Role {#7268
id: 1,
name: "Super Admin",
slug: "super-admin",
created_at: "2023-07-27 07:17:27",
updated_at: "2023-07-27 07:17:27",
}
//Get role permissions only 'name' attribute
$r->permissions()->pluck('name')
= Illuminate\Support\Collection {#7292
all: [
"Create User",
"Read User",
"Update User",
"Delete User",
"List User",
],
}
//Get Property Residential Id 1 Neighbourhood Record
$pr = App\Models\PropertyResidential::find(1)
->property->street->neighbourhood
= App\Models\Neighbourhood {#7328
id: 1,
name: "Taman Koperasi Guru",
acronym: "tkg",
subdomain: "tkg",
slug: "taman-koperasi-guru",
postcode: "25150",
city: "Kuantan",
state: "Pahang",
resgistrar_id: null,
created_at: null,
updated_at: null,
}
//Get Property Id 1 Neighbourhood Record
$pr = App\Models\Property::find(1)->street->neighbourhood
= App\Models\Neighbourhood {#7328
id: 1,
name: "Taman Koperasi Guru",
acronym: "tkg",
subdomain: "tkg",
slug: "taman-koperasi-guru",
postcode: "25150",
city: "Kuantan",
state: "Pahang",
resgistrar_id: null,
created_at: null,
updated_at: null,
}
//Get property with number(1) neighbourhood record
$pr = App\Models\Property::where('number','1')
->first()->street->neighbourhood
= App\Models\Neighbourhood {#7336
id: 1,
name: "Taman Koperasi Guru",
acronym: "tkg",
subdomain: "tkg",
slug: "taman-koperasi-guru",
postcode: "25150",
city: "Kuantan",
state: "Pahang",
resgistrar_id: null,
created_at: null,
updated_at: null,
}
//Get Property Id(1) Neighbourhood Name
$pr = App\Models\Property::find(1)->street->neighbourhood->name
= "Taman Koperasi Guru"
//Get Property Id(1) Street Name
$pr = App\Models\Property::find(1)->street->name
= "Lorong Karyawan 1"
//Get property record with number (2) on street (1) only with full_name and created_at attribute
$pr = App\Models\Property::where('number','2')
->where('street_id','1')
->first()
->residents
->map->only('full_name','created_at')
= Illuminate\Support\Collection {#7371
all: [
[
"full_name" => "Ghazali Tajuddin",
"created_at" => Illuminate\Support\Carbon @1690467115 {#7268
date: 2023-07-27 14:11:55.0 UTC (+00:00),
},
],
[
"full_name" => "Ida",
"created_at" => Illuminate\Support\Carbon @1690467115 {#7344
date: 2023-07-27 14:11:55.0 UTC (+00:00),
},
],
],
}
//Get property residential with male disabilities and take 2 records
$pr = App\Models\PropertyResidential::
whereNotNull('male_disabilities')
->where('male_disabilities','>',0)->take(2)->get()
= Illuminate\Database\Eloquent\Collection {#7269
all: [
App\Models\PropertyResidential {#7268
id: 1,
property_id: 1,
registrar_id: null,
male_babies: 2,
female_babies: 2,
male_childs: 2,
female_childs: 2,
male_adults: 2,
female_adults: 2,
male_seniors: 2,
female_seniors: 2,
male_disabilities: 2,
female_disabilities: 2,
has_health_problem: 2,
health_description: "2",
total_resident: 2,
occupancy_status: 2,
created_at: "2023-07-28 02:26:24",
updated_at: null,
},
App\Models\PropertyResidential {#7271
id: 2,
property_id: 2,
registrar_id: null,
male_babies: 2,
female_babies: 2,
male_childs: 2,
female_childs: 2,
male_adults: 2,
female_adults: 2,
male_seniors: 2,
female_seniors: 2,
male_disabilities: 2,
female_disabilities: 2,
has_health_problem: 2,
health_description: "2",
total_resident: 2,
occupancy_status: 2,
created_at: "2023-07-28 02:26:24",
updated_at: null,
},
],
}
//Get first record property record
$pr->get(0)->property
= App\Models\Property {#7259
id: 1,
type: 1,
number: "1",
street_id: 1,
owner_name: null,
owner_contact: null,
neighbourhood_id: 1,
registrar_id: 1,
created_at: null,
updated_at: null,
}