$scopes */ public function __construct( private array $scopes, ) { if (empty($scopes)) { throw new \InvalidArgumentException('Token scope cannot be empty'); } foreach ($scopes as $scope) { if (! is_string($scope) || empty(trim($scope))) { throw new \InvalidArgumentException('Invalid scope value'); } } } /** * Create from space-separated string (OAuth standard format) */ public static function fromString(string $scopeString): self { $scopes = array_values(array_filter( array_map('trim', explode(' ', $scopeString)), fn ($scope) => ! empty($scope) )); return new self($scopes); } /** * Create from array of scopes * * @param array $scopes */ public static function fromArray(array $scopes): self { return new self($scopes); } /** * Get scopes as array * * @return array */ public function toArray(): array { return $this->scopes; } /** * Get scopes as space-separated string (OAuth standard format) */ public function toString(): string { return implode(' ', $this->scopes); } /** * Check if scope includes a specific permission */ public function includes(string $scope): bool { return in_array($scope, $this->scopes, true); } /** * Check if scope includes all specified permissions * * @param array $requiredScopes */ public function includesAll(array $requiredScopes): bool { foreach ($requiredScopes as $required) { if (! $this->includes($required)) { return false; } } return true; } /** * Check if scope includes any of the specified permissions * * @param array $scopes */ public function includesAny(array $scopes): bool { foreach ($scopes as $scope) { if ($this->includes($scope)) { return true; } } return false; } /** * Add additional scopes * * @param array $additionalScopes */ public function withAdditional(array $additionalScopes): self { return new self([...$this->scopes, ...$additionalScopes]); } /** * Remove specific scopes * * @param array $scopesToRemove */ public function without(array $scopesToRemove): self { $filtered = array_filter( $this->scopes, fn ($scope) => ! in_array($scope, $scopesToRemove, true) ); if (empty($filtered)) { throw new \InvalidArgumentException('Cannot remove all scopes'); } return new self(array_values($filtered)); } public function __toString(): string { return $this->toString(); } }