From 2ab5f04f46d74ec75d173c4fe5ac68f08a72beab Mon Sep 17 00:00:00 2001 From: Pavel Dohnal Date: Mon, 30 Aug 2021 13:24:00 +0200 Subject: [PATCH] Add segment for machine opens [MAILPOET-3737] --- .../dynamic/dynamic_segments_filters/email.tsx | 2 ++ assets/js/src/segments/dynamic/types.ts | 1 + .../DynamicSegments/Filters/EmailAction.php | 6 ++++++ .../DynamicSegments/Filters/EmailActionTest.php | 17 +++++++++++++++++ views/segments.html | 1 + 5 files changed, 27 insertions(+) diff --git a/assets/js/src/segments/dynamic/dynamic_segments_filters/email.tsx b/assets/js/src/segments/dynamic/dynamic_segments_filters/email.tsx index edb7bf935c..6842c12ee9 100644 --- a/assets/js/src/segments/dynamic/dynamic_segments_filters/email.tsx +++ b/assets/js/src/segments/dynamic/dynamic_segments_filters/email.tsx @@ -14,6 +14,7 @@ import { EmailOpensAbsoluteCountFields } from './email_opens_absolute_count'; export const EmailSegmentOptions = [ { value: EmailActionTypes.OPENS_ABSOLUTE_COUNT, label: MailPoet.I18n.t('emailActionOpensAbsoluteCount'), group: SegmentTypes.Email }, { value: EmailActionTypes.OPENED, label: MailPoet.I18n.t('emailActionOpened'), group: SegmentTypes.Email }, + { value: EmailActionTypes.MACHINE_OPENED, label: MailPoet.I18n.t('emailActionMachineOpened'), group: SegmentTypes.Email }, { value: EmailActionTypes.NOT_OPENED, label: MailPoet.I18n.t('emailActionNotOpened'), group: SegmentTypes.Email }, { value: EmailActionTypes.CLICKED, label: MailPoet.I18n.t('emailActionClicked'), group: SegmentTypes.Email }, { value: EmailActionTypes.CLICKED_ANY, label: MailPoet.I18n.t('emailActionClickedAnyEmail'), group: SegmentTypes.Email }, @@ -48,6 +49,7 @@ const componentsMap = { [EmailActionTypes.CLICKED]: EmailStatisticsFields, [EmailActionTypes.NOT_CLICKED]: EmailStatisticsFields, [EmailActionTypes.OPENED]: EmailStatisticsFields, + [EmailActionTypes.MACHINE_OPENED]: EmailStatisticsFields, [EmailActionTypes.NOT_OPENED]: EmailStatisticsFields, [EmailActionTypes.CLICKED_ANY]: null, }; diff --git a/assets/js/src/segments/dynamic/types.ts b/assets/js/src/segments/dynamic/types.ts index e18c875942..b26bbb0c72 100644 --- a/assets/js/src/segments/dynamic/types.ts +++ b/assets/js/src/segments/dynamic/types.ts @@ -9,6 +9,7 @@ export enum SegmentTypes { export enum EmailActionTypes { OPENS_ABSOLUTE_COUNT = 'opensAbsoluteCount', OPENED = 'opened', + MACHINE_OPENED = 'machineOpened', NOT_OPENED = 'notOpened', CLICKED = 'clicked', CLICKED_ANY = 'clickedAny', diff --git a/lib/Segments/DynamicSegments/Filters/EmailAction.php b/lib/Segments/DynamicSegments/Filters/EmailAction.php index cfe4876615..b4ff0f7dbd 100644 --- a/lib/Segments/DynamicSegments/Filters/EmailAction.php +++ b/lib/Segments/DynamicSegments/Filters/EmailAction.php @@ -15,6 +15,7 @@ use MailPoetVendor\Doctrine\ORM\EntityManager; class EmailAction implements Filter { const ACTION_OPENED = 'opened'; + const ACTION_MACHINE_OPENED = 'machineOpened'; const ACTION_NOT_OPENED = 'notOpened'; const ACTION_CLICKED = 'clicked'; const ACTION_CLICKED_ANY = 'clickedAny'; @@ -22,6 +23,7 @@ class EmailAction implements Filter { const ALLOWED_ACTIONS = [ self::ACTION_OPENED, + self::ACTION_MACHINE_OPENED, self::ACTION_NOT_OPENED, self::ACTION_CLICKED, self::ACTION_NOT_CLICKED, @@ -103,6 +105,10 @@ class EmailAction implements Filter { $queryBuilder->andWhere('(stats.user_agent_type = :userAgentType) OR (stats.user_agent_type IS NULL)') ->setParameter('userAgentType', UserAgentEntity::USER_AGENT_TYPE_HUMAN); } + if ($action === EmailAction::ACTION_MACHINE_OPENED) { + $queryBuilder->andWhere('(stats.user_agent_type = :userAgentType)') + ->setParameter('userAgentType', UserAgentEntity::USER_AGENT_TYPE_MACHINE); + } if ($action === EmailAction::ACTION_CLICKED && $linkId) { $where .= ' AND stats.link_id = :link' . $parameterSuffix; } diff --git a/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php b/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php index 3fc27f8d9a..bb34c4a25c 100644 --- a/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php +++ b/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php @@ -195,6 +195,23 @@ class EmailActionTest extends \MailPoetTest { expect($result)->equals(2); } + public function testMachineOpens() { + $subscriberOpenedMachine = $this->createSubscriber('opened_machine@example.com'); + $this->createStatsNewsletter($subscriberOpenedMachine); + $open = $this->createStatisticsOpens($subscriberOpenedMachine); + $open->setUserAgentType(UserAgentEntity::USER_AGENT_TYPE_MACHINE); + $userAgent = new UserAgentEntity(UserAgentEntity::MACHINE_USER_AGENTS[0]); + $this->entityManager->persist($userAgent); + $open->setUserAgent($userAgent); + $this->entityManager->flush(); + + $segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_MACHINE_OPENED, (int)$this->newsletter->getId()); + $statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute(); + assert($statement instanceof Statement); + $result = $statement->rowCount(); + expect($result)->equals(1); + } + private function getQueryBuilder() { $subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName(); return $this->entityManager diff --git a/views/segments.html b/views/segments.html index 337dbaa38a..6661de5aa1 100644 --- a/views/segments.html +++ b/views/segments.html @@ -140,6 +140,7 @@ 'selectUserRolePlaceholder': __('Select user role'), 'selectCustomFieldPlaceholder': __('Select custom field'), 'emailActionOpened': _x('opened', 'Dynamic segment creation: when newsletter was opened'), + 'emailActionMachineOpened': _x('machine-opened', 'Dynamic segment creation: list of all subscribers that opened the newsletter automatically in the background'), 'emailActionOpensAbsoluteCount': __('# of opens'), 'emailActionOpens': __('opens'), 'emailActionDays': __('days'),