Files
piratepoet/mailpoet/lib/Automation/Engine/Data/WorkflowRun.php
David Remer 02489a61a6 Add version_id to WorkflowRun
[MAILPOET-4430]
2022-08-10 16:57:25 +02:00

164 lines
4.0 KiB
PHP

<?php declare(strict_types = 1);
namespace MailPoet\Automation\Engine\Data;
use DateTimeImmutable;
use MailPoet\Automation\Engine\Exceptions;
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
use MailPoet\Automation\Engine\Utils\Json;
use MailPoet\Automation\Engine\Workflows\Subject;
class WorkflowRun {
public const STATUS_RUNNING = 'running';
public const STATUS_COMPLETE = 'complete';
public const STATUS_CANCELLED = 'cancelled';
public const STATUS_FAILED = 'failed';
/** @var int */
private $id;
/** @var int */
private $workflowId;
/** @var int */
private $versionId;
/** @var string */
private $triggerKey;
/** @var string */
private $status = self::STATUS_RUNNING;
/** @var DateTimeImmutable */
private $createdAt;
/** @var DateTimeImmutable */
private $updatedAt;
/** @var Subject[] */
private $subjects;
/** @var array<class-string, string> */
private $subjectKeyClassMap = [];
/**
* @param Subject[] $subjects
*/
public function __construct(
int $workflowId,
int $versionId,
string $triggerKey,
array $subjects,
int $id = null
) {
$this->workflowId = $workflowId;
$this->versionId = $versionId;
$this->triggerKey = $triggerKey;
$this->subjects = $subjects;
foreach ($subjects as $subject) {
$this->subjectKeyClassMap[get_class($subject)] = $subject->getKey();
}
if ($id) {
$this->id = $id;
}
$now = new DateTimeImmutable();
$this->createdAt = $now;
$this->updatedAt = $now;
}
public function getId(): int {
return $this->id;
}
public function getWorkflowId(): int {
return $this->workflowId;
}
public function getVersionId(): int {
return $this->workflowId;
}
public function getTriggerKey(): string {
return $this->triggerKey;
}
public function getStatus(): string {
return $this->status;
}
public function getCreatedAt(): DateTimeImmutable {
return $this->createdAt;
}
public function getUpdatedAt(): DateTimeImmutable {
return $this->updatedAt;
}
/** @return Subject[] */
public function getSubjects(string $key = null): array {
if ($key) {
return array_values(
array_filter($this->subjects, function (Subject $subject) use ($key) {
return $subject->getKey() === $key;
})
);
}
return $this->subjects;
}
/**
* @template T of Subject
* @param class-string<T> $class
* @return T
*/
public function requireSingleSubject(string $class): Subject {
$key = $this->subjectKeyClassMap[$class] ?? null;
if (!$key) {
throw Exceptions::subjectClassNotFound($class);
}
$subjects = $this->getSubjects($key);
if (count($subjects) === 0) {
throw Exceptions::subjectNotFound($key);
}
if (count($subjects) > 1) {
throw Exceptions::multipleSubjectsFound($key);
}
// ensure PHPStan we're indeed returning an instance of $class
$subject = $subjects[0];
if (!$subject instanceof $class) {
throw new InvalidStateException();
}
return $subject;
}
public function toArray(): array {
return [
'workflow_id' => $this->workflowId,
'version_id' => $this->versionId,
'trigger_key' => $this->triggerKey,
'status' => $this->status,
'created_at' => $this->createdAt->format(DateTimeImmutable::W3C),
'updated_at' => $this->updatedAt->format(DateTimeImmutable::W3C),
'subjects' => Json::encode(
array_map(function (Subject $subject): array {
return ['key' => $subject->getKey(), 'args' => $subject->pack()];
}, $this->subjects)
),
];
}
public static function fromArray(array $data): self {
$workflowRun = new WorkflowRun((int)$data['workflow_id'], (int)$data['version_id'], $data['trigger_key'], $data['subjects']);
$workflowRun->id = (int)$data['id'];
$workflowRun->status = $data['status'];
$workflowRun->createdAt = $data['created_at'];
$workflowRun->updatedAt = $data['updated_at'];
return $workflowRun;
}
}