diff --git a/lib/API/JSON/v1/DynamicSegments.php b/lib/API/JSON/v1/DynamicSegments.php index c2e366a8e3..a698f3f80f 100644 --- a/lib/API/JSON/v1/DynamicSegments.php +++ b/lib/API/JSON/v1/DynamicSegments.php @@ -135,6 +135,8 @@ class DynamicSegments extends APIEndpoint { return WPFunctions::get()->__('Please select product.', 'mailpoet'); case InvalidFilterException::MISSING_CATEGORY_ID: return WPFunctions::get()->__('Please select category.', 'mailpoet'); + case InvalidFilterException::MISSING_VALUE: + return WPFunctions::get()->__('Please fill all required values.', 'mailpoet'); default: return WPFunctions::get()->__('An error occurred while saving data.', 'mailpoet'); } diff --git a/lib/Segments/DynamicSegments/Exceptions/InvalidFilterException.php b/lib/Segments/DynamicSegments/Exceptions/InvalidFilterException.php index 437cf24254..b0e820595f 100644 --- a/lib/Segments/DynamicSegments/Exceptions/InvalidFilterException.php +++ b/lib/Segments/DynamicSegments/Exceptions/InvalidFilterException.php @@ -14,5 +14,6 @@ class InvalidFilterException extends InvalidStateException { const MISSING_CATEGORY_ID = 6; const MISSING_PRODUCT_ID = 7; const INVALID_EMAIL_ACTION = 8; + const MISSING_VALUE = 9; }; diff --git a/lib/Segments/DynamicSegments/FilterDataMapper.php b/lib/Segments/DynamicSegments/FilterDataMapper.php index 425fb92281..c7310326f9 100644 --- a/lib/Segments/DynamicSegments/FilterDataMapper.php +++ b/lib/Segments/DynamicSegments/FilterDataMapper.php @@ -5,6 +5,7 @@ namespace MailPoet\Segments\DynamicSegments; use MailPoet\Entities\DynamicSegmentFilterData; use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException; use MailPoet\Segments\DynamicSegments\Filters\EmailAction; +use MailPoet\Segments\DynamicSegments\Filters\EmailOpensAbsoluteCountAction; use MailPoet\Segments\DynamicSegments\Filters\WooCommerceCategory; use MailPoet\Segments\DynamicSegments\Filters\WooCommerceProduct; @@ -41,8 +42,9 @@ class FilterDataMapper { */ private function createEmail(array $data): DynamicSegmentFilterData { if (empty($data['action'])) throw new InvalidFilterException('Missing action', InvalidFilterException::MISSING_ACTION); - if (empty($data['newsletter_id'])) throw new InvalidFilterException('Missing newsletter id', InvalidFilterException::MISSING_NEWSLETTER_ID); if (!in_array($data['action'], EmailAction::ALLOWED_ACTIONS)) throw new InvalidFilterException('Invalid email action', InvalidFilterException::INVALID_EMAIL_ACTION); + if ($data['action'] === EmailOpensAbsoluteCountAction::TYPE) return $this->createEmailOpensAbsoluteCount($data); + if (empty($data['newsletter_id'])) throw new InvalidFilterException('Missing newsletter id', InvalidFilterException::MISSING_NEWSLETTER_ID); $filterData = [ 'segmentType' => DynamicSegmentFilterData::TYPE_EMAIL, 'action' => $data['action'], @@ -54,6 +56,22 @@ class FilterDataMapper { return new DynamicSegmentFilterData($filterData); } + /** + * @throws InvalidFilterException + */ + private function createEmailOpensAbsoluteCount(array $data): DynamicSegmentFilterData { + if (empty($data['opens'])) throw new InvalidFilterException('Missing number of opens', InvalidFilterException::MISSING_VALUE); + if (empty($data['days'])) throw new InvalidFilterException('Missing number of days', InvalidFilterException::MISSING_VALUE); + $filterData = [ + 'segmentType' => DynamicSegmentFilterData::TYPE_EMAIL, + 'action' => $data['action'], + 'opens' => $data['opens'], + 'days' => $data['days'], + 'operator' => $data['operator'] ?? 'more', + ]; + return new DynamicSegmentFilterData($filterData); + } + /** * @throws InvalidFilterException */ diff --git a/lib/Segments/DynamicSegments/Filters/EmailAction.php b/lib/Segments/DynamicSegments/Filters/EmailAction.php index 514d543cd2..1e4137574a 100644 --- a/lib/Segments/DynamicSegments/Filters/EmailAction.php +++ b/lib/Segments/DynamicSegments/Filters/EmailAction.php @@ -21,6 +21,7 @@ class EmailAction implements Filter { self::ACTION_NOT_OPENED, self::ACTION_CLICKED, self::ACTION_NOT_CLICKED, + EmailOpensAbsoluteCountAction::TYPE, ]; /** @var EntityManager */ diff --git a/lib/Segments/DynamicSegments/Filters/EmailOpensAbsoluteCountAction.php b/lib/Segments/DynamicSegments/Filters/EmailOpensAbsoluteCountAction.php index 6d1c8b5aad..5827784beb 100644 --- a/lib/Segments/DynamicSegments/Filters/EmailOpensAbsoluteCountAction.php +++ b/lib/Segments/DynamicSegments/Filters/EmailOpensAbsoluteCountAction.php @@ -42,5 +42,4 @@ class EmailOpensAbsoluteCountAction implements Filter { $queryBuilder->setParameter('opens' . $filter->getId(), $filterData->getParam('opens')); return $queryBuilder; } - } diff --git a/tests/unit/Segments/DynamicSegments/FilterDataMapperTest.php b/tests/unit/Segments/DynamicSegments/FilterDataMapperTest.php index 87664f2bfb..f35a8941f4 100644 --- a/tests/unit/Segments/DynamicSegments/FilterDataMapperTest.php +++ b/tests/unit/Segments/DynamicSegments/FilterDataMapperTest.php @@ -5,6 +5,7 @@ namespace MailPoet\Segments\DynamicSegments; use MailPoet\Entities\DynamicSegmentFilterData; use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException; use MailPoet\Segments\DynamicSegments\Filters\EmailAction; +use MailPoet\Segments\DynamicSegments\Filters\EmailOpensAbsoluteCountAction; use MailPoet\Segments\DynamicSegments\Filters\WooCommerceCategory; use MailPoet\Segments\DynamicSegments\Filters\WooCommerceProduct; @@ -166,4 +167,23 @@ class FilterDataMapperTest extends \MailPoetUnitTest { 'action' => WooCommerceProduct::ACTION_PRODUCT, ]); } + + public function testItCreatesEmailOpens() { + $data = [ + 'segmentType' => DynamicSegmentFilterData::TYPE_EMAIL, + 'action' => EmailOpensAbsoluteCountAction::TYPE, + 'opens' => 5, + 'days' => 3, + ]; + $filter = $this->mapper->map($data); + expect($filter)->isInstanceOf(DynamicSegmentFilterData::class); + expect($filter->getFilterType())->equals(DynamicSegmentFilterData::TYPE_EMAIL); + expect($filter->getData())->equals([ + 'segmentType' => DynamicSegmentFilterData::TYPE_EMAIL, + 'action' => EmailOpensAbsoluteCountAction::TYPE, + 'opens' => 5, + 'days' => 3, + 'operator' => 'more', + ]); + } }