I basic structure

This commit is contained in:
a6a2f5842 2025-06-15 18:29:50 +02:00
parent 7cfc7749cc
commit 1fb57141bc
9 changed files with 185 additions and 31 deletions

View File

@ -4,15 +4,17 @@ return [
'models' => [ 'models' => [
'role' => \Blax\Roles\Models\Role::class, 'role' => \Blax\Roles\Models\Role::class,
'role_member' => \Blax\Roles\Models\RoleMember::class,
'role_permission' => \Blax\Roles\Models\RolePermission::class,
'permission' => \Blax\Roles\Models\Permission::class, 'permission' => \Blax\Roles\Models\Permission::class,
'permission_usage' => \Blax\Roles\Models\PermissionUsage::class,
], ],
'table_names' => [ 'table_names' => [
'roles' => 'roles', 'roles' => 'roles',
'permissions' => 'permissions', 'permissions' => 'permissions',
'model_has_roles' => 'model_has_roles', 'permission_usage' => 'permission_usage',
'model_has_permissions' => 'model_has_permissions',
'role_has_permissions' => 'role_has_permissions',
], ],
]; ];

View File

@ -13,25 +13,52 @@ return new class extends Migration
*/ */
public function up(): void public function up(): void
{ {
// TODO finish the migration // Permission
Schema::create(config('permissions.table_names.permissions'), function (Blueprint $table) {
Schema::create('roles', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('name')->unique(); $table->string('name')->unique();
$table->string('description')->nullable(); $table->string('description')->nullable();
$table->timestamps(); $table->timestamps();
}); });
Schema::create('permissions', function (Blueprint $table) { // PermissionUsage
Schema::create(config('permissions.table_names.permission_usage'), function (Blueprint $table) {
$table->id(); $table->id();
$table->string('name')->unique(); $table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade');
$table->morphs('user');
$table->json('context')->nullable();
$table->timestamps();
});
// Role
Schema::create(config('permissions.table_names.roles'), function (Blueprint $table) {
$table->id();
$table->foreignId('parent_id')
->nullable()
->constrained('roles')
->onDelete('set null');
$table->string('name');
$table->string('slug',32)->unique();
$table->string('description')->nullable(); $table->string('description')->nullable();
$table->timestamps(); $table->timestamps();
}); });
Schema::create('assignments', function (Blueprint $table) { // RoleMember
$table->morphs('affected'); Schema::create(config('permissions.table_names.role_members'), function (Blueprint $table) {
$table->morphs('assignment'); $table->id();
$table->foreignId('role_id')->constrained('roles')->onDelete('cascade');
$table->morphs('member');
$table->json('context')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
// RolePermission
Schema::create(config('permissions.table_names.role_permission'), function (Blueprint $table) {
$table->id();
$table->foreignId('role_id')->constrained('roles')->onDelete('cascade');
$table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade');
$table->json('context')->nullable();
$table->timestamp('expires_at')->nullable(); $table->timestamp('expires_at')->nullable();
$table->timestamps(); $table->timestamps();
}); });

View File

@ -1,7 +0,0 @@
<?php
namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class Assignment extends Model {}

View File

@ -4,4 +4,27 @@ namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Permission extends Model {} class Permission extends Model {
protected $fillable = [
'name',
'slug',
'description',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('permissions.table_names.permissions') ?: parent::getTable();
}
public function usages()
{
return $this->hasMany(PermissionUsage::class);
}
public function roles()
{
return $this->belongsToMany(RolePermission::class);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class PermissionUsage extends Model {
protected $fillable = [
'permission_id',
'usage_count'
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('permissions.table_names.permission_usages') ?: parent::getTable();
}
public function permission()
{
return $this->belongsTo(Permission::class);
}
}

View File

@ -4,4 +4,34 @@ namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Role extends Model {} class Role extends Model {
protected $fillable = [
'parent_id',
'name',
'slug',
'description',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('permissions.table_names.roles') ?: parent::getTable();
}
public function members() {
return $this->belongsToMany(RoleMember::class);
}
public function permissions() {
return $this->belongsToMany(RolePermission::class);
}
public function parent() {
return $this->belongsTo(Role::class, 'parent_id');
}
public function children() {
return $this->hasMany(Role::class, 'parent_id');
}
}

29
src/Models/RoleMember.php Normal file
View File

@ -0,0 +1,29 @@
<?php
namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class RoleMember extends Model {
protected $fillable = [
'role_id',
'member',
'context',
'expires_at',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('permissions.table_names.role_members') ?: parent::getTable();
}
public function role() {
return $this->belongsTo(Role::class);
}
public function member() {
return $this->morphTo();
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class RolePermission extends Model {
protected $fillable = [
'role_id',
'permission_id',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('permissions.table_names.role_permission') ?: parent::getTable();
}
public function role() {
return $this->belongsTo(Role::class);
}
public function permission() {
return $this->belongsTo(Permission::class);
}
}

View File

@ -5,28 +5,27 @@ namespace Blax\Roles;
trait HasRoles trait HasRoles
{ {
/** /**
* The roles that belong to the model. * Get all roles for the user.
* *
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/ */
public function roles() public function roles()
{ {
return $this->belongsToMany( return $this->morphToMany(
config('permissions.models.role'), config('permissions.models.role', \Blax\Roles\Models\Role::class),
config('permissions.table_names.model_has_roles'), 'member',
'model_id', config('permissions.table_names.role_members', 'role_members')
'role_id'
); );
} }
/** /**
* Check if the model has a specific role. * Check if the user has a specific role.
* *
* @param string $role * @param string $roleSlug
* @return bool * @return bool
*/ */
public function hasRole($role) public function hasRole(string $roleSlug): bool
{ {
return $this->roles()->where('name', $role)->exists(); return $this->roles()->where('slug', $roleSlug)->exists();
} }
} }