belongsToMany(User::class) ->withTimestamps() ->using(GroupUser::class); } /** * Relationship: Permissions assigned to this group */ public function permissions(): BelongsToMany { return $this->belongsToMany( config('permission.models.permission'), config('permission.table_names.group_has_permissions'), 'group_id', 'permission_id' ); } /** * Scope: Groups with specific permission */ public function scopeWithPermission(Builder $query, $permission): Builder { return $query->whereHas('permissions', function ($q) use ($permission) { $q->where('name', $permission); }); } /** * Scope: Groups with permissions on specific resource */ public function scopeWithResourcePermissions(Builder $query, $resourceId, $resourceType): Builder { return $query->whereHas('permissions', function ($q) use ($resourceId, $resourceType) { $q->where('name', 'like', "{$resourceType}-{$resourceId}-%"); }); } /** * Assign permission to group */ public function assignPermission($permission): self { if (is_string($permission)) { $permission = Permission::findByName($permission); } $this->permissions()->syncWithoutDetaching($permission); return $this; } /** * Revoke permission from group */ public function revokePermission($permission): self { if (is_string($permission)) { $permission = Permission::findByName($permission); } $this->permissions()->detach($permission); return $this; } /** * Sync all permissions */ public function syncPermissions($permissions): self { $permissionIds = collect($permissions)->map(function ($perm) { return is_string($perm) ? Permission::findByName($perm)->id : $perm->id; }); $this->permissions()->sync($permissionIds); return $this; } /** * Check if group has permission */ public function hasPermission($permission): bool { if (is_string($permission)) { return $this->permissions->contains('name', $permission); } return $this->permissions->contains('id', $permission->id); } /** * Get all users with permissions through this group */ public function getUsersWithPermissionsAttribute() { return User::whereHas('groups', function ($query) { $query->where('groups.id', $this->id); })->get(); } /** * Get permission names attribute */ public function getPermissionNamesAttribute() { return $this->permissions->pluck('name'); } /** * Validation rules */ public static function validationRules($groupId = null): array { return [ 'name' => 'required|string|max:255|unique:groups,name,'.$groupId, 'description' => 'nullable|string|max:500', 'permissions' => 'array', 'permissions.*' => 'exists:permissions,id', 'users' => 'array', 'users.*' => 'exists:users,id' ]; } /** * The "booting" method of the model */ protected static function boot() { parent::boot(); static::deleting(function ($group) { if ($group->isForceDeleting()) { $group->users()->detach(); $group->permissions()->detach(); } }); } }