init
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use DateTimeImmutable;
|
||||
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
|
||||
use MailPoet\Automation\Engine\Utils\Json;
|
||||
|
||||
class Automation {
|
||||
public const STATUS_ACTIVE = 'active';
|
||||
public const STATUS_DEACTIVATING = 'deactivating';
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
public const STATUS_TRASH = 'trash';
|
||||
public const STATUS_ALL = [
|
||||
self::STATUS_ACTIVE,
|
||||
self::STATUS_DEACTIVATING,
|
||||
self::STATUS_DRAFT,
|
||||
self::STATUS_TRASH,
|
||||
];
|
||||
|
||||
/** @var int|null */
|
||||
private $id;
|
||||
|
||||
/** @var int|null */
|
||||
private $versionId;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var \WP_User */
|
||||
private $author;
|
||||
|
||||
/** @var string */
|
||||
private $status = self::STATUS_DRAFT;
|
||||
|
||||
/** @var DateTimeImmutable */
|
||||
private $createdAt;
|
||||
|
||||
/** @var DateTimeImmutable */
|
||||
private $updatedAt;
|
||||
|
||||
/** @var ?DateTimeImmutable */
|
||||
private $activatedAt = null;
|
||||
|
||||
/** @var array<string|int, Step> */
|
||||
private $steps;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private $meta = [];
|
||||
|
||||
/** @param array<string, Step> $steps */
|
||||
public function __construct(
|
||||
string $name,
|
||||
array $steps,
|
||||
\WP_User $author,
|
||||
int $id = null,
|
||||
int $versionId = null
|
||||
) {
|
||||
$this->name = $name;
|
||||
$this->steps = $steps;
|
||||
$this->author = $author;
|
||||
$this->id = $id;
|
||||
$this->versionId = $versionId;
|
||||
|
||||
$now = new DateTimeImmutable();
|
||||
$this->createdAt = $now;
|
||||
$this->updatedAt = $now;
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
if ($this->id === null) {
|
||||
throw InvalidStateException::create()->withMessage('No automation ID was set');
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(int $id): void {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getVersionId(): int {
|
||||
if (!$this->versionId) {
|
||||
throw InvalidStateException::create()->withMessage('No automation version ID was set');
|
||||
}
|
||||
return $this->versionId;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): void {
|
||||
$this->name = $name;
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public function getStatus(): string {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(string $status): void {
|
||||
if ($status === self::STATUS_ACTIVE && $this->status !== self::STATUS_ACTIVE) {
|
||||
$this->activatedAt = new DateTimeImmutable();
|
||||
}
|
||||
$this->status = $status;
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public function getCreatedAt(): DateTimeImmutable {
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function setCreatedAt(DateTimeImmutable $createdAt): void {
|
||||
$this->createdAt = $createdAt;
|
||||
}
|
||||
|
||||
public function getAuthor(): \WP_User {
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function getUpdatedAt(): DateTimeImmutable {
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
public function getActivatedAt(): ?DateTimeImmutable {
|
||||
return $this->activatedAt;
|
||||
}
|
||||
|
||||
/** @return array<string|int, Step> */
|
||||
public function getSteps(): array {
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string|int, Step>
|
||||
*/
|
||||
public function getTriggers(): array {
|
||||
return array_filter(
|
||||
$this->steps,
|
||||
function (Step $step) {
|
||||
return $step->getType() === Step::TYPE_TRIGGER;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** @param array<string|int, Step> $steps */
|
||||
public function setSteps(array $steps): void {
|
||||
$this->steps = $steps;
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public function getStep(string $id): ?Step {
|
||||
return $this->steps[$id] ?? null;
|
||||
}
|
||||
|
||||
public function getTrigger(string $key): ?Step {
|
||||
foreach ($this->steps as $step) {
|
||||
if ($step->getType() === Step::TYPE_TRIGGER && $step->getKey() === $key) {
|
||||
return $step;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function equals(Automation $compare): bool {
|
||||
$compareArray = $compare->toArray();
|
||||
$currentArray = $this->toArray();
|
||||
$ignoreValues = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
foreach ($ignoreValues as $ignore) {
|
||||
unset($compareArray[$ignore]);
|
||||
unset($currentArray[$ignore]);
|
||||
}
|
||||
return $compareArray === $currentArray;
|
||||
}
|
||||
|
||||
public function needsFullValidation(): bool {
|
||||
return in_array($this->status, [Automation::STATUS_ACTIVE, Automation::STATUS_DEACTIVATING], true);
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'status' => $this->status,
|
||||
'author' => $this->author->ID,
|
||||
'created_at' => $this->createdAt->format(DateTimeImmutable::W3C),
|
||||
'updated_at' => $this->updatedAt->format(DateTimeImmutable::W3C),
|
||||
'activated_at' => $this->activatedAt ? $this->activatedAt->format(DateTimeImmutable::W3C) : null,
|
||||
'steps' => Json::encode(
|
||||
array_map(function (Step $step) {
|
||||
return $step->toArray();
|
||||
}, $this->steps)
|
||||
),
|
||||
'meta' => Json::encode($this->meta),
|
||||
];
|
||||
}
|
||||
|
||||
private function setUpdatedAt(): void {
|
||||
$this->updatedAt = new DateTimeImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getMeta(string $key) {
|
||||
return $this->meta[$key] ?? null;
|
||||
}
|
||||
|
||||
public function getAllMetas(): array {
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function setMeta(string $key, $value): void {
|
||||
$this->meta[$key] = $value;
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public function deleteMeta(string $key): void {
|
||||
unset($this->meta[$key]);
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public function deleteAllMetas(): void {
|
||||
$this->meta = [];
|
||||
$this->setUpdatedAt();
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
// TODO: validation
|
||||
$automation = new self(
|
||||
$data['name'],
|
||||
array_map(function (array $stepData): Step {
|
||||
return Step::fromArray($stepData);
|
||||
}, Json::decode($data['steps'])),
|
||||
new \WP_User((int)$data['author'])
|
||||
);
|
||||
$automation->id = (int)$data['id'];
|
||||
$automation->versionId = (int)$data['version_id'];
|
||||
$automation->status = $data['status'];
|
||||
$automation->createdAt = new DateTimeImmutable($data['created_at']);
|
||||
$automation->updatedAt = new DateTimeImmutable($data['updated_at']);
|
||||
$automation->activatedAt = $data['activated_at'] !== null ? new DateTimeImmutable($data['activated_at']) : null;
|
||||
|
||||
$automation->meta = $data['meta'] ? Json::decode($data['meta']) : [];
|
||||
return $automation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
class AutomationRun {
|
||||
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 $automationId;
|
||||
|
||||
/** @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;
|
||||
|
||||
/**
|
||||
* @param Subject[] $subjects
|
||||
*/
|
||||
public function __construct(
|
||||
int $automationId,
|
||||
int $versionId,
|
||||
string $triggerKey,
|
||||
array $subjects,
|
||||
int $id = null
|
||||
) {
|
||||
$this->automationId = $automationId;
|
||||
$this->versionId = $versionId;
|
||||
$this->triggerKey = $triggerKey;
|
||||
$this->subjects = $subjects;
|
||||
|
||||
if ($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
$now = new DateTimeImmutable();
|
||||
$this->createdAt = $now;
|
||||
$this->updatedAt = $now;
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(int $id): void {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getAutomationId(): int {
|
||||
return $this->automationId;
|
||||
}
|
||||
|
||||
public function getVersionId(): int {
|
||||
return $this->versionId;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'automation_id' => $this->automationId,
|
||||
'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' => array_map(function (Subject $subject): array {
|
||||
return $subject->toArray();
|
||||
}, $this->subjects),
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
$automationRun = new AutomationRun(
|
||||
(int)$data['automation_id'],
|
||||
(int)$data['version_id'],
|
||||
$data['trigger_key'],
|
||||
array_map(function (array $subject) {
|
||||
return Subject::fromArray($subject);
|
||||
}, $data['subjects'])
|
||||
);
|
||||
$automationRun->id = (int)$data['id'];
|
||||
$automationRun->status = $data['status'];
|
||||
$automationRun->createdAt = new DateTimeImmutable($data['created_at']);
|
||||
$automationRun->updatedAt = new DateTimeImmutable($data['updated_at']);
|
||||
return $automationRun;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use DateTimeImmutable;
|
||||
use InvalidArgumentException;
|
||||
use MailPoet\Automation\Engine\Utils\Json;
|
||||
use Throwable;
|
||||
|
||||
class AutomationRunLog {
|
||||
public const STATUS_RUNNING = 'running';
|
||||
public const STATUS_COMPLETE = 'complete';
|
||||
public const STATUS_FAILED = 'failed';
|
||||
|
||||
public const STATUS_ALL = [
|
||||
self::STATUS_RUNNING,
|
||||
self::STATUS_COMPLETE,
|
||||
self::STATUS_FAILED,
|
||||
];
|
||||
|
||||
public const TYPE_ACTION = 'action';
|
||||
public const TYPE_TRIGGER = 'trigger';
|
||||
|
||||
public const KEY_UNKNOWN = 'unknown';
|
||||
|
||||
/** @var int */
|
||||
private $id;
|
||||
|
||||
/** @var int */
|
||||
private $automationRunId;
|
||||
|
||||
/** @var string */
|
||||
private $stepId;
|
||||
|
||||
/** @var string */
|
||||
private $stepType;
|
||||
|
||||
/** @var string */
|
||||
private $stepKey;
|
||||
|
||||
/** @var string */
|
||||
private $status;
|
||||
|
||||
/** @var DateTimeImmutable */
|
||||
private $startedAt;
|
||||
|
||||
/** @var DateTimeImmutable */
|
||||
private $updatedAt;
|
||||
|
||||
/** @var int */
|
||||
private $runNumber = 1;
|
||||
|
||||
/** @var array */
|
||||
private $data = [];
|
||||
|
||||
/** @var array|null */
|
||||
private $error;
|
||||
|
||||
public function __construct(
|
||||
int $automationRunId,
|
||||
string $stepId,
|
||||
string $stepType,
|
||||
int $id = null
|
||||
) {
|
||||
$this->automationRunId = $automationRunId;
|
||||
$this->stepId = $stepId;
|
||||
$this->stepType = $stepType;
|
||||
$this->stepKey = self::KEY_UNKNOWN;
|
||||
$this->status = self::STATUS_RUNNING;
|
||||
|
||||
$now = new DateTimeImmutable();
|
||||
$this->startedAt = $now;
|
||||
$this->updatedAt = $now;
|
||||
|
||||
if ($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getAutomationRunId(): int {
|
||||
return $this->automationRunId;
|
||||
}
|
||||
|
||||
public function getStepId(): string {
|
||||
return $this->stepId;
|
||||
}
|
||||
|
||||
public function getStepType(): string {
|
||||
return $this->stepType;
|
||||
}
|
||||
|
||||
public function getStepKey(): string {
|
||||
return $this->stepKey;
|
||||
}
|
||||
|
||||
public function setStepKey(string $stepKey): void {
|
||||
$this->stepKey = $stepKey;
|
||||
$this->updatedAt = new DateTimeImmutable();
|
||||
}
|
||||
|
||||
public function getStatus(): string {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(string $status): void {
|
||||
if (!in_array($status, self::STATUS_ALL, true)) {
|
||||
throw new InvalidArgumentException("Invalid status '$status'.");
|
||||
}
|
||||
$this->status = $status;
|
||||
$this->updatedAt = new DateTimeImmutable();
|
||||
}
|
||||
|
||||
public function getStartedAt(): DateTimeImmutable {
|
||||
return $this->startedAt;
|
||||
}
|
||||
|
||||
public function getUpdatedAt(): DateTimeImmutable {
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
public function getRunNumber(): int {
|
||||
return $this->runNumber;
|
||||
}
|
||||
|
||||
public function setRunNumber(int $runNumber): void {
|
||||
$this->runNumber = $runNumber;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(DateTimeImmutable $updatedAt): void {
|
||||
$this->updatedAt = $updatedAt;
|
||||
}
|
||||
|
||||
public function getData(): array {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/** @param mixed $value */
|
||||
public function setData(string $key, $value): void {
|
||||
if (!$this->isDataStorable($value)) {
|
||||
throw new InvalidArgumentException("Invalid data provided for key '$key'. Only scalar values and arrays of scalar values are allowed.");
|
||||
}
|
||||
$this->data[$key] = $value;
|
||||
$this->updatedAt = new DateTimeImmutable();
|
||||
}
|
||||
|
||||
public function getError(): ?array {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'automation_run_id' => $this->automationRunId,
|
||||
'step_id' => $this->stepId,
|
||||
'step_type' => $this->stepType,
|
||||
'step_key' => $this->stepKey,
|
||||
'status' => $this->status,
|
||||
'started_at' => $this->startedAt->format(DateTimeImmutable::W3C),
|
||||
'updated_at' => $this->updatedAt->format(DateTimeImmutable::W3C),
|
||||
'run_number' => $this->runNumber,
|
||||
'data' => Json::encode($this->data),
|
||||
'error' => $this->error ? Json::encode($this->error) : null,
|
||||
];
|
||||
}
|
||||
|
||||
public function setError(Throwable $error): void {
|
||||
// Normalize all nested objects in error trace to associative arrays.
|
||||
// Empty objects would then get decoded to "[]" instead of "{}".
|
||||
$trace = Json::decode(Json::encode($error->getTrace()));
|
||||
$this->error = [
|
||||
'message' => $error->getMessage(),
|
||||
'errorClass' => get_class($error),
|
||||
'code' => $error->getCode(),
|
||||
'trace' => $trace,
|
||||
];
|
||||
$this->updatedAt = new DateTimeImmutable();
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
$log = new AutomationRunLog((int)$data['automation_run_id'], $data['step_id'], $data['step_type']);
|
||||
$log->id = (int)$data['id'];
|
||||
$log->stepKey = $data['step_key'];
|
||||
$log->status = $data['status'];
|
||||
$log->startedAt = new DateTimeImmutable($data['started_at']);
|
||||
$log->updatedAt = new DateTimeImmutable($data['updated_at']);
|
||||
$log->runNumber = (int)$data['run_number'];
|
||||
$log->data = Json::decode($data['data']);
|
||||
$log->error = isset($data['error']) ? Json::decode($data['error']) : null;
|
||||
return $log;
|
||||
}
|
||||
|
||||
/** @param mixed $data */
|
||||
private function isDataStorable($data): bool {
|
||||
if (is_scalar($data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($data as $value) {
|
||||
if (!$this->isDataStorable($value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class AutomationStatistics {
|
||||
|
||||
private $automationId;
|
||||
private $versionId;
|
||||
private $entered;
|
||||
private $inProgress;
|
||||
|
||||
public function __construct(
|
||||
int $automationId,
|
||||
int $entered = 0,
|
||||
int $inProcess = 0,
|
||||
?int $versionId = null
|
||||
) {
|
||||
$this->automationId = $automationId;
|
||||
$this->entered = $entered;
|
||||
$this->inProgress = $inProcess;
|
||||
$this->versionId = $versionId;
|
||||
}
|
||||
|
||||
public function getAutomationId(): int {
|
||||
return $this->automationId;
|
||||
}
|
||||
|
||||
public function getVersionId(): ?int {
|
||||
return $this->versionId;
|
||||
}
|
||||
|
||||
public function getEntered(): int {
|
||||
return $this->entered;
|
||||
}
|
||||
|
||||
public function getInProgress(): int {
|
||||
return $this->inProgress;
|
||||
}
|
||||
|
||||
public function getExited(): int {
|
||||
return $this->getEntered() - $this->getInProgress();
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'automation_id' => $this->getAutomationId(),
|
||||
'totals' => [
|
||||
'entered' => $this->getEntered(),
|
||||
'in_progress' => $this->getInProgress(),
|
||||
'exited' => $this->getExited(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class AutomationTemplate {
|
||||
public const TYPE_DEFAULT = 'default';
|
||||
public const TYPE_PREMIUM = 'premium';
|
||||
public const TYPE_COMING_SOON = 'coming-soon';
|
||||
|
||||
/** @var string */
|
||||
private $slug;
|
||||
|
||||
/** @var string */
|
||||
private $category;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var string */
|
||||
private $description;
|
||||
|
||||
/** @var callable(): Automation */
|
||||
private $automationFactory;
|
||||
|
||||
/** @var array<string, int|bool> */
|
||||
private $requiredCapabilities;
|
||||
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @param callable(): Automation $automationFactory
|
||||
* @param array<string, int|bool> $requiredCapabilities
|
||||
*/
|
||||
public function __construct(
|
||||
string $slug,
|
||||
string $category,
|
||||
string $name,
|
||||
string $description,
|
||||
callable $automationFactory,
|
||||
array $requiredCapabilities = [],
|
||||
string $type = self::TYPE_DEFAULT
|
||||
) {
|
||||
$this->slug = $slug;
|
||||
$this->category = $category;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->automationFactory = $automationFactory;
|
||||
$this->requiredCapabilities = $requiredCapabilities;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getSlug(): string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getCategory(): string {
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getDescription(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/** @return array<string, int|bool> */
|
||||
public function getRequiredCapabilities(): array {
|
||||
return $this->requiredCapabilities;
|
||||
}
|
||||
|
||||
public function createAutomation(): Automation {
|
||||
return ($this->automationFactory)();
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'slug' => $this->getSlug(),
|
||||
'name' => $this->getName(),
|
||||
'category' => $this->getCategory(),
|
||||
'type' => $this->getType(),
|
||||
'required_capabilities' => $this->getRequiredCapabilities(),
|
||||
'description' => $this->getDescription(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class AutomationTemplateCategory {
|
||||
/** @var string */
|
||||
private $slug;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
public function __construct(
|
||||
string $slug,
|
||||
string $name
|
||||
) {
|
||||
$this->slug = $slug;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getSlug(): string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Automation\Engine\Integration\Payload;
|
||||
|
||||
class Field {
|
||||
public const TYPE_BOOLEAN = 'boolean';
|
||||
public const TYPE_INTEGER = 'integer';
|
||||
public const TYPE_NUMBER = 'number';
|
||||
public const TYPE_STRING = 'string';
|
||||
public const TYPE_ENUM = 'enum';
|
||||
public const TYPE_ENUM_ARRAY = 'enum_array';
|
||||
public const TYPE_DATETIME = 'datetime';
|
||||
|
||||
/** @var string */
|
||||
private $key;
|
||||
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var callable */
|
||||
private $factory;
|
||||
|
||||
/** @var array */
|
||||
private $args;
|
||||
|
||||
public function __construct(
|
||||
string $key,
|
||||
string $type,
|
||||
string $name,
|
||||
callable $factory,
|
||||
array $args = []
|
||||
) {
|
||||
|
||||
$this->key = $key;
|
||||
$this->type = $type;
|
||||
$this->name = $name;
|
||||
$this->factory = $factory;
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
public function getKey(): string {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getFactory(): callable {
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
public function getValue(Payload $payload, array $params = []) {
|
||||
return $this->getFactory()($payload, $params);
|
||||
}
|
||||
|
||||
public function getArgs(): array {
|
||||
return $this->args;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class Filter {
|
||||
/** @var string */
|
||||
private $id;
|
||||
|
||||
/** @var string */
|
||||
private $fieldType;
|
||||
|
||||
/** @var string */
|
||||
private $fieldKey;
|
||||
|
||||
/** @var string */
|
||||
private $condition;
|
||||
|
||||
/** @var array */
|
||||
private $args;
|
||||
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $fieldType,
|
||||
string $fieldKey,
|
||||
string $condition,
|
||||
array $args
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->fieldType = $fieldType;
|
||||
$this->fieldKey = $fieldKey;
|
||||
$this->condition = $condition;
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getFieldType(): string {
|
||||
return $this->fieldType;
|
||||
}
|
||||
|
||||
public function getFieldKey(): string {
|
||||
return $this->fieldKey;
|
||||
}
|
||||
|
||||
public function getCondition(): string {
|
||||
return $this->condition;
|
||||
}
|
||||
|
||||
public function getArgs(): array {
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'field_type' => $this->fieldType,
|
||||
'field_key' => $this->fieldKey,
|
||||
'condition' => $this->condition,
|
||||
'args' => $this->args,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self(
|
||||
$data['id'],
|
||||
$data['field_type'],
|
||||
$data['field_key'],
|
||||
$data['condition'],
|
||||
$data['args']
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class FilterGroup {
|
||||
public const OPERATOR_AND = 'and';
|
||||
public const OPERATOR_OR = 'or';
|
||||
|
||||
/** @var string */
|
||||
private $id;
|
||||
|
||||
/** @var string */
|
||||
private $operator;
|
||||
|
||||
/** @var Filter[] */
|
||||
private $filters;
|
||||
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $operator,
|
||||
array $filters
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->operator = $operator;
|
||||
$this->filters = $filters;
|
||||
}
|
||||
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getOperator(): string {
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
public function getFilters(): array {
|
||||
return $this->filters;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'operator' => $this->operator,
|
||||
'filters' => array_map(function (Filter $filter): array {
|
||||
return $filter->toArray();
|
||||
}, $this->filters),
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self(
|
||||
$data['id'],
|
||||
$data['operator'],
|
||||
array_map(function (array $filter) {
|
||||
return Filter::fromArray($filter);
|
||||
}, $data['filters'])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class Filters {
|
||||
public const OPERATOR_AND = 'and';
|
||||
public const OPERATOR_OR = 'or';
|
||||
|
||||
/** @var string */
|
||||
private $operator;
|
||||
|
||||
/** @var FilterGroup[] */
|
||||
private $groups;
|
||||
|
||||
public function __construct(
|
||||
string $operator,
|
||||
array $groups
|
||||
) {
|
||||
$this->operator = $operator;
|
||||
$this->groups = $groups;
|
||||
}
|
||||
|
||||
public function getOperator(): string {
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
public function getGroups(): array {
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'operator' => $this->operator,
|
||||
'groups' => array_map(function (FilterGroup $group): array {
|
||||
return $group->toArray();
|
||||
}, $this->groups),
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self(
|
||||
$data['operator'],
|
||||
array_map(function (array $group) {
|
||||
return FilterGroup::fromArray($group);
|
||||
}, $data['groups'])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class NextStep {
|
||||
/** @var string|null */
|
||||
protected $id;
|
||||
|
||||
public function __construct(
|
||||
?string $id
|
||||
) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId(): ?string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self($data['id']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
class Step {
|
||||
public const TYPE_ROOT = 'root';
|
||||
public const TYPE_TRIGGER = 'trigger';
|
||||
public const TYPE_ACTION = 'action';
|
||||
|
||||
/** @var string */
|
||||
private $id;
|
||||
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/** @var string */
|
||||
private $key;
|
||||
|
||||
/** @var array */
|
||||
protected $args;
|
||||
|
||||
/** @var NextStep[] */
|
||||
protected $nextSteps;
|
||||
|
||||
/** @var Filters|null */
|
||||
private $filters;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $args
|
||||
* @param NextStep[] $nextSteps
|
||||
*/
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $type,
|
||||
string $key,
|
||||
array $args,
|
||||
array $nextSteps,
|
||||
Filters $filters = null
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->key = $key;
|
||||
$this->args = $args;
|
||||
$this->nextSteps = $nextSteps;
|
||||
$this->filters = $filters;
|
||||
}
|
||||
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getKey(): string {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/** @return NextStep[] */
|
||||
public function getNextSteps(): array {
|
||||
return $this->nextSteps;
|
||||
}
|
||||
|
||||
public function getNextStepIds(): array {
|
||||
$ids = [];
|
||||
foreach ($this->nextSteps as $nextStep) {
|
||||
$nextStepId = $nextStep->getId();
|
||||
if ($nextStepId) {
|
||||
$ids[] = $nextStep->getId();
|
||||
}
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/** @param NextStep[] $nextSteps */
|
||||
public function setNextSteps(array $nextSteps): void {
|
||||
$this->nextSteps = $nextSteps;
|
||||
}
|
||||
|
||||
public function getArgs(): array {
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
public function getFilters(): ?Filters {
|
||||
return $this->filters;
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'key' => $this->key,
|
||||
'args' => $this->args,
|
||||
'next_steps' => array_map(function (NextStep $nextStep) {
|
||||
return $nextStep->toArray();
|
||||
}, $this->nextSteps),
|
||||
'filters' => $this->filters ? $this->filters->toArray() : null,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self(
|
||||
$data['id'],
|
||||
$data['type'],
|
||||
$data['key'],
|
||||
$data['args'],
|
||||
array_map(function (array $nextStep) {
|
||||
return NextStep::fromArray($nextStep);
|
||||
}, $data['next_steps']),
|
||||
isset($data['filters']) ? Filters::fromArray($data['filters']) : null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Automation\Engine\Exceptions;
|
||||
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
|
||||
use MailPoet\Automation\Engine\Integration\Payload;
|
||||
use MailPoet\Automation\Engine\Integration\Subject;
|
||||
use Throwable;
|
||||
|
||||
class StepRunArgs {
|
||||
/** @var Automation */
|
||||
private $automation;
|
||||
|
||||
/** @var AutomationRun */
|
||||
private $automationRun;
|
||||
|
||||
/** @var Step */
|
||||
private $step;
|
||||
|
||||
/** @var array<string, SubjectEntry<Subject<Payload>>[]> */
|
||||
private $subjectEntries = [];
|
||||
|
||||
/** @var array<class-string, string> */
|
||||
private $subjectKeyClassMap = [];
|
||||
|
||||
/** @var array<string, Field> */
|
||||
private $fields = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $fieldToSubjectMap = [];
|
||||
|
||||
/** @var int */
|
||||
private $runNumber;
|
||||
|
||||
/** @param SubjectEntry<Subject<Payload>>[] $subjectsEntries */
|
||||
public function __construct(
|
||||
Automation $automation,
|
||||
AutomationRun $automationRun,
|
||||
Step $step,
|
||||
array $subjectsEntries,
|
||||
int $runNumber
|
||||
) {
|
||||
$this->automation = $automation;
|
||||
$this->step = $step;
|
||||
$this->automationRun = $automationRun;
|
||||
$this->runNumber = $runNumber;
|
||||
|
||||
foreach ($subjectsEntries as $entry) {
|
||||
$subject = $entry->getSubject();
|
||||
$key = $subject->getKey();
|
||||
$this->subjectEntries[$key] = array_merge($this->subjectEntries[$key] ?? [], [$entry]);
|
||||
$this->subjectKeyClassMap[get_class($subject)] = $key;
|
||||
|
||||
foreach ($subject->getFields() as $field) {
|
||||
$this->fields[$field->getKey()] = $field;
|
||||
$this->fieldToSubjectMap[$field->getKey()] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getAutomation(): Automation {
|
||||
return $this->automation;
|
||||
}
|
||||
|
||||
public function getAutomationRun(): AutomationRun {
|
||||
return $this->automationRun;
|
||||
}
|
||||
|
||||
public function getStep(): Step {
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
/** @return array<string, SubjectEntry<Subject<Payload>>[]> */
|
||||
public function getSubjectEntries(): array {
|
||||
return $this->subjectEntries;
|
||||
}
|
||||
|
||||
/** @return SubjectEntry<Subject<Payload>> */
|
||||
public function getSingleSubjectEntry(string $key): SubjectEntry {
|
||||
$subjects = $this->subjectEntries[$key] ?? [];
|
||||
if (count($subjects) === 0) {
|
||||
throw Exceptions::subjectDataNotFound($key, $this->automationRun->getId());
|
||||
}
|
||||
if (count($subjects) > 1) {
|
||||
throw Exceptions::multipleSubjectsFound($key, $this->automationRun->getId());
|
||||
}
|
||||
return $subjects[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @template P of Payload
|
||||
* @template S of Subject<P>
|
||||
* @param class-string<S> $class
|
||||
* @return SubjectEntry<S<P>>
|
||||
*/
|
||||
public function getSingleSubjectEntryByClass(string $class): SubjectEntry {
|
||||
$key = $this->subjectKeyClassMap[$class] ?? null;
|
||||
if (!$key) {
|
||||
throw Exceptions::subjectClassNotFound($class);
|
||||
}
|
||||
|
||||
/** @var SubjectEntry<S<P>> $entry -- for PHPStan */
|
||||
$entry = $this->getSingleSubjectEntry($key);
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template P of Payload
|
||||
* @param class-string<P> $class
|
||||
* @return P
|
||||
*/
|
||||
public function getSinglePayloadByClass(string $class): Payload {
|
||||
$payloads = [];
|
||||
foreach ($this->subjectEntries as $entries) {
|
||||
foreach ($entries as $entry) {
|
||||
$payload = $entry->getPayload();
|
||||
if (get_class($payload) === $class) {
|
||||
$payloads[] = $payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($payloads) === 0) {
|
||||
throw Exceptions::payloadNotFound($class, $this->automationRun->getId());
|
||||
}
|
||||
if (count($payloads) > 1) {
|
||||
throw Exceptions::multiplePayloadsFound($class, $this->automationRun->getId());
|
||||
}
|
||||
|
||||
// ensure PHPStan we're indeed returning an instance of $class
|
||||
$payload = $payloads[0];
|
||||
if (!$payload instanceof $class) {
|
||||
throw InvalidStateException::create();
|
||||
}
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
public function getFieldValue(string $key, array $params = []) {
|
||||
$field = $this->fields[$key] ?? null;
|
||||
$subjectKey = $this->fieldToSubjectMap[$key] ?? null;
|
||||
if (!$field || !$subjectKey) {
|
||||
throw Exceptions::fieldNotFound($key);
|
||||
}
|
||||
|
||||
$entry = $this->getSingleSubjectEntry($subjectKey);
|
||||
try {
|
||||
$value = $field->getValue($entry->getPayload(), $params);
|
||||
} catch (Throwable $e) {
|
||||
throw Exceptions::fieldLoadFailed($field->getKey(), $field->getArgs());
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getRunNumber(): int {
|
||||
return $this->runNumber;
|
||||
}
|
||||
|
||||
public function isFirstRun(): bool {
|
||||
return $this->runNumber === 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Automation\Engine\Exceptions;
|
||||
use MailPoet\Automation\Engine\Integration\Payload;
|
||||
use MailPoet\Automation\Engine\Integration\Subject;
|
||||
|
||||
class StepValidationArgs {
|
||||
/** @var Automation */
|
||||
private $automation;
|
||||
|
||||
/** @var Step */
|
||||
private $step;
|
||||
|
||||
/** @var array<string, Subject<Payload>> */
|
||||
private $subjects = [];
|
||||
|
||||
/** @var array<class-string, string> */
|
||||
private $subjectKeyClassMap = [];
|
||||
|
||||
/** @param Subject<Payload>[] $subjects */
|
||||
public function __construct(
|
||||
Automation $automation,
|
||||
Step $step,
|
||||
array $subjects
|
||||
) {
|
||||
$this->automation = $automation;
|
||||
$this->step = $step;
|
||||
|
||||
foreach ($subjects as $subject) {
|
||||
$key = $subject->getKey();
|
||||
$this->subjects[$key] = $subject;
|
||||
$this->subjectKeyClassMap[get_class($subject)] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
public function getAutomation(): Automation {
|
||||
return $this->automation;
|
||||
}
|
||||
|
||||
public function getStep(): Step {
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
/** @return Subject<Payload>[] */
|
||||
public function getSubjects(): array {
|
||||
return array_values($this->subjects);
|
||||
}
|
||||
|
||||
/** @return Subject<Payload> */
|
||||
public function getSingleSubject(string $key): Subject {
|
||||
$subject = $this->subjects[$key] ?? null;
|
||||
if (!$subject) {
|
||||
throw Exceptions::subjectNotFound($key);
|
||||
}
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template P of Payload
|
||||
* @template S of Subject<P>
|
||||
* @param class-string<S> $class
|
||||
* @return S<P>
|
||||
*/
|
||||
public function getSingleSubjectByClass(string $class): Subject {
|
||||
$key = $this->subjectKeyClassMap[$class] ?? null;
|
||||
if (!$key) {
|
||||
throw Exceptions::subjectClassNotFound($class);
|
||||
}
|
||||
|
||||
/** @var S<P> $subject -- for PHPStan */
|
||||
$subject = $this->getSingleSubject($key);
|
||||
return $subject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Automation\Engine\Utils\Json;
|
||||
|
||||
class Subject {
|
||||
/** @var string */
|
||||
private $key;
|
||||
|
||||
/** @var array */
|
||||
private $args;
|
||||
|
||||
public function __construct(
|
||||
string $key,
|
||||
array $args
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
public function getKey(): string {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getArgs(): array {
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
public function getHash(): string {
|
||||
return md5($this->getKey() . serialize($this->getArgs()));
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
return [
|
||||
'key' => $this->getKey(),
|
||||
'args' => Json::encode($this->getArgs()),
|
||||
'hash' => $this->getHash(),
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self {
|
||||
return new self($data['key'], Json::decode($data['args']));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Automation\Engine\Data;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Automation\Engine\Data\Subject as SubjectData;
|
||||
use MailPoet\Automation\Engine\Exceptions;
|
||||
use MailPoet\Automation\Engine\Integration\Payload;
|
||||
use MailPoet\Automation\Engine\Integration\Subject;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* @template-covariant S of Subject<Payload>
|
||||
*/
|
||||
class SubjectEntry {
|
||||
/** @var S */
|
||||
private $subject;
|
||||
|
||||
/** @var SubjectData */
|
||||
private $subjectData;
|
||||
|
||||
/** @var Payload|null */
|
||||
private $payloadCache;
|
||||
|
||||
/** @param S $subject */
|
||||
public function __construct(
|
||||
Subject $subject,
|
||||
SubjectData $subjectData
|
||||
) {
|
||||
$this->subject = $subject;
|
||||
$this->subjectData = $subjectData;
|
||||
}
|
||||
|
||||
/** @return S */
|
||||
public function getSubject(): Subject {
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
public function getSubjectData(): SubjectData {
|
||||
return $this->subjectData;
|
||||
}
|
||||
|
||||
/** @return Payload */
|
||||
public function getPayload() {
|
||||
if ($this->payloadCache === null) {
|
||||
try {
|
||||
$this->payloadCache = $this->subject->getPayload($this->subjectData);
|
||||
} catch (Throwable $e) {
|
||||
throw Exceptions::subjectLoadFailed($this->subject->getKey(), $this->subjectData->getArgs());
|
||||
}
|
||||
}
|
||||
return $this->payloadCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
Reference in New Issue
Block a user