Interrupt automation run creation if a run already exists and only_once setting is set

[MAILPOET-4966]
This commit is contained in:
David Remer
2023-02-16 08:31:43 +02:00
committed by Aschepikov
parent 38e7346b6e
commit fcf6e738c7
5 changed files with 81 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ namespace MailPoet\Automation\Engine\Storage;
use MailPoet\Automation\Engine\Data\Automation; use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Engine\Data\AutomationRun; use MailPoet\Automation\Engine\Data\AutomationRun;
use MailPoet\Automation\Engine\Data\Subject;
use MailPoet\Automation\Engine\Exceptions; use MailPoet\Automation\Engine\Exceptions;
use wpdb; use wpdb;
@@ -108,6 +109,26 @@ class AutomationRunStorage {
); );
} }
/**
* @param Automation $automation
* @return int
*/
public function countRunsForAutomationAndSubject(Automation $automation, Subject $subject): int {
$table = esc_sql($this->table);
$subjectTable = esc_sql($this->subjectTable);
$sql = "SELECT count(runs.id) as count from $table as runs
JOIN $subjectTable as subjects on runs.id = subjects.automation_run_id
WHERE runs.automation_id = %d
AND subjects.hash = %s";
$result = $this->wpdb->get_col(
(string)$this->wpdb->prepare($sql, $automation->getId(), $subject->hash())
);
return $result ? (int)current($result) : 0;
}
public function getCountForAutomation(Automation $automation, string ...$status): int { public function getCountForAutomation(Automation $automation, string ...$status): int {
if (!count($status)) { if (!count($status)) {
return 0; return 0;

View File

@@ -0,0 +1,49 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\MailPoet\Hooks;
use MailPoet\Automation\Engine\Data\StepRunArgs;
use MailPoet\Automation\Engine\Hooks;
use MailPoet\Automation\Engine\Storage\AutomationRunStorage;
use MailPoet\Automation\Integrations\MailPoet\Subjects\SubscriberSubject;
use MailPoet\WP\Functions;
class CreateAutomationRunHook {
/** @var Functions */
private $wp;
private $automationRunStorage;
public function __construct(
Functions $wp,
AutomationRunStorage $automationRunStorage
) {
$this->wp = $wp;
$this->automationRunStorage = $automationRunStorage;
}
public function init(): void {
$this->wp->addAction(Hooks::AUTOMATION_RUN_CREATE, [$this, 'createAutomationRun'], 5, 2);
}
public function createAutomationRun(bool $result, StepRunArgs $args): bool {
if (!$result) {
return $result;
}
$automation = $args->getAutomation();
$runOnlyOnce = $automation->getMeta('run_automation_once');
if (!$runOnlyOnce) {
return true;
}
$subscriberSubject = $args->getAutomationRun()->getSubjects(SubscriberSubject::KEY);
if (!$subscriberSubject) {
return true;
}
return $this->automationRunStorage->countRunsForAutomationAndSubject($automation, current($subscriberSubject)) === 0;
}
}

View File

@@ -6,6 +6,7 @@ use MailPoet\Automation\Engine\Integration;
use MailPoet\Automation\Engine\Registry; use MailPoet\Automation\Engine\Registry;
use MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction; use MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction;
use MailPoet\Automation\Integrations\MailPoet\Hooks\AutomationEditorLoadingHooks; use MailPoet\Automation\Integrations\MailPoet\Hooks\AutomationEditorLoadingHooks;
use MailPoet\Automation\Integrations\MailPoet\Hooks\CreateAutomationRunHook;
use MailPoet\Automation\Integrations\MailPoet\Subjects\SegmentSubject; use MailPoet\Automation\Integrations\MailPoet\Subjects\SegmentSubject;
use MailPoet\Automation\Integrations\MailPoet\Subjects\SubscriberSubject; use MailPoet\Automation\Integrations\MailPoet\Subjects\SubscriberSubject;
use MailPoet\Automation\Integrations\MailPoet\Triggers\SomeoneSubscribesTrigger; use MailPoet\Automation\Integrations\MailPoet\Triggers\SomeoneSubscribesTrigger;
@@ -30,8 +31,12 @@ class MailPoetIntegration implements Integration {
/** @var SendEmailAction */ /** @var SendEmailAction */
private $sendEmailAction; private $sendEmailAction;
/** @var AutomationEditorLoadingHooks */
private $automationEditorLoadingHooks; private $automationEditorLoadingHooks;
/** @var CreateAutomationRunHook */
private $createAutomationRunHook;
public function __construct( public function __construct(
ContextFactory $contextFactory, ContextFactory $contextFactory,
SegmentSubject $segmentSubject, SegmentSubject $segmentSubject,
@@ -39,7 +44,8 @@ class MailPoetIntegration implements Integration {
SomeoneSubscribesTrigger $someoneSubscribesTrigger, SomeoneSubscribesTrigger $someoneSubscribesTrigger,
UserRegistrationTrigger $userRegistrationTrigger, UserRegistrationTrigger $userRegistrationTrigger,
SendEmailAction $sendEmailAction, SendEmailAction $sendEmailAction,
AutomationEditorLoadingHooks $automationEditorLoadingHooks AutomationEditorLoadingHooks $automationEditorLoadingHooks,
CreateAutomationRunHook $createAutomationRunHook
) { ) {
$this->contextFactory = $contextFactory; $this->contextFactory = $contextFactory;
$this->segmentSubject = $segmentSubject; $this->segmentSubject = $segmentSubject;
@@ -48,6 +54,7 @@ class MailPoetIntegration implements Integration {
$this->userRegistrationTrigger = $userRegistrationTrigger; $this->userRegistrationTrigger = $userRegistrationTrigger;
$this->sendEmailAction = $sendEmailAction; $this->sendEmailAction = $sendEmailAction;
$this->automationEditorLoadingHooks = $automationEditorLoadingHooks; $this->automationEditorLoadingHooks = $automationEditorLoadingHooks;
$this->createAutomationRunHook = $createAutomationRunHook;
} }
public function register(Registry $registry): void { public function register(Registry $registry): void {
@@ -68,5 +75,6 @@ class MailPoetIntegration implements Integration {
); );
$this->automationEditorLoadingHooks->init(); $this->automationEditorLoadingHooks->init();
$this->createAutomationRunHook->init();
} }
} }

View File

@@ -162,6 +162,7 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Templates\AutomationBuilder::class)->setPublic(true)->setShared(false); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Templates\AutomationBuilder::class)->setPublic(true)->setShared(false);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Actions\SendEmailAction::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Hooks\AutomationEditorLoadingHooks::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Hooks\AutomationEditorLoadingHooks::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Hooks\CreateAutomationRunHook::class)->setPublic(true);
// Config // Config
$container->autowire(\MailPoet\Config\AccessControl::class)->setPublic(true); $container->autowire(\MailPoet\Config\AccessControl::class)->setPublic(true);
$container->autowire(\MailPoet\Config\Activator::class)->setPublic(true); $container->autowire(\MailPoet\Config\Activator::class)->setPublic(true);

View File

@@ -44,7 +44,7 @@ parameters:
- '/Call to method getName\(\) on an unknown class _generated\\([a-zA-Z])*Cookie/' # codeception generate incorrect return type in ../../tests/_support/_generated - '/Call to method getName\(\) on an unknown class _generated\\([a-zA-Z])*Cookie/' # codeception generate incorrect return type in ../../tests/_support/_generated
- -
message: "#^Cannot cast string|void to string\\.$#" message: "#^Cannot cast string|void to string\\.$#"
count: 9 count: 10
path: ../../lib/Automation/Engine/Storage/AutomationRunStorage.php path: ../../lib/Automation/Engine/Storage/AutomationRunStorage.php
- -
message: "#^Cannot cast string|void to string\\.$#" message: "#^Cannot cast string|void to string\\.$#"