Files
piratepoet/mailpoet/lib/Automation/Integrations/WooCommerce/Triggers/BuysAProductTrigger.php
David Remer a7f66d9812 Add BuysAProduct trigger backend
[MAILPOET-5516]
2023-09-25 07:11:43 -07:00

155 lines
4.4 KiB
PHP

<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\WooCommerce\Triggers;
use MailPoet\Automation\Engine\Control\FilterHandler;
use MailPoet\Automation\Engine\Data\Field;
use MailPoet\Automation\Engine\Data\Filter;
use MailPoet\Automation\Engine\Data\FilterGroup;
use MailPoet\Automation\Engine\Data\StepRunArgs;
use MailPoet\Automation\Engine\Data\StepValidationArgs;
use MailPoet\Automation\Engine\Data\Subject;
use MailPoet\Automation\Engine\Hooks;
use MailPoet\Automation\Engine\Integration\Trigger;
use MailPoet\Automation\Engine\Storage\AutomationRunStorage;
use MailPoet\Automation\Engine\WordPress;
use MailPoet\Automation\Integrations\Core\Filters\EnumArrayFilter;
use MailPoet\Automation\Integrations\Core\Filters\EnumFilter;
use MailPoet\Automation\Integrations\WooCommerce\Subjects\CustomerSubject;
use MailPoet\Automation\Integrations\WooCommerce\Subjects\OrderStatusChangeSubject;
use MailPoet\Automation\Integrations\WooCommerce\Subjects\OrderSubject;
use MailPoet\Validator\Builder;
use MailPoet\Validator\Schema\ObjectSchema;
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
class BuysAProductTrigger implements Trigger {
public const KEY = 'woocommerce:buys-a-product';
/** @var WordPress */
private $wp;
/** @var WooCommerceHelper */
private $wc;
/** @var AutomationRunStorage */
private $automationRunStorage;
/** @var FilterHandler */
private $filterHandler;
public function __construct(
WordPress $wp,
WooCommerceHelper $wc,
AutomationRunStorage $automationRunStorage,
FilterHandler $filterHandler
) {
$this->wp = $wp;
$this->wc = $wc;
$this->automationRunStorage = $automationRunStorage;
$this->filterHandler = $filterHandler;
}
public function getKey(): string {
return self::KEY;
}
public function getName(): string {
return __('Customer buys a product', 'mailpoet');
}
public function getArgsSchema(): ObjectSchema {
return Builder::object([
'product_ids' => Builder::array(
Builder::integer()
)->minItems(1)->required(),
'to' => Builder::string()->required()->default('wc-completed'),
]);
}
public function getSubjectKeys(): array {
return [
OrderSubject::KEY,
OrderStatusChangeSubject::KEY,
CustomerSubject::KEY,
];
}
public function validate(StepValidationArgs $args): void {
}
public function registerHooks(): void {
$this->wp->addAction(
'woocommerce_order_status_changed',
[
$this,
'handle',
],
10,
3
);
}
/**
* @param int $orderId
* @param string $from
* @param string $to
* @return void
*/
public function handle($orderId, $from, $to): void {
$order = $this->wc->wcGetOrder($orderId);
if (!$order) {
return;
}
$this->wp->doAction(Hooks::TRIGGER, $this, [
new Subject(OrderSubject::KEY, ['order_id' => $orderId]),
new Subject(CustomerSubject::KEY, ['customer_id' => $order->get_customer_id()]),
new Subject(OrderStatusChangeSubject::KEY, ['from' => $from, 'to' => $to]),
]);
}
public function isTriggeredBy(StepRunArgs $args): bool {
//Trigger the run only once.
$orderSubjectData = $args->getSingleSubjectEntryByClass(OrderSubject::class)->getSubjectData();
if ($this->automationRunStorage->getCountByAutomationAndSubject($args->getAutomation(), $orderSubjectData) > 0) {
return false;
}
$group = new FilterGroup(
'',
FilterGroup::OPERATOR_AND,
$this->getFilters($args)
);
return $this->filterHandler->matchesGroup($group, $args);
}
protected function getFilters(StepRunArgs $args): array {
$triggerArgs = $args->getStep()->getArgs();
$filters = [
Filter::fromArray([
'id' => '',
'field_type' => Field::TYPE_ENUM_ARRAY,
'field_key' => 'woocommerce:order:products',
'condition' => EnumArrayFilter::CONDITION_MATCHES_ANY_OF,
'args' => [
'value' => $triggerArgs['product_ids'] ?? [],
],
]),
];
$status = str_replace('wc-', '', $triggerArgs['to'] ?? 'completed');
if ($status === 'any') {
return $filters;
}
$filters[] = Filter::fromArray([
'id' => '',
'field_type' => Field::TYPE_ENUM,
'field_key' => 'woocommerce:order:status',
'condition' => EnumFilter::IS_ANY_OF,
'args' => [
'value' => [$status],
],
]);
return $filters;
}
}