Add multiple emails support with any of and all of for machine-opened
[MAILPOET-3957]
This commit is contained in:
committed by
Veljko V
parent
743276c057
commit
ea8bfdc863
@ -8,6 +8,7 @@ import Select from 'common/form/select/select';
|
||||
import { Grid } from 'common/grid';
|
||||
import {
|
||||
AnyValueTypes,
|
||||
EmailActionTypes,
|
||||
EmailFormItem,
|
||||
SelectOption,
|
||||
WindowNewslettersList,
|
||||
@ -42,12 +43,14 @@ export const EmailOpenStatisticsFields: React.FunctionComponent<Props> = ({ filt
|
||||
useEffect(() => {
|
||||
if ((segment.operator !== AnyValueTypes.ANY)
|
||||
&& (segment.operator !== AnyValueTypes.ALL)
|
||||
&& (segment.operator !== AnyValueTypes.NONE)
|
||||
&& ((segment.operator !== AnyValueTypes.NONE)
|
||||
|| (segment.action === EmailActionTypes.MACHINE_OPENED)
|
||||
)
|
||||
) {
|
||||
updateSegmentFilter({ operator: AnyValueTypes.ANY }, filterIndex);
|
||||
}
|
||||
}, [
|
||||
segment.newsletter_id,
|
||||
segment.action,
|
||||
segment.operator,
|
||||
filterIndex,
|
||||
updateSegmentFilter,
|
||||
@ -66,7 +69,7 @@ export const EmailOpenStatisticsFields: React.FunctionComponent<Props> = ({ filt
|
||||
>
|
||||
<option value={AnyValueTypes.ANY}>{MailPoet.I18n.t('anyOf')}</option>
|
||||
<option value={AnyValueTypes.ALL}>{MailPoet.I18n.t('allOf')}</option>
|
||||
<option value={AnyValueTypes.NONE}>{MailPoet.I18n.t('noneOf')}</option>
|
||||
{segment.action === EmailActionTypes.OPENED ? <option value={AnyValueTypes.NONE}>{MailPoet.I18n.t('noneOf')}</option> : null}
|
||||
</Select>
|
||||
</Grid.CenteredRow>
|
||||
<Grid.CenteredRow>
|
||||
|
@ -63,7 +63,7 @@ class DynamicSegmentsResponseBuilder {
|
||||
}
|
||||
if (($filter['segmentType'] === DynamicSegmentFilterData::TYPE_EMAIL)) {
|
||||
// compatibility with older filters
|
||||
if ((($filter['action'] === EmailAction::ACTION_OPENED) || ($filter['action'] === EmailAction::ACTION_NOT_OPENED))) {
|
||||
if ((($filter['action'] === EmailAction::ACTION_OPENED) || ($filter['action'] === EmailAction::ACTION_NOT_OPENED) || ($filter['action'] === EmailAction::ACTION_MACHINE_OPENED))) {
|
||||
if (isset($filter['newsletter_id']) && !isset($filter['newsletters'])) {
|
||||
// make sure the newsletters are an array
|
||||
$filter['newsletters'] = [intval($filter['newsletter_id'])];
|
||||
|
@ -153,7 +153,7 @@ class FilterDataMapper {
|
||||
'operator' => $data['operator'] ?? DynamicSegmentFilterData::OPERATOR_ANY,
|
||||
];
|
||||
|
||||
if (($data['action'] !== EmailAction::ACTION_OPENED) && ($data['action'] !== EmailAction::ACTION_NOT_OPENED)) {
|
||||
if (($data['action'] === EmailAction::ACTION_CLICKED) || ($data['action'] === EmailAction::ACTION_NOT_CLICKED)) {
|
||||
if (empty($data['newsletter_id'])) throw new InvalidFilterException('Missing newsletter id', InvalidFilterException::MISSING_NEWSLETTER_ID);
|
||||
$filterData['newsletter_id'] = $data['newsletter_id'];
|
||||
} else {
|
||||
|
@ -107,7 +107,7 @@ class EmailAction implements Filter {
|
||||
}
|
||||
|
||||
private function applyForOpenedActions(QueryBuilder $queryBuilder, DynamicSegmentFilterData $filterData, string $parameterSuffix) {
|
||||
$operator = $filterData->getParam('operator');
|
||||
$operator = $filterData->getParam('operator') ?? DynamicSegmentFilterData::OPERATOR_ANY;
|
||||
$action = $filterData->getAction();
|
||||
|
||||
if ($action === self::ACTION_NOT_OPENED) {
|
||||
@ -130,7 +130,7 @@ class EmailAction implements Filter {
|
||||
|
||||
$where = '1';
|
||||
|
||||
if (($action === EmailAction::ACTION_OPENED) && ($operator === DynamicSegmentFilterData::OPERATOR_NONE)) {
|
||||
if ($operator === DynamicSegmentFilterData::OPERATOR_NONE) {
|
||||
$queryBuilder = $queryBuilder->innerJoin(
|
||||
$subscribersTable,
|
||||
$statsSentTable,
|
||||
@ -143,7 +143,7 @@ class EmailAction implements Filter {
|
||||
"statssent.subscriber_id = stats.subscriber_id AND stats.newsletter_id IN (:newsletters" . $parameterSuffix . ')'
|
||||
)->setParameter('newsletters' . $parameterSuffix, $newsletters, Connection::PARAM_INT_ARRAY);
|
||||
$where .= ' AND stats.id IS NULL';
|
||||
} elseif ($action === EmailAction::ACTION_OPENED) {
|
||||
} else {
|
||||
$queryBuilder = $queryBuilder->innerJoin(
|
||||
$subscribersTable,
|
||||
$statsTable,
|
||||
@ -155,13 +155,6 @@ class EmailAction implements Filter {
|
||||
$queryBuilder->groupBy('subscriber_id');
|
||||
$queryBuilder->having('COUNT(1) = ' . count($newsletters));
|
||||
}
|
||||
} else { // Machine opens
|
||||
$queryBuilder = $queryBuilder->innerJoin(
|
||||
$subscribersTable,
|
||||
$statsTable,
|
||||
'stats',
|
||||
"stats.subscriber_id = $subscribersTable.id AND stats.newsletter_id = :newsletter" . $parameterSuffix
|
||||
)->setParameter('newsletter' . $parameterSuffix, $newsletterId);
|
||||
}
|
||||
if (($action === EmailAction::ACTION_OPENED) && ($operator !== DynamicSegmentFilterData::OPERATOR_NONE)) {
|
||||
$queryBuilder->andWhere('stats.user_agent_type = :userAgentType')
|
||||
|
@ -289,14 +289,14 @@ class EmailActionTest extends \MailPoetTest {
|
||||
$open->setUserAgent($userAgent);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_OPENED, ['newsletter_id' => (int)$this->newsletter->getId()]);
|
||||
$segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_OPENED, ['newsletters' => [(int)$this->newsletter->getId()]]);
|
||||
$statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute();
|
||||
$this->assertInstanceOf(Statement::class, $statement);
|
||||
$result = $statement->rowCount();
|
||||
expect($result)->equals(2);
|
||||
}
|
||||
|
||||
public function testMachineOpens() {
|
||||
public function testMachineOpensAny() {
|
||||
$subscriberOpenedMachine = $this->createSubscriber('opened_machine@example.com');
|
||||
$this->createStatsNewsletter($subscriberOpenedMachine, $this->newsletter);
|
||||
$open = $this->createStatisticsOpens($subscriberOpenedMachine, $this->newsletter);
|
||||
@ -306,7 +306,43 @@ class EmailActionTest extends \MailPoetTest {
|
||||
$open->setUserAgent($userAgent);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$segmentFilter = $this->getSegmentFilter(EmailAction::ACTION_MACHINE_OPENED, ['newsletter_id' => (int)$this->newsletter->getId()]);
|
||||
$segmentFilter = $this->getSegmentFilter(
|
||||
EmailAction::ACTION_MACHINE_OPENED,
|
||||
['newsletters' => [
|
||||
(int)$this->newsletter->getId(),
|
||||
(int)$this->newsletter2->getId(),
|
||||
]]
|
||||
);
|
||||
$statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute();
|
||||
$this->assertInstanceOf(Statement::class, $statement);
|
||||
$result = $statement->rowCount();
|
||||
expect($result)->equals(1);
|
||||
}
|
||||
|
||||
public function testMachineOpensAll() {
|
||||
$subscriberOpenedMachine = $this->createSubscriber('opened_machine@example.com');
|
||||
$this->createStatsNewsletter($subscriberOpenedMachine, $this->newsletter);
|
||||
$this->createStatsNewsletter($subscriberOpenedMachine, $this->newsletter2);
|
||||
$open1 = $this->createStatisticsOpens($subscriberOpenedMachine, $this->newsletter);
|
||||
$open1->setUserAgentType(UserAgentEntity::USER_AGENT_TYPE_MACHINE);
|
||||
$open2 = $this->createStatisticsOpens($subscriberOpenedMachine, $this->newsletter2);
|
||||
$open2->setUserAgentType(UserAgentEntity::USER_AGENT_TYPE_MACHINE);
|
||||
$userAgent = new UserAgentEntity(UserAgentEntity::MACHINE_USER_AGENTS[0]);
|
||||
$this->entityManager->persist($userAgent);
|
||||
$open1->setUserAgent($userAgent);
|
||||
$open2->setUserAgent($userAgent);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$segmentFilter = $this->getSegmentFilter(
|
||||
EmailAction::ACTION_MACHINE_OPENED,
|
||||
[
|
||||
'newsletters' => [
|
||||
(int)$this->newsletter->getId(),
|
||||
(int)$this->newsletter2->getId(),
|
||||
],
|
||||
'operator' => DynamicSegmentFilterData::OPERATOR_ALL,
|
||||
]
|
||||
);
|
||||
$statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute();
|
||||
$this->assertInstanceOf(Statement::class, $statement);
|
||||
$result = $statement->rowCount();
|
||||
|
Reference in New Issue
Block a user