visible = $visible; $this->label = $normalizedLabel; $this->amount = $normalizedAmount; $this->currency = $normalizedCurrency; $this->observedAtLabel = $normalizedObservedAtLabel; $this->disclaimerRequired = $disclaimerRequired; } /** * Construct a price view with the price region suppressed. * * Convenience factory for the §10.5 "価格がない場合は価格 * 領域を非表示" branch so call sites do not have to spell out * five `null` arguments. */ public static function hidden(): self { return new self( false, null, null, null, null, false ); } /** * Whether the price region should be rendered at all. */ public function visible(): bool { return $this->visible; } /** * Pre-formatted price label, or null when not displayed. */ public function label(): ?string { return $this->label; } /** * Underlying decimal-string amount, or null. */ public function amount(): ?string { return $this->amount; } /** * ISO 4217 currency code, or null. */ public function currency(): ?string { return $this->currency; } /** * Pre-formatted observation timestamp label, or null. */ public function observedAtLabel(): ?string { return $this->observedAtLabel; } /** * Whether the renderer MUST surface a disclaimer alongside * the price. */ public function disclaimerRequired(): bool { return $this->disclaimerRequired; } /** * Report whether this view equals the supplied one. * * Equality is structural: every field must match with strict * comparison. * * @param self $other Other view to compare against. */ public function equals( self $other ): bool { return $this->visible === $other->visible && $this->label === $other->label && $this->amount === $other->amount && $this->currency === $other->currency && $this->observedAtLabel === $other->observedAtLabel && $this->disclaimerRequired === $other->disclaimerRequired; } /** * Validate and normalize a nullable string field that, when * non-null, must carry non-empty content. * * @param string $field Field name for the error message. * @param string|null $value Raw value, or null. * * @throws InvalidArgumentException When `$value` is the empty * string after trimming. */ private static function normalizeOptionalString( string $field, ?string $value ): ?string { if ( $value === null ) { return null; } $trimmed = trim( $value ); if ( $trimmed === '' ) { $message = sprintf( 'PriceView %s must be null or a non-empty string.', $field ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Developer-facing message, never rendered to HTML. throw new InvalidArgumentException( $message ); } return $trimmed; } }