Add "core" automation integration & implement wait action

The "core" integration will provide triggers, actions, and subjects
that are not specific to any 3rd party integration.

[MAILPOET-4136]
This commit is contained in:
Jan Jakes
2022-03-07 16:08:07 +01:00
committed by Veljko V
parent f7866aab49
commit fc16bacadc
6 changed files with 95 additions and 11 deletions

View File

@ -12,4 +12,8 @@ class ActionScheduler {
public function schedule(int $timestamp, string $hook, array $args = []): int { public function schedule(int $timestamp, string $hook, array $args = []): int {
return as_schedule_single_action($timestamp, $hook, $args, self::GROUP_ID); return as_schedule_single_action($timestamp, $hook, $args, self::GROUP_ID);
} }
public function hasScheduledAction(string $hook, array $args = []): bool {
return as_has_scheduled_action($hook, $args, self::GROUP_ID);
}
} }

View File

@ -82,6 +82,12 @@ class StepRunner {
throw Exceptions::workflowNotFound($workflowRun->getWorkflowId()); throw Exceptions::workflowNotFound($workflowRun->getWorkflowId());
} }
// complete workflow run
if (!$stepId) {
$this->workflowRunStorage->updateStatus($workflowRunId, WorkflowRun::STATUS_COMPLETE);
return;
}
$step = $workflow->getStep($stepId); $step = $workflow->getStep($stepId);
if (!$step) { if (!$step) {
throw Exceptions::workflowStepNotFound($stepId); throw Exceptions::workflowStepNotFound($stepId);
@ -94,19 +100,21 @@ class StepRunner {
throw new InvalidStateException(); throw new InvalidStateException();
} }
// enqueue next step / complete workflow $nextStepArgs = [
$nextStepId = $step->getNextStepId(); [
if ($nextStepId) { 'workflow_run_id' => $workflowRunId,
$this->actionScheduler->enqueue(Hooks::WORKFLOW_STEP, [ 'step_id' => $step->getNextStepId(),
[ ],
'workflow_run_id' => $workflowRunId, ];
'step_id' => $nextStepId,
], // next step scheduled by action
]); if ($this->actionScheduler->hasScheduledAction(Hooks::WORKFLOW_STEP, $nextStepArgs)) {
} else { return;
$this->workflowRunStorage->updateStatus($workflowRunId, WorkflowRun::STATUS_COMPLETE);
} }
// enqueue next step
$this->actionScheduler->enqueue(Hooks::WORKFLOW_STEP, $nextStepArgs);
// TODO: allow long-running steps (that are not done here yet) // TODO: allow long-running steps (that are not done here yet)
} }
} }

View File

@ -6,11 +6,15 @@ use MailPoet\Automation\Engine\API\API;
use MailPoet\Automation\Engine\Control\StepRunner; use MailPoet\Automation\Engine\Control\StepRunner;
use MailPoet\Automation\Engine\Control\TriggerHandler; use MailPoet\Automation\Engine\Control\TriggerHandler;
use MailPoet\Automation\Engine\Storage\WorkflowStorage; use MailPoet\Automation\Engine\Storage\WorkflowStorage;
use MailPoet\Automation\Integrations\Core\CoreIntegration;
class Engine { class Engine {
/** @var API */ /** @var API */
private $api; private $api;
/** @var CoreIntegration */
private $coreIntegration;
/** @var Registry */ /** @var Registry */
private $registry; private $registry;
@ -28,6 +32,7 @@ class Engine {
public function __construct( public function __construct(
API $api, API $api,
CoreIntegration $coreIntegration,
Registry $registry, Registry $registry,
StepRunner $stepRunner, StepRunner $stepRunner,
TriggerHandler $triggerHandler, TriggerHandler $triggerHandler,
@ -35,6 +40,7 @@ class Engine {
WorkflowStorage $workflowStorage WorkflowStorage $workflowStorage
) { ) {
$this->api = $api; $this->api = $api;
$this->coreIntegration = $coreIntegration;
$this->registry = $registry; $this->registry = $registry;
$this->stepRunner = $stepRunner; $this->stepRunner = $stepRunner;
$this->triggerHandler = $triggerHandler; $this->triggerHandler = $triggerHandler;
@ -50,6 +56,7 @@ class Engine {
$this->stepRunner->initialize(); $this->stepRunner->initialize();
$this->triggerHandler->initialize(); $this->triggerHandler->initialize();
$this->coreIntegration->register($this->registry);
$this->wordPress->doAction(Hooks::INITIALIZE, [$this->registry]); $this->wordPress->doAction(Hooks::INITIALIZE, [$this->registry]);
$this->registerActiveTriggerHooks(); $this->registerActiveTriggerHooks();
} }

View File

@ -0,0 +1,40 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\Core\Actions;
use MailPoet\Automation\Engine\Control\ActionScheduler;
use MailPoet\Automation\Engine\Hooks;
use MailPoet\Automation\Engine\Workflows\Action;
use MailPoet\Automation\Engine\Workflows\Step;
use MailPoet\Automation\Engine\Workflows\Workflow;
use MailPoet\Automation\Engine\Workflows\WorkflowRun;
class WaitAction implements Action {
/** @var ActionScheduler */
private $actionScheduler;
public function __construct(
ActionScheduler $actionScheduler
) {
$this->actionScheduler = $actionScheduler;
}
public function getKey(): string {
return 'core:wait';
}
public function getName(): string {
return __('Wait', 'mailpoet');
}
public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void {
$this->actionScheduler->schedule(time() + $step->getArgs()['seconds'], Hooks::WORKFLOW_STEP, [
[
'workflow_run_id' => $workflowRun->getId(),
'step_id' => $step->getNextStepId(),
],
]);
// TODO: call a step complete ($id) hook instead?
}
}

View File

@ -0,0 +1,22 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\Core;
use MailPoet\Automation\Engine\Integration;
use MailPoet\Automation\Engine\Registry;
use MailPoet\Automation\Integrations\Core\Actions\WaitAction;
class CoreIntegration implements Integration {
/** @var WaitAction */
private $waitAction;
public function __construct(
WaitAction $waitAction
) {
$this->waitAction = $waitAction;
}
public function register(Registry $registry): void {
$registry->addAction($this->waitAction);
}
}

View File

@ -118,6 +118,9 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Automation\Engine\Storage\WorkflowRunStorage::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Storage\WorkflowRunStorage::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\Storage\WorkflowStorage::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Storage\WorkflowStorage::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Engine\WordPress::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\WordPress::class)->setPublic(true);
// Automation - core integration
$container->autowire(\MailPoet\Automation\Integrations\Core\Actions\WaitAction::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\Core\CoreIntegration::class)->setPublic(true);
// Automation - MailPoet integration // Automation - MailPoet integration
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\MailPoetIntegration::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\MailPoetIntegration::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Subjects\SegmentSubject::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Subjects\SegmentSubject::class)->setPublic(true);