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); } }