221 lines
5.2 KiB
PHP
221 lines
5.2 KiB
PHP
<?php
|
|
|
|
|
|
namespace App\Models\Permission\Traits;
|
|
|
|
use App\Models\Permission\Role;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Contracts\Auth\Access\Gate;
|
|
use App\Domains\Permission\Services\PermissionService;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
|
|
trait HasRoles
|
|
{
|
|
use HasPermissions;
|
|
|
|
public static function bootHasRoles()
|
|
{
|
|
static::deleting(function ($model) {
|
|
if (method_exists($model, 'isForceDeleting') && ! $model->isForceDeleting()) {
|
|
return;
|
|
}
|
|
|
|
$model->roles()->detach();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* A model may have roles.
|
|
*/
|
|
public function roles(): BelongsToMany
|
|
{
|
|
return $this->belongsToMany(Role::class, 'account_has_roles', 'account_id', 'role_id');
|
|
}
|
|
|
|
/**
|
|
* Assign the given role to the model.
|
|
*
|
|
* @param array|string|Role ...$roles
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function assignRole(...$roles)
|
|
{
|
|
$roles = collect($roles)->flatten()->map(function ($role) {
|
|
if (empty($role)) {
|
|
return false;
|
|
}
|
|
|
|
return $this->getStoredRole($role);
|
|
})->filter(function ($role) {
|
|
return $role instanceof Role;
|
|
})->all();
|
|
|
|
$this->roles()->saveMany($roles);
|
|
|
|
$this->forgetCachedPermissions();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Revoke the given role from the model.
|
|
*
|
|
* @param string|Role $role
|
|
*/
|
|
public function removeRole($role)
|
|
{
|
|
$this->roles()->detach($this->getStoredRole($role));
|
|
}
|
|
|
|
/**
|
|
* Remove all current roles and set the given ones.
|
|
*
|
|
* @param array|Role|string ...$roles
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function syncRoles(...$roles)
|
|
{
|
|
return DB::transaction(function () use ($roles) {
|
|
$this->roles()->detach();
|
|
|
|
return $this->assignRole($roles);
|
|
});
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Determine if the model has (one of) the given role(s).
|
|
*
|
|
* @param string|array|Role|Collection $roles
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasRole($roles): bool
|
|
{
|
|
if (is_string($roles) && false !== strpos($roles, '|')) {
|
|
$roles = $this->convertPipeToArray($roles);
|
|
}
|
|
|
|
if (is_string($roles)) {
|
|
return $this->roles->contains('name', $roles);
|
|
}
|
|
|
|
if ($roles instanceof Role) {
|
|
return $this->roles->contains('id', $roles->id);
|
|
}
|
|
|
|
if (is_array($roles)) {
|
|
foreach ($roles as $role) {
|
|
if ($this->hasRole($role)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return $roles->intersect($this->roles)->isNotEmpty();
|
|
}
|
|
|
|
/**
|
|
* Determine if the model has any of the given role(s).
|
|
*
|
|
* @param string|array|Role|Collection $roles
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasAnyRole($roles): bool
|
|
{
|
|
return $this->hasRole($roles);
|
|
}
|
|
|
|
/**
|
|
* Determine if the model has all of the given role(s).
|
|
*
|
|
* @param string|Role|Collection $roles
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasAllRoles($roles): bool
|
|
{
|
|
if (is_string($roles) && false !== strpos($roles, '|')) {
|
|
$roles = $this->convertPipeToArray($roles);
|
|
}
|
|
|
|
if (is_string($roles)) {
|
|
return $this->roles->contains('name', $roles);
|
|
}
|
|
|
|
if ($roles instanceof Role) {
|
|
return $this->roles->contains('id', $roles->id);
|
|
}
|
|
|
|
$roles = collect()->make($roles)->map(function ($role) {
|
|
return $role instanceof Role ? $role->name : $role;
|
|
});
|
|
|
|
return $roles->intersect($this->roles->pluck('name')) == $roles;
|
|
}
|
|
|
|
/**
|
|
* Return all permissions directly coupled to the model.
|
|
*/
|
|
public function getDirectPermissions(): Collection
|
|
{
|
|
return $this->permissions;
|
|
}
|
|
|
|
public function getRoleNames(): Collection
|
|
{
|
|
return $this->roles->pluck('name');
|
|
}
|
|
|
|
protected function getStoredRole($role): Role
|
|
{
|
|
if (is_numeric($role)) {
|
|
return app(Role::class)->findById($role);
|
|
}
|
|
|
|
return $role;
|
|
}
|
|
|
|
protected function convertPipeToArray(string $pipeString)
|
|
{
|
|
$pipeString = trim($pipeString);
|
|
|
|
if (strlen($pipeString) <= 2) {
|
|
return $pipeString;
|
|
}
|
|
|
|
$quoteCharacter = substr($pipeString, 0, 1);
|
|
$endCharacter = substr($quoteCharacter, -1, 1);
|
|
|
|
if ($quoteCharacter !== $endCharacter) {
|
|
return explode('|', $pipeString);
|
|
}
|
|
|
|
if (! in_array($quoteCharacter, ["'", '"'])) {
|
|
return explode('|', $pipeString);
|
|
}
|
|
|
|
return explode('|', trim($pipeString, $quoteCharacter));
|
|
}
|
|
|
|
/**
|
|
* Determine if the entity has a given ability.
|
|
*
|
|
* @param string $ability
|
|
* @param array|mixed $arguments
|
|
* @return bool
|
|
*/
|
|
public function can($ability, $arguments = [])
|
|
{
|
|
return app(Gate::class)->forUser($this)->check($ability, $arguments);
|
|
}
|
|
}
|