diff --git a/mailpoet/lib/Automation/Engine/Control/TriggerHandler.php b/mailpoet/lib/Automation/Engine/Control/TriggerHandler.php new file mode 100644 index 0000000000..60d5c9f63c --- /dev/null +++ b/mailpoet/lib/Automation/Engine/Control/TriggerHandler.php @@ -0,0 +1,46 @@ +actionScheduler = $actionScheduler; + $this->wordPress = $wordPress; + $this->workflowStorage = $workflowStorage; + } + + public function initialize(): void { + $this->wordPress->addAction(Hooks::TRIGGER, [$this, 'processTrigger']); + } + + public function processTrigger(Trigger $trigger): void { + $workflows = $this->workflowStorage->getActiveWorkflowsByTrigger($trigger); + foreach ($workflows as $workflow) { + $step = $workflow->getTrigger($trigger->getKey()); + if (!$step) { + throw Exceptions::workflowTriggerNotFound($workflow->getId(), $trigger->getKey()); + } + + // TODO: create new workflow run + } + } +} diff --git a/mailpoet/lib/Automation/Engine/Engine.php b/mailpoet/lib/Automation/Engine/Engine.php index efa497c986..d74b6b16cc 100644 --- a/mailpoet/lib/Automation/Engine/Engine.php +++ b/mailpoet/lib/Automation/Engine/Engine.php @@ -3,6 +3,7 @@ namespace MailPoet\Automation\Engine; use MailPoet\Automation\Engine\API\API; +use MailPoet\Automation\Engine\Control\TriggerHandler; use MailPoet\Automation\Engine\Storage\WorkflowStorage; class Engine { @@ -12,6 +13,9 @@ class Engine { /** @var Registry */ private $registry; + /** @var TriggerHandler */ + private $triggerHandler; + /** @var WordPress */ private $wordPress; @@ -21,11 +25,13 @@ class Engine { public function __construct( API $api, Registry $registry, + TriggerHandler $triggerHandler, WordPress $wordPress, WorkflowStorage $workflowStorage ) { $this->api = $api; $this->registry = $registry; + $this->triggerHandler = $triggerHandler; $this->wordPress = $wordPress; $this->workflowStorage = $workflowStorage; } @@ -35,6 +41,7 @@ class Engine { require_once __DIR__ . '/../../../vendor/woocommerce/action-scheduler/action-scheduler.php'; $this->api->initialize(); + $this->triggerHandler->initialize(); $this->wordPress->doAction(Hooks::INITIALIZE, [$this->registry]); $this->registerActiveTriggerHooks(); diff --git a/mailpoet/lib/Automation/Engine/Exceptions.php b/mailpoet/lib/Automation/Engine/Exceptions.php index 869559e59c..d5d7148b55 100644 --- a/mailpoet/lib/Automation/Engine/Exceptions.php +++ b/mailpoet/lib/Automation/Engine/Exceptions.php @@ -3,6 +3,7 @@ namespace MailPoet\Automation\Engine; use MailPoet\Automation\Engine\Exceptions\InvalidStateException; +use MailPoet\Automation\Engine\Exceptions\NotFoundException; use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException; class Exceptions { @@ -10,6 +11,7 @@ class Exceptions { private const DATABASE_ERROR = 'mailpoet_automation_database_error'; private const API_METHOD_NOT_ALLOWED = 'mailpoet_automation_api_method_not_allowed'; private const API_NO_JSON_BODY = 'mailpoet_automation_api_no_json_body'; + private const WORKFLOW_TRIGGER_NOT_FOUND = 'mailpoet_automation_workflow_trigger_not_found'; public function __construct() { throw new InvalidStateException( @@ -41,4 +43,10 @@ class Exceptions { ->withErrorCode(self::API_NO_JSON_BODY) ->withMessage(__('No JSON body passed.', 'mailpoet')); } + + public static function workflowTriggerNotFound(int $workflowId, string $key): NotFoundException { + return NotFoundException::create() + ->withErrorCode(self::WORKFLOW_TRIGGER_NOT_FOUND) + ->withMessage(__(sprintf("Workflow trigger with key '%s' not found in workflow ID '%s'.", $key, $workflowId), 'mailpoet')); + } } diff --git a/mailpoet/lib/Automation/Engine/Hooks.php b/mailpoet/lib/Automation/Engine/Hooks.php index 76f67ed48a..5507ac60ab 100644 --- a/mailpoet/lib/Automation/Engine/Hooks.php +++ b/mailpoet/lib/Automation/Engine/Hooks.php @@ -4,4 +4,5 @@ namespace MailPoet\Automation\Engine; class Hooks { public const INITIALIZE = 'mailpoet/automation/initialize'; + public const TRIGGER = 'mailpoet/automation/trigger'; } diff --git a/mailpoet/lib/Automation/Engine/Storage/WorkflowStorage.php b/mailpoet/lib/Automation/Engine/Storage/WorkflowStorage.php index 27001d3798..0605801e62 100644 --- a/mailpoet/lib/Automation/Engine/Storage/WorkflowStorage.php +++ b/mailpoet/lib/Automation/Engine/Storage/WorkflowStorage.php @@ -3,6 +3,7 @@ namespace MailPoet\Automation\Engine\Storage; use MailPoet\Automation\Engine\Exceptions; +use MailPoet\Automation\Engine\Workflows\Trigger; use MailPoet\Automation\Engine\Workflows\Workflow; use wpdb; @@ -45,4 +46,20 @@ class WorkflowStorage { } return array_unique($triggerKeys); } + + /** @return Workflow[] */ + public function getActiveWorkflowsByTrigger(Trigger $trigger): array { + $query = strval( + $this->wpdb->prepare( + "SELECT * FROM $this->table WHERE status = %s AND trigger_keys LIKE %s", + Workflow::STATUS_ACTIVE, + '%' . $this->wpdb->esc_like($trigger->getKey()) . '%' + ) + ); + + $data = $this->wpdb->get_results($query, ARRAY_A); + return array_map(function (array $workflowData) { + return Workflow::fromArray($workflowData); + }, (array)$data); + } } diff --git a/mailpoet/lib/DI/ContainerConfigurator.php b/mailpoet/lib/DI/ContainerConfigurator.php index 739826a5ec..822d6ac52a 100644 --- a/mailpoet/lib/DI/ContainerConfigurator.php +++ b/mailpoet/lib/DI/ContainerConfigurator.php @@ -108,6 +108,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\Automation\Engine\API\Endpoints\SystemDatabaseEndpoint::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\API\Endpoints\WorkflowsEndpoint::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Builder\CreateWorkflowController::class)->setPublic(true); + $container->autowire(\MailPoet\Automation\Engine\Control\TriggerHandler::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Engine::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Migrations\Migrator::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Engine\Registry::class)->setPublic(true);