Add "was sent email" filter
MAILPOET-5004
This commit is contained in:
committed by
Aschepikov
parent
87f703f22a
commit
8a66c83257
@ -43,6 +43,7 @@ const componentsMap = {
|
||||
EmailOpensAbsoluteCountFields,
|
||||
[EmailActionTypes.CLICKED]: EmailClickStatisticsFields,
|
||||
[EmailActionTypes.OPENED]: EmailOpenStatisticsFields,
|
||||
[EmailActionTypes.WAS_SENT]: EmailOpenStatisticsFields,
|
||||
[EmailActionTypes.MACHINE_OPENED]: EmailOpenStatisticsFields,
|
||||
[EmailActionTypes.CLICKED_ANY]: null,
|
||||
};
|
||||
|
@ -12,6 +12,11 @@ export const EmailSegmentOptions = [
|
||||
label: MailPoet.I18n.t('emailActionMachineOpensAbsoluteCount'),
|
||||
group: SegmentTypes.Email,
|
||||
},
|
||||
{
|
||||
value: EmailActionTypes.WAS_SENT,
|
||||
label: MailPoet.I18n.t('emailActionWasSent'),
|
||||
group: SegmentTypes.Email,
|
||||
},
|
||||
{
|
||||
value: EmailActionTypes.OPENED,
|
||||
label: MailPoet.I18n.t('emailActionOpened'),
|
||||
|
@ -12,6 +12,7 @@ export enum EmailActionTypes {
|
||||
MACHINE_OPENS_ABSOLUTE_COUNT = 'machineOpensAbsoluteCount',
|
||||
OPENED = 'opened',
|
||||
MACHINE_OPENED = 'machineOpened',
|
||||
WAS_SENT = 'wasSent',
|
||||
CLICKED = 'clicked',
|
||||
CLICKED_ANY = 'clickedAny',
|
||||
}
|
||||
|
@ -18,16 +18,18 @@ use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
class EmailAction implements Filter {
|
||||
const ACTION_OPENED = 'opened';
|
||||
const ACTION_MACHINE_OPENED = 'machineOpened';
|
||||
/** @deprecated */
|
||||
/** @deprecated */
|
||||
const ACTION_NOT_OPENED = 'notOpened';
|
||||
const ACTION_CLICKED = 'clicked';
|
||||
/** @deprecated */
|
||||
const ACTION_WAS_SENT = 'wasSent';
|
||||
/** @deprecated */
|
||||
const ACTION_NOT_CLICKED = 'notClicked';
|
||||
|
||||
const ALLOWED_ACTIONS = [
|
||||
self::ACTION_OPENED,
|
||||
self::ACTION_MACHINE_OPENED,
|
||||
self::ACTION_CLICKED,
|
||||
self::ACTION_WAS_SENT,
|
||||
EmailActionClickAny::TYPE,
|
||||
EmailOpensAbsoluteCountAction::TYPE,
|
||||
EmailOpensAbsoluteCountAction::MACHINE_TYPE,
|
||||
@ -35,11 +37,15 @@ class EmailAction implements Filter {
|
||||
|
||||
/** @var EntityManager */
|
||||
private $entityManager;
|
||||
/** @var FilterHelper */
|
||||
private $filterHelper;
|
||||
|
||||
public function __construct(
|
||||
EntityManager $entityManager
|
||||
EntityManager $entityManager,
|
||||
FilterHelper $filterHelper
|
||||
) {
|
||||
$this->entityManager = $entityManager;
|
||||
$this->filterHelper = $filterHelper;
|
||||
}
|
||||
|
||||
public function apply(QueryBuilder $queryBuilder, DynamicSegmentFilterEntity $filter): QueryBuilder {
|
||||
@ -49,6 +55,8 @@ class EmailAction implements Filter {
|
||||
|
||||
if ($action === self::ACTION_CLICKED) {
|
||||
return $this->applyForClickedActions($queryBuilder, $filterData, $parameterSuffix);
|
||||
} elseif ($action === self::ACTION_WAS_SENT) {
|
||||
return $this->applyForWasSentAction($queryBuilder, $filterData, $parameterSuffix);
|
||||
} else {
|
||||
return $this->applyForOpenedActions($queryBuilder, $filterData, $parameterSuffix);
|
||||
}
|
||||
@ -175,4 +183,36 @@ class EmailAction implements Filter {
|
||||
}
|
||||
return $clause;
|
||||
}
|
||||
|
||||
private function applyForWasSentAction(QueryBuilder $queryBuilder, DynamicSegmentFilterData $filterData, string $parameterSuffix): QueryBuilder {
|
||||
$newsletters = (array)$filterData->getParam('newsletters');
|
||||
$operator = $filterData->getParam('operator') ?? DynamicSegmentFilterData::OPERATOR_ANY;
|
||||
$subscribersTable = $this->filterHelper->getSubscribersTable();
|
||||
$statisticsNewslettersTable = $this->entityManager->getClassMetadata(StatisticsNewsletterEntity::class)->getTableName();
|
||||
|
||||
if ($operator === DynamicSegmentFilterData::OPERATOR_NONE) {
|
||||
$queryBuilder->leftJoin(
|
||||
$this->filterHelper->getSubscribersTable(),
|
||||
$statisticsNewslettersTable,
|
||||
'statisticsNewsletter',
|
||||
"$subscribersTable.id = statisticsNewsletter.subscriber_id AND statisticsNewsletter.newsletter_id IN (:newsletters" . $parameterSuffix . ')'
|
||||
)
|
||||
->setParameter('newsletters' . $parameterSuffix, $newsletters, Connection::PARAM_INT_ARRAY)
|
||||
->andWhere('statisticsNewsletter.subscriber_id IS NULL');
|
||||
} else {
|
||||
$queryBuilder->innerJoin(
|
||||
$subscribersTable,
|
||||
$statisticsNewslettersTable,
|
||||
'statisticsNewsletter',
|
||||
"statisticsNewsletter.subscriber_id = $subscribersTable.id AND statisticsNewsletter.newsletter_id IN (:newsletters" . $parameterSuffix . ')'
|
||||
)->setParameter('newsletters' . $parameterSuffix, $newsletters, Connection::PARAM_INT_ARRAY);
|
||||
|
||||
if ($operator === DynamicSegmentFilterData::OPERATOR_ALL) {
|
||||
$queryBuilder->groupBy('subscriber_id');
|
||||
$queryBuilder->having('COUNT(1) = ' . count($newsletters));
|
||||
}
|
||||
}
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +292,71 @@ class EmailActionTest extends \MailPoetTest {
|
||||
$this->assertEqualsCanonicalizing(['opened_machine@example.com'], $emails);
|
||||
}
|
||||
|
||||
public function testSentEmailAny(): void {
|
||||
$subscriber1 = $this->createSubscriber('1@example.com');
|
||||
$subscriber2 = $this->createSubscriber('2@example.com');
|
||||
$this->createSubscriber('3@example.com');
|
||||
|
||||
|
||||
$this->createStatsNewsletter($subscriber1, $this->newsletter);
|
||||
$this->createStatsNewsletter($subscriber2, $this->newsletter2);
|
||||
|
||||
$segmentFilterData = $this->getSegmentFilterData(EmailAction::ACTION_WAS_SENT, [
|
||||
'newsletters' => [$this->newsletter->getId(), $this->newsletter2->getId()],
|
||||
'operator' => DynamicSegmentFilterData::OPERATOR_ANY,
|
||||
]);
|
||||
|
||||
$emails = $this->tester->getSubscriberEmailsMatchingDynamicFilter($segmentFilterData, $this->emailAction);
|
||||
|
||||
expect($emails)->contains('1@example.com');
|
||||
expect($emails)->contains('2@example.com');
|
||||
expect($emails)->notContains('3@example.com');
|
||||
}
|
||||
|
||||
public function testSentEmailAll(): void {
|
||||
$subscriber1 = $this->createSubscriber('1@example.com');
|
||||
$subscriber2 = $this->createSubscriber('2@example.com');
|
||||
$subscriber3 = $this->createSubscriber('3@example.com');
|
||||
|
||||
$this->createStatsNewsletter($subscriber1, $this->newsletter);
|
||||
$this->createStatsNewsletter($subscriber1, $this->newsletter2);
|
||||
$this->createStatsNewsletter($subscriber2, $this->newsletter2);
|
||||
$this->createStatsNewsletter($subscriber3, $this->newsletter2);
|
||||
|
||||
$segmentFilterData = $this->getSegmentFilterData(EmailAction::ACTION_WAS_SENT, [
|
||||
'newsletters' => [$this->newsletter->getId(), $this->newsletter2->getId()],
|
||||
'operator' => DynamicSegmentFilterData::OPERATOR_ALL,
|
||||
]);
|
||||
|
||||
$emails = $this->tester->getSubscriberEmailsMatchingDynamicFilter($segmentFilterData, $this->emailAction);
|
||||
|
||||
expect($emails)->contains('1@example.com');
|
||||
expect($emails)->notContains('2@example.com');
|
||||
expect($emails)->notContains('3@example.com');
|
||||
}
|
||||
|
||||
public function testSentEmailNone(): void {
|
||||
$subscriber1 = $this->createSubscriber('1@example.com');
|
||||
$subscriber2 = $this->createSubscriber('2@example.com');
|
||||
$subscriber3 = $this->createSubscriber('3@example.com');
|
||||
|
||||
$this->createStatsNewsletter($subscriber1, $this->newsletter);
|
||||
$this->createStatsNewsletter($subscriber1, $this->newsletter2);
|
||||
$this->createStatsNewsletter($subscriber2, $this->newsletter2);
|
||||
$this->createStatsNewsletter($subscriber3, $this->newsletter3);
|
||||
|
||||
$segmentFilterData = $this->getSegmentFilterData(EmailAction::ACTION_WAS_SENT, [
|
||||
'newsletters' => [$this->newsletter->getId(), $this->newsletter2->getId()],
|
||||
'operator' => DynamicSegmentFilterData::OPERATOR_NONE,
|
||||
]);
|
||||
|
||||
$emails = $this->tester->getSubscriberEmailsMatchingDynamicFilter($segmentFilterData, $this->emailAction);
|
||||
|
||||
expect($emails)->notContains('1@example.com');
|
||||
expect($emails)->notContains('2@example.com');
|
||||
expect($emails)->contains('3@example.com');
|
||||
}
|
||||
|
||||
private function getSegmentFilterData(string $action, array $data): DynamicSegmentFilterData {
|
||||
return new DynamicSegmentFilterData(DynamicSegmentFilterData::TYPE_EMAIL, $action, $data);
|
||||
}
|
||||
|
@ -137,6 +137,7 @@
|
||||
'selectUserRolePlaceholder': __('Search user roles'),
|
||||
'selectCustomFieldPlaceholder': __('Select custom field'),
|
||||
'emailActionOpened': _x('opened', 'Dynamic segment creation: when newsletter was opened'),
|
||||
'emailActionWasSent': _x('was sent', 'Dynamic segment creation: when newsletter was sent'),
|
||||
'emailActionMachineOpened': _x('machine-opened', 'Dynamic segment creation: list of all subscribers that opened the newsletter automatically in the background'),
|
||||
'emailActionOpensAbsoluteCount': __('# of opens'),
|
||||
'emailActionMachineOpensAbsoluteCount': __('# of machine-opens'),
|
||||
|
Reference in New Issue
Block a user