$steps */ public function __construct( public readonly string $id, public readonly string $createdAt, public readonly int $userId, public readonly string $diviVersion, public readonly string $pluginVersion, public readonly string $stateKey, public readonly array $steps ) { } public function green(): bool { if ($this->steps === []) { return false; } foreach ($this->steps as $step) { if (! $step->green()) { return false; } } return true; } /** Green and made for exactly this Divi version, plugin version and Divi files (ReleaseResolver::stateKey()). */ public function freshFor(string $diviVersion, string $pluginVersion, string $stateKey): bool { return $this->green() && $this->diviVersion === $diviVersion && $this->pluginVersion === $pluginVersion && $this->stateKey === $stateKey; } public function step(string $key): ?CheckStep { foreach ($this->steps as $step) { if ($step->key === $key) { return $step; } } return null; } /** @return array */ public function toArray(): array { return [ 'id' => $this->id, 'created_at' => $this->createdAt, 'user_id' => $this->userId, 'divi_version' => $this->diviVersion, 'plugin_version' => $this->pluginVersion, 'state_key' => $this->stateKey, 'steps' => array_map(static fn (CheckStep $step): array => $step->toArray(), $this->steps), ]; } public static function fromArray(mixed $data): ?self { if (! is_array($data)) { return null; } foreach (['id', 'created_at', 'divi_version', 'plugin_version', 'state_key'] as $key) { if (! is_string($data[$key] ?? null)) { return null; } } if (! is_int($data['user_id'] ?? null) || ! is_array($data['steps'] ?? null)) { return null; } $steps = []; foreach ($data['steps'] as $step) { $parsed = CheckStep::fromArray($step); if ($parsed === null) { return null; } $steps[] = $parsed; } return new self( $data['id'], $data['created_at'], $data['user_id'], $data['divi_version'], $data['plugin_version'], $data['state_key'], $steps ); } }