|null $agent_ids Null means global (unrestricted). */ private function __construct( private readonly ?array $agent_ids, ) {} /** * Unrestricted scope (managers / admins). * * @since 0.1.0 */ public static function global(): self { return new self( null ); } /** * Restrict to one or more agent ids. * * @param int ...$agent_ids Agent database ids. * * @since 0.1.0 */ public static function for_agents( int ...$agent_ids ): self { $ids = array_values( array_unique( array_map( 'intval', $agent_ids ) ) ); $ids = array_values( array_filter( $ids, static fn( int $id ): bool => $id > 0 ) ); return new self( $ids ); } /** * Whether this scope is unrestricted. * * @since 0.1.0 */ public function is_global(): bool { return null === $this->agent_ids; } /** * Allowed agent ids, or null when global. * * @return list|null * * @since 0.1.0 */ public function agent_ids(): ?array { return $this->agent_ids; } /** * Whether a booking/agent row is visible under this scope. * * @param int|null $agent_id Agent id on the row. * * @since 0.1.0 */ public function allows_agent( ?int $agent_id ): bool { if ( $this->is_global() ) { return true; } if ( null === $agent_id || null === $this->agent_ids ) { return false; } return in_array( $agent_id, $this->agent_ids, true ); } /** * Intersect a requested agent filter with this scope. * * @param list|null $requested Optional client filter. * @return list|null Null means no agent restriction (global + no filter). * * @since 0.1.0 */ public function resolve_agent_filter( ?array $requested = null ): ?array { if ( $this->is_global() ) { return $requested; } $scoped = $this->agent_ids ?? []; if ( null === $requested || [] === $requested ) { return $scoped; } $want = array_fill_keys( array_map( 'intval', $requested ), true ); $out = []; foreach ( $scoped as $id ) { if ( isset( $want[ $id ] ) ) { $out[] = $id; } } return $out; } }