|null $reference */ public function __construct( public string $key, public string $label, public string $value, public ?string $secondaryValue, public ?string $targetUrl, public string $targetKind, public string $availability, public ?string $unavailableReason, public ?string $contextBadge, public int $priority, public string $actionLabel, public ?array $reference = null, ) {} public static function available( string $key, string $label, string $value, ?string $secondaryValue, string $targetUrl, string $targetKind, int $priority, string $actionLabel, ?string $contextBadge = null, ): self { return new self( key: $key, label: $label, value: $value, secondaryValue: $secondaryValue, targetUrl: $targetUrl, targetKind: $targetKind, availability: 'available', unavailableReason: null, contextBadge: $contextBadge, priority: $priority, actionLabel: $actionLabel, reference: null, ); } public static function unavailable( string $key, string $label, UnavailableRelationState $state, string $targetKind, int $priority, string $actionLabel, ): self { return new self( key: $key, label: $label, value: 'Unavailable', secondaryValue: $state->showReference ? $state->referenceValue : null, targetUrl: null, targetKind: $targetKind, availability: $state->reason, unavailableReason: $state->message, contextBadge: null, priority: $priority, actionLabel: $actionLabel, reference: null, ); } /** * @param array{ * primaryLabel: string, * secondaryLabel: ?string, * state: string, * stateDescription: ?string, * linkTarget: array{targetKind: string, url: string, actionLabel: string, contextBadge: ?string}|null, * technicalDetail: array{displayId: ?string, fullId: string, sourceHint: ?string, copyable: bool, defaultCollapsed: bool}, * isLinkable: bool * }&array $reference */ public static function fromResolvedReference( string $key, string $label, string $targetKind, int $priority, string $actionLabel, array $reference, ): self { $linkTarget = is_array($reference['linkTarget'] ?? null) ? $reference['linkTarget'] : null; $technicalDetail = is_array($reference['technicalDetail'] ?? null) ? $reference['technicalDetail'] : []; $isLinkable = ($reference['isLinkable'] ?? false) === true && is_string($linkTarget['url'] ?? null) && $linkTarget['url'] !== ''; $secondaryValueParts = array_values(array_filter([ is_string($reference['secondaryLabel'] ?? null) ? $reference['secondaryLabel'] : null, is_string($technicalDetail['displayId'] ?? null) ? 'ID '.$technicalDetail['displayId'] : null, ])); return new self( key: $key, label: $label, value: (string) ($reference['primaryLabel'] ?? 'Reference'), secondaryValue: $secondaryValueParts !== [] ? implode(' ยท ', $secondaryValueParts) : null, targetUrl: $isLinkable ? (string) $linkTarget['url'] : null, targetKind: $targetKind, availability: $isLinkable ? 'available' : (string) ($reference['state'] ?? 'unresolved'), unavailableReason: is_string($reference['stateDescription'] ?? null) ? $reference['stateDescription'] : null, contextBadge: is_string($linkTarget['contextBadge'] ?? null) ? $linkTarget['contextBadge'] : null, priority: $priority, actionLabel: is_string($linkTarget['actionLabel'] ?? null) ? (string) $linkTarget['actionLabel'] : $actionLabel, reference: $reference, ); } public function isAvailable(): bool { return $this->availability === 'available' && is_string($this->targetUrl) && $this->targetUrl !== ''; } /** * @return array{ * key: string, * label: string, * value: string, * secondaryValue: ?string, * targetUrl: ?string, * targetKind: string, * availability: string, * unavailableReason: ?string, * contextBadge: ?string, * priority: int, * actionLabel: string, * reference: array|null * } */ public function toArray(): array { return [ 'key' => $this->key, 'label' => $this->label, 'value' => $this->value, 'secondaryValue' => $this->secondaryValue, 'targetUrl' => $this->targetUrl, 'targetKind' => $this->targetKind, 'availability' => $this->availability, 'unavailableReason' => $this->unavailableReason, 'contextBadge' => $this->contextBadge, 'priority' => $this->priority, 'actionLabel' => $this->actionLabel, 'reference' => $this->reference, ]; } }