A traits, I fields

This commit is contained in:
a6a2f5842 2025-06-16 09:49:36 +02:00
parent e65ea42586
commit cf337a8bb6
14 changed files with 186 additions and 31 deletions

6
.gitattributes vendored Normal file
View File

@ -0,0 +1,6 @@
/.vscode export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/phpunit.xml.dist export-ignore
/docs export-ignore
/tests export-ignore

6
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"editor.formatOnSave": true,
"[php]": {
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
},
}

View File

@ -32,6 +32,7 @@
},
"require": {
"php": "^8.0",
"illuminated/helper-functions": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/auth": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/container": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/contracts": "^8.12|^9.0|^10.0|^11.0|^12.0",
@ -39,21 +40,16 @@
"illuminate/support": "^8.12|^9.0|^10.0|^11.0|^12.0"
},
"require-dev": {
"laravel/pint": "^1.22"
"laravel/pint": "^1.22",
"laravel/framework": "*"
},
"extra": {
"laravel": {
"providers": [
"Blax\\Roles\\PermissionsServiceProvider"
"Blax\\Roles\\RolesServiceProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-install-cmd": [
"@php artisan vendor:publish --tag=roles-migrations --force",
"@php artisan vendor:publish --tag=roles-config --force"
]
}
"prefer-stable": true
}

View File

@ -8,11 +8,13 @@ return [
'role_permission' => \Blax\Roles\Models\RolePermission::class,
'permission' => \Blax\Roles\Models\Permission::class,
'permission_usage' => \Blax\Roles\Models\PermissionUsage::class,
'permission_members' => \Blax\Roles\Models\PermissionMember::class,
],
'table_names' => [
'permissions' => 'permissions',
'permission_usage' => 'permission_usages',
'permission_members' => 'permission_members',
'roles' => 'roles',
'role_member' => 'role_members',
'role_permission' => 'role_permissions',

View File

@ -21,15 +21,26 @@ return new class extends Migration
$table->timestamps();
});
// PermissionMember
Schema::create(config('roles.table_names.permission_members'), function (Blueprint $table) {
$table->id();
$table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade');
$table->morphs('member');
$table->json('context')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
// PermissionUsage
Schema::create(config('roles.table_names.permission_usage'), function (Blueprint $table) {
$table->id();
$table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade');
$table->float('usage', 8)->default(1);
$table->morphs('user');
$table->json('context')->nullable();
$table->timestamps();
});
// Role
Schema::create(config('roles.table_names.roles'), function (Blueprint $table) {
$table->id();
@ -73,6 +84,7 @@ return new class extends Migration
Schema::dropIfExists(config('roles.table_names.role_members'));
Schema::dropIfExists(config('roles.table_names.roles'));
Schema::dropIfExists(config('roles.table_names.permission_usage'));
Schema::dropIfExists(config('roles.table_names.permission_members'));
Schema::dropIfExists(config('roles.table_names.permissions'));
}
};

View File

@ -4,7 +4,8 @@ namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model {
class Permission extends Model
{
protected $fillable = [
'slug',
'description',
@ -26,4 +27,9 @@ class Permission extends Model {
{
return $this->belongsToMany(RolePermission::class);
}
public function members()
{
return $this->hasMany(PermissionMember::class);
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace Blax\Roles\Models;
use Blax\Roles\Traits\WillExpire;
use Illuminate\Database\Eloquent\Model;
class PermissionMember extends Model
{
use WillExpire;
protected $fillable = [
'permission_id',
'member_id',
'member_type',
'context',
'expires_at',
];
protected $casts = [
'context' => 'array',
'expires_at' => 'datetime',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('roles.table_names.permission_members') ?: parent::getTable();
}
public function permission()
{
return $this->belongsTo(Permission::class);
}
public function member()
{
return $this->morphTo();
}
}

View File

@ -4,10 +4,19 @@ namespace Blax\Roles\Models;
use Illuminate\Database\Eloquent\Model;
class PermissionUsage extends Model {
class PermissionUsage extends Model
{
protected $fillable = [
'permission_id',
'usage_count'
'usage',
'context',
'user_type',
'user_id',
];
protected $casts = [
'context' => 'array',
'usage' => 'float',
];
public function __construct(array $attributes = [])
@ -21,4 +30,9 @@ class PermissionUsage extends Model {
{
return $this->belongsTo(Permission::class);
}
public function user()
{
return $this->morphTo();
}
}

View File

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

View File

@ -2,9 +2,13 @@
namespace Blax\Roles\Models;
use Blax\Roles\Traits\WillExpire;
use Illuminate\Database\Eloquent\Model;
class RoleMember extends Model {
class RoleMember extends Model
{
use WillExpire;
protected $fillable = [
'role_id',
'member',
@ -12,6 +16,11 @@ class RoleMember extends Model {
'expires_at',
];
protected $casts = [
'context' => 'array',
'expires_at' => 'datetime',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
@ -19,11 +28,13 @@ class RoleMember extends Model {
$this->table = config('roles.table_names.role_members') ?: parent::getTable();
}
public function role() {
public function role()
{
return $this->belongsTo(Role::class);
}
public function member() {
public function member()
{
return $this->morphTo();
}
}

View File

@ -2,9 +2,13 @@
namespace Blax\Roles\Models;
use Blax\Roles\Traits\WillExpire;
use Illuminate\Database\Eloquent\Model;
class RolePermission extends Model {
class RolePermission extends Model
{
use WillExpire;
protected $fillable = [
'role_id',
'permission_id',
@ -17,11 +21,13 @@ class RolePermission extends Model {
$this->table = config('roles.table_names.role_permissions') ?: parent::getTable();
}
public function role() {
public function role()
{
return $this->belongsTo(Role::class);
}
public function permission() {
public function permission()
{
return $this->belongsTo(Permission::class);
}
}

View File

@ -2,7 +2,7 @@
namespace Blax\Roles;
class PermissionsServiceProvider extends \Illuminate\Support\ServiceProvider
class RolesServiceProvider extends \Illuminate\Support\ServiceProvider
{
/**
* Register the service provider.
@ -73,5 +73,6 @@ class PermissionsServiceProvider extends \Illuminate\Support\ServiceProvider
$this->app->bind(\Blax\Roles\Models\RolePermission::class, fn ($app) => $app->make($app->config['roles.models.role_permission']));
$this->app->bind(\Blax\Roles\Models\Permission::class, fn ($app) => $app->make($app->config['roles.models.permission']));
$this->app->bind(\Blax\Roles\Models\PermissionUsage::class, fn ($app) => $app->make($app->config['roles.models.permission_usage']));
$this->app->bind(\Blax\Roles\Models\PermissionMember::class, fn ($app) => $app->make($app->config['roles.models.permission_members']));
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Blax\Roles\Traits;
trait HasPermissions
{
public function hasPermission(string $permission, array $context = []): bool
{
return $this->permissions()
->where('name', $permission)
->where(function ($query) use ($context) {
if (!empty($context)) {
$query->where('context', $context);
}
})
->exists();
}
public function permissions()
{
return $this->morphToMany(
config('roles.models.permission'),
'member',
config('roles.table_names.permission_members')
);
}
}

22
src/Traits/WillExpire.php Normal file
View File

@ -0,0 +1,22 @@
<?php
namespace Blax\Roles\Traits;
trait WillExpire
{
public static function bootWillExpire()
{
static::addGlobalScope('willExpire', function ($builder) {
$builder->where(function ($query) {
$query->whereNull('expires_at')
->orWhere('expires_at', '>', now());
});
});
}
public function isExpired(): bool
{
return $this->expires_at && $this->expires_at->isPast();
}
}