$conditions AND conditions. * @param list $actions Ordered steps. * @param CancelIfDefinition|null $cancel_if Cancel-if. * @param int|null $pause_period_hours Pause window. * @param bool $is_enabled Enabled. * @param int $run_count Run count. * @param DateTimeImmutable|null $last_run_at Last run UTC. * @param DateTimeImmutable $created_at Created UTC. * @param DateTimeImmutable $updated_at Updated UTC. * * @throws DomainException When name is empty or there are no actions. */ public function __construct( private ?int $id, private readonly Uuid $uuid, private string $name, private ?string $description, private ?string $recipe_key, private TriggerDefinition $trigger, private array $conditions, private array $actions, private ?CancelIfDefinition $cancel_if, private ?int $pause_period_hours, private bool $is_enabled, private int $run_count, private ?DateTimeImmutable $last_run_at, private DateTimeImmutable $created_at, private DateTimeImmutable $updated_at, ) { $name = trim( $this->name ); if ( '' === $name ) { throw new DomainException( 'automation.name_empty', 'Automation name must not be empty.' ); } $this->name = $name; if ( [] === $this->actions ) { throw new DomainException( 'automation.no_actions', 'An automation must have at least one action.' ); } if ( $this->run_count < 0 ) { throw new DomainException( 'automation.run_count', 'run_count must not be negative.' ); } if ( null !== $this->pause_period_hours && $this->pause_period_hours < 0 ) { throw new DomainException( 'automation.pause_negative', 'pause_period_hours must not be negative.' ); } } /** * Database id. * * @since 0.1.0 */ public function id(): ?int { return $this->id; } /** * UUID. * * @since 0.1.0 */ public function uuid(): Uuid { return $this->uuid; } /** * Name. * * @since 0.1.0 */ public function name(): string { return $this->name; } /** * Description. * * @since 0.1.0 */ public function description(): ?string { return $this->description; } /** * Recipe key. * * @since 0.1.0 */ public function recipe_key(): ?string { return $this->recipe_key; } /** * Trigger. * * @since 0.1.0 */ public function trigger(): TriggerDefinition { return $this->trigger; } /** * Conditions. * * @return list * * @since 0.1.0 */ public function conditions(): array { return $this->conditions; } /** * Actions. * * @return list * * @since 0.1.0 */ public function actions(): array { return $this->actions; } /** * Cancel-if. * * @since 0.1.0 */ public function cancel_if(): ?CancelIfDefinition { return $this->cancel_if; } /** * Pause period hours. * * @since 0.1.0 */ public function pause_period_hours(): ?int { return $this->pause_period_hours; } /** * Enabled. * * @since 0.1.0 */ public function is_enabled(): bool { return $this->is_enabled; } /** * Run count. * * @since 0.1.0 */ public function run_count(): int { return $this->run_count; } /** * Last run. * * @since 0.1.0 */ public function last_run_at(): ?DateTimeImmutable { return $this->last_run_at; } /** * Created. * * @since 0.1.0 */ public function created_at(): DateTimeImmutable { return $this->created_at; } /** * Updated. * * @since 0.1.0 */ public function updated_at(): DateTimeImmutable { return $this->updated_at; } /** * Assign id after insert. * * @param int $id Id. * * @throws DomainException When the id is already assigned or is not positive. * * @since 0.1.0 */ public function assign_id( int $id ): void { if ( $id < 1 ) { throw new DomainException( 'automation.id_invalid', 'Automation id must be positive.' ); } if ( null !== $this->id ) { throw new DomainException( 'automation.id_assigned', 'Automation id is already assigned.' ); } $this->id = $id; } /** * Enable. * * @param DateTimeImmutable $when When. * * @since 0.1.0 */ public function enable( DateTimeImmutable $when ): void { $this->is_enabled = true; $this->updated_at = $when; } /** * Disable. * * @param DateTimeImmutable $when When. * * @since 0.1.0 */ public function disable( DateTimeImmutable $when ): void { $this->is_enabled = false; $this->updated_at = $when; } /** * Record a run. * * @param DateTimeImmutable $when When. * * @since 0.1.0 */ public function record_run( DateTimeImmutable $when ): void { ++$this->run_count; $this->last_run_at = $when; $this->updated_at = $when; } /** * Replace definition. * * @param string $name Name. * @param string|null $description Description. * @param TriggerDefinition $trigger Trigger. * @param list $conditions Conditions. * @param list $actions Actions. * @param CancelIfDefinition|null $cancel_if Cancel-if. * @param int|null $pause Pause hours. * @param DateTimeImmutable $when When. * * @throws DomainException When the name is empty or there are no actions. * * @since 0.1.0 */ public function replace_definition( string $name, ?string $description, TriggerDefinition $trigger, array $conditions, array $actions, ?CancelIfDefinition $cancel_if, ?int $pause, DateTimeImmutable $when, ): void { $name = trim( $name ); if ( '' === $name ) { throw new DomainException( 'automation.name_empty', 'Automation name must not be empty.' ); } if ( [] === $actions ) { throw new DomainException( 'automation.no_actions', 'An automation must have at least one action.' ); } $this->name = $name; $this->description = $description; $this->trigger = $trigger; $this->conditions = $conditions; $this->actions = $actions; $this->cancel_if = $cancel_if; $this->pause_period_hours = $pause; $this->updated_at = $when; } /** * Step at index. * * @param int $index Index. * * @since 0.1.0 */ public function step_at( int $index ): ?ActionStep { return $this->actions[ $index ] ?? null; } }