*/ public array $urls; /** @param list $urls Public same-host URLs. */ public function __construct( string $type, string $external_id, string $occurred_at, array $urls ) { $this->type = $type; $this->external_id = $external_id; $this->occurred_at = $occurred_at; $this->urls = $urls; } /** @param list $urls Server-bounded URL list. */ public function with_urls( array $urls ): self { return new self( $this->type, $this->external_id, $this->occurred_at, $urls ); } public function is_automatic(): bool { return self::MANUAL !== $this->type; } public function debounce_key(): string { $urls = array_map( static fn ( RunUrl $url ): string => $url->url, $this->urls ); return 'two_ua_release_' . substr( hash( 'sha256', $this->type . '|' . implode( '|', $urls ) ), 0, 32 ); } /** * @return array{ * type: string, external_id: string, occurred_at: string, * urls: list * } WordPress Cron boundary payload. */ public function to_payload(): array { return array( 'type' => $this->type, 'external_id' => $this->external_id, 'occurred_at' => $this->occurred_at, 'urls' => array_map( static fn ( RunUrl $url ): array => $url->to_payload(), $this->urls ), ); } /** @param array $payload WordPress Cron boundary payload. */ public static function from_payload( array $payload ): ?self { $type = $payload['type'] ?? null; $external_id = $payload['external_id'] ?? null; $occurred_at = $payload['occurred_at'] ?? null; $url_payload = $payload['urls'] ?? null; if ( ! is_string( $type ) || ! is_string( $external_id ) || ! is_string( $occurred_at ) ) { return null; } if ( ! is_array( $url_payload ) ) { return null; } $urls = self::urls_from_payload( $url_payload ); return array() === $urls ? null : new self( $type, $external_id, $occurred_at, $urls ); } /** @param array $payload @return list */ private static function urls_from_payload( array $payload ): array { $urls = array(); foreach ( $payload as $item ) { $url = is_array( $item ) ? RunUrl::from_payload( $item ) : null; if ( $url instanceof RunUrl ) { $urls[] = $url; } } return $urls; } }