Add hook and basic handler for automation triggers
For now trigger keys are stored in the workflow as a JSON array. This is not optimal in case someone has many workflows but as workflows are user-created it's unlinkely someone will have thousands of them. We can consider adding a workflow_triggers table as well. [MAILPOET-4136]
This commit is contained in:
46
mailpoet/lib/Automation/Engine/Control/TriggerHandler.php
Normal file
46
mailpoet/lib/Automation/Engine/Control/TriggerHandler.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Automation\Engine\Control;
|
||||||
|
|
||||||
|
use MailPoet\Automation\Engine\Exceptions;
|
||||||
|
use MailPoet\Automation\Engine\Hooks;
|
||||||
|
use MailPoet\Automation\Engine\Storage\WorkflowStorage;
|
||||||
|
use MailPoet\Automation\Engine\WordPress;
|
||||||
|
use MailPoet\Automation\Engine\Workflows\Trigger;
|
||||||
|
|
||||||
|
class TriggerHandler {
|
||||||
|
/** @var ActionScheduler */
|
||||||
|
private $actionScheduler;
|
||||||
|
|
||||||
|
/** @var WordPress */
|
||||||
|
private $wordPress;
|
||||||
|
|
||||||
|
/** @var WorkflowStorage */
|
||||||
|
private $workflowStorage;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ActionScheduler $actionScheduler,
|
||||||
|
WordPress $wordPress,
|
||||||
|
WorkflowStorage $workflowStorage
|
||||||
|
) {
|
||||||
|
$this->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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Automation\Engine;
|
namespace MailPoet\Automation\Engine;
|
||||||
|
|
||||||
use MailPoet\Automation\Engine\API\API;
|
use MailPoet\Automation\Engine\API\API;
|
||||||
|
use MailPoet\Automation\Engine\Control\TriggerHandler;
|
||||||
use MailPoet\Automation\Engine\Storage\WorkflowStorage;
|
use MailPoet\Automation\Engine\Storage\WorkflowStorage;
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
@ -12,6 +13,9 @@ class Engine {
|
|||||||
/** @var Registry */
|
/** @var Registry */
|
||||||
private $registry;
|
private $registry;
|
||||||
|
|
||||||
|
/** @var TriggerHandler */
|
||||||
|
private $triggerHandler;
|
||||||
|
|
||||||
/** @var WordPress */
|
/** @var WordPress */
|
||||||
private $wordPress;
|
private $wordPress;
|
||||||
|
|
||||||
@ -21,11 +25,13 @@ class Engine {
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
API $api,
|
API $api,
|
||||||
Registry $registry,
|
Registry $registry,
|
||||||
|
TriggerHandler $triggerHandler,
|
||||||
WordPress $wordPress,
|
WordPress $wordPress,
|
||||||
WorkflowStorage $workflowStorage
|
WorkflowStorage $workflowStorage
|
||||||
) {
|
) {
|
||||||
$this->api = $api;
|
$this->api = $api;
|
||||||
$this->registry = $registry;
|
$this->registry = $registry;
|
||||||
|
$this->triggerHandler = $triggerHandler;
|
||||||
$this->wordPress = $wordPress;
|
$this->wordPress = $wordPress;
|
||||||
$this->workflowStorage = $workflowStorage;
|
$this->workflowStorage = $workflowStorage;
|
||||||
}
|
}
|
||||||
@ -35,6 +41,7 @@ class Engine {
|
|||||||
require_once __DIR__ . '/../../../vendor/woocommerce/action-scheduler/action-scheduler.php';
|
require_once __DIR__ . '/../../../vendor/woocommerce/action-scheduler/action-scheduler.php';
|
||||||
|
|
||||||
$this->api->initialize();
|
$this->api->initialize();
|
||||||
|
$this->triggerHandler->initialize();
|
||||||
|
|
||||||
$this->wordPress->doAction(Hooks::INITIALIZE, [$this->registry]);
|
$this->wordPress->doAction(Hooks::INITIALIZE, [$this->registry]);
|
||||||
$this->registerActiveTriggerHooks();
|
$this->registerActiveTriggerHooks();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Automation\Engine;
|
namespace MailPoet\Automation\Engine;
|
||||||
|
|
||||||
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
|
use MailPoet\Automation\Engine\Exceptions\InvalidStateException;
|
||||||
|
use MailPoet\Automation\Engine\Exceptions\NotFoundException;
|
||||||
use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException;
|
use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException;
|
||||||
|
|
||||||
class Exceptions {
|
class Exceptions {
|
||||||
@ -10,6 +11,7 @@ class Exceptions {
|
|||||||
private const DATABASE_ERROR = 'mailpoet_automation_database_error';
|
private const DATABASE_ERROR = 'mailpoet_automation_database_error';
|
||||||
private const API_METHOD_NOT_ALLOWED = 'mailpoet_automation_api_method_not_allowed';
|
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 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() {
|
public function __construct() {
|
||||||
throw new InvalidStateException(
|
throw new InvalidStateException(
|
||||||
@ -41,4 +43,10 @@ class Exceptions {
|
|||||||
->withErrorCode(self::API_NO_JSON_BODY)
|
->withErrorCode(self::API_NO_JSON_BODY)
|
||||||
->withMessage(__('No JSON body passed.', 'mailpoet'));
|
->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'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,5 @@ namespace MailPoet\Automation\Engine;
|
|||||||
|
|
||||||
class Hooks {
|
class Hooks {
|
||||||
public const INITIALIZE = 'mailpoet/automation/initialize';
|
public const INITIALIZE = 'mailpoet/automation/initialize';
|
||||||
|
public const TRIGGER = 'mailpoet/automation/trigger';
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Automation\Engine\Storage;
|
namespace MailPoet\Automation\Engine\Storage;
|
||||||
|
|
||||||
use MailPoet\Automation\Engine\Exceptions;
|
use MailPoet\Automation\Engine\Exceptions;
|
||||||
|
use MailPoet\Automation\Engine\Workflows\Trigger;
|
||||||
use MailPoet\Automation\Engine\Workflows\Workflow;
|
use MailPoet\Automation\Engine\Workflows\Workflow;
|
||||||
use wpdb;
|
use wpdb;
|
||||||
|
|
||||||
@ -45,4 +46,20 @@ class WorkflowStorage {
|
|||||||
}
|
}
|
||||||
return array_unique($triggerKeys);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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\SystemDatabaseEndpoint::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\Automation\Engine\API\Endpoints\WorkflowsEndpoint::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\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\Engine::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\Automation\Engine\Migrations\Migrator::class)->setPublic(true);
|
$container->autowire(\MailPoet\Automation\Engine\Migrations\Migrator::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\Automation\Engine\Registry::class)->setPublic(true);
|
$container->autowire(\MailPoet\Automation\Engine\Registry::class)->setPublic(true);
|
||||||
|
Reference in New Issue
Block a user