diff --git a/lib/Segments/DynamicSegments/Filters/EmailAction.php b/lib/Segments/DynamicSegments/Filters/EmailAction.php index 1e4137574a..5fb2e858e1 100644 --- a/lib/Segments/DynamicSegments/Filters/EmailAction.php +++ b/lib/Segments/DynamicSegments/Filters/EmailAction.php @@ -14,6 +14,7 @@ class EmailAction implements Filter { const ACTION_OPENED = 'opened'; const ACTION_NOT_OPENED = 'notOpened'; const ACTION_CLICKED = 'clicked'; + const ACTION_CLICKED_ANY = 'clickedAny'; const ACTION_NOT_CLICKED = 'notClicked'; const ALLOWED_ACTIONS = [ @@ -21,9 +22,16 @@ class EmailAction implements Filter { self::ACTION_NOT_OPENED, self::ACTION_CLICKED, self::ACTION_NOT_CLICKED, + self::ACTION_CLICKED_ANY, EmailOpensAbsoluteCountAction::TYPE, ]; + const CLICK_ACTIONS = [ + self::ACTION_CLICKED, + self::ACTION_NOT_CLICKED, + self::ACTION_CLICKED_ANY, + ]; + /** @var EntityManager */ private $entityManager; @@ -39,7 +47,7 @@ class EmailAction implements Filter { $statsSentTable = $this->entityManager->getClassMetadata(StatisticsNewsletterEntity::class)->getTableName(); $subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName(); - if (($action === self::ACTION_CLICKED) || ($action === self::ACTION_NOT_CLICKED)) { + if (in_array($action, self::CLICK_ACTIONS, true)) { $statsTable = $this->entityManager->getClassMetadata(StatisticsClickEntity::class)->getTableName(); } else { $statsTable = $this->entityManager->getClassMetadata(StatisticsOpenEntity::class)->getTableName(); @@ -58,22 +66,27 @@ class EmailAction implements Filter { $statsTable, 'stats', $this->createNotStatsJoinCondition($filter, $action, $linkId) - ); + )->setParameter('newsletter' . $filter->getId(), $newsletterId); $where .= ' AND stats.id IS NULL'; + } else if ($action === self::ACTION_CLICKED_ANY) { + $queryBuilder = $queryBuilder->innerJoin( + $subscribersTable, + $statsTable, + 'stats', + "stats.subscriber_id = $subscribersTable.id" + ); } else { $queryBuilder = $queryBuilder->innerJoin( $subscribersTable, $statsTable, 'stats', "stats.subscriber_id = $subscribersTable.id AND stats.newsletter_id = :newsletter" . $filter->getId() - ); + )->setParameter('newsletter' . $filter->getId(), $newsletterId); } if ($action === EmailAction::ACTION_CLICKED && $linkId) { $where .= ' AND stats.link_id = :link' . $filter->getId(); } - $queryBuilder = $queryBuilder - ->andWhere($where) - ->setParameter('newsletter' . $filter->getId(), $newsletterId); + $queryBuilder = $queryBuilder->andWhere($where); if (in_array($action, [EmailAction::ACTION_CLICKED, EmailAction::ACTION_NOT_CLICKED]) && $linkId) { $queryBuilder = $queryBuilder ->setParameter('link' . $filter->getId(), $linkId); diff --git a/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php b/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php index a48d9b6d88..90fc6e2dd8 100644 --- a/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php +++ b/tests/integration/Segments/DynamicSegments/Filters/EmailActionTest.php @@ -139,6 +139,17 @@ class EmailActionTest extends \MailPoetTest { expect($subscriber2->getEmail())->equals('not_opened@example.com'); } + public function testGetClickedAnyLink() { + $segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_CLICKED_ANY); + $statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute(); + $this->assertInstanceOf(Statement::class, $statement); + $result = $statement->fetchAll(); + expect(count($result))->equals(1); + $subscriber1 = $this->entityManager->find(SubscriberEntity::class, $result[0]['id']); + $this->assertInstanceOf(SubscriberEntity::class, $subscriber1); + expect($subscriber1->getEmail())->equals('opened_clicked@example.com'); + } + public function testGetNotClickedWithWrongLink() { $segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_NOT_CLICKED, (int)$this->newsletter->getId(), 2); $statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute(); @@ -179,7 +190,7 @@ class EmailActionTest extends \MailPoetTest { ->from($subscribersTable); } - private function getSegmentFilter(string $action, int $newsletterId, int $linkId = null): DynamicSegmentFilterEntity { + private function getSegmentFilter(string $action, int $newsletterId = null, int $linkId = null): DynamicSegmentFilterEntity { $segmentFilterData = new DynamicSegmentFilterData([ 'segmentType' => DynamicSegmentFilterData::TYPE_EMAIL, 'action' => $action,