*/ private array $stages; /** * @var int */ private int $heartbeat; /** * @var string */ private string $lease_owner; /** * @var int */ private int $lease_expires; /** * @var int */ private int $started_at; /** * @param string $status Job status. * @param array $stages Stage records. * @param int $heartbeat Last commit time. * @param string $lease_owner Current lease holder. * @param int $lease_expires Lease expiry. * @param int $started_at Job start time. */ private function __construct( string $status, array $stages, int $heartbeat, string $lease_owner, int $lease_expires, int $started_at ) { $this->schema_version = self::SCHEMA_VERSION; $this->status = $status; $this->stages = $stages; $this->heartbeat = $heartbeat; $this->lease_owner = $lease_owner; $this->lease_expires = $lease_expires; $this->started_at = $started_at; } /** * Builds a fresh job with every stage pending. * * @since 1.14.0 * * @param array $stage_ids Stage ids, in execution order. * * @return self */ public static function idle( array $stage_ids ): self { $stages = array(); foreach ( $stage_ids as $id ) { $stages[ $id ] = array( 'status' => 'pending', 'cursor' => 0, 'processed' => 0, 'failures' => 0, 'error' => '', ); } return new self( 'idle', $stages, 0, '', 0, 0 ); } /** * Rebuilds state from a stored record, or null when it cannot be trusted. * * @since 1.14.0 * * @param mixed $raw Stored option value. * * @return self|null */ public static function from_array( $raw ): ?self { if ( ! is_array( $raw ) ) { return null; } if ( ( $raw['schema_version'] ?? null ) !== self::SCHEMA_VERSION ) { return null; } if ( ! is_array( $raw['stages'] ?? null ) ) { return null; } $stages = array(); foreach ( $raw['stages'] as $id => $stage ) { if ( ! is_string( $id ) || ! is_array( $stage ) ) { return null; } $stages[ $id ] = array( 'status' => (string) ( $stage['status'] ?? 'pending' ), 'cursor' => (int) ( $stage['cursor'] ?? 0 ), 'processed' => (int) ( $stage['processed'] ?? 0 ), 'failures' => (int) ( $stage['failures'] ?? 0 ), 'error' => (string) ( $stage['error'] ?? '' ), ); } return new self( (string) ( $raw['status'] ?? 'idle' ), $stages, (int) ( $raw['heartbeat'] ?? 0 ), (string) ( $raw['lease_owner'] ?? '' ), (int) ( $raw['lease_expires'] ?? 0 ), (int) ( $raw['started_at'] ?? 0 ) ); } /** * @since 1.14.0 * * @return array */ public function to_array(): array { return array( 'schema_version' => $this->schema_version, 'status' => $this->status, 'stages' => $this->stages, 'heartbeat' => $this->heartbeat, 'lease_owner' => $this->lease_owner, 'lease_expires' => $this->lease_expires, 'started_at' => $this->started_at, ); } /** * @since 1.14.0 */ public function status(): string { return $this->status; } /** * @since 1.14.0 * * @return array */ public function stages(): array { return $this->stages; } /** * @since 1.14.0 */ public function heartbeat(): int { return $this->heartbeat; } /** * @since 1.14.0 */ public function lease_owner(): string { return $this->lease_owner; } /** * @since 1.14.0 */ public function lease_expires(): int { return $this->lease_expires; } /** * @since 1.14.0 */ public function started_at(): int { return $this->started_at; } /** * @since 1.14.0 * * @param string $status New status. */ public function with_status( string $status ): self { $clone = clone $this; $clone->status = $status; return $clone; } /** * @since 1.14.0 * * @param string $id Stage id. * @param array{status: string, cursor: int, processed: int, failures: int, error: string} $stage Stage record. */ public function with_stage( string $id, array $stage ): self { $clone = clone $this; $clone->stages[ $id ] = $stage; return $clone; } /** * Returns a copy without the given stage's record. * * @since 1.18.1 * * @param string $id Stage id. */ public function without_stage( string $id ): self { $clone = clone $this; unset( $clone->stages[ $id ] ); return $clone; } /** * @since 1.14.0 * * @param int $timestamp Commit time. */ public function with_heartbeat( int $timestamp ): self { $clone = clone $this; $clone->heartbeat = $timestamp; return $clone; } /** * @since 1.14.0 * * @param int $timestamp Job start time. */ public function with_started_at( int $timestamp ): self { $clone = clone $this; $clone->started_at = $timestamp; return $clone; } /** * @since 1.14.0 * * @param string $owner Lease holder token. * @param int $expires Lease expiry timestamp. */ public function with_lease( string $owner, int $expires ): self { $clone = clone $this; $clone->lease_owner = $owner; $clone->lease_expires = $expires; return $clone; } /** * @since 1.14.0 */ public function without_lease(): self { return $this->with_lease( '', 0 ); } }