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 { Grid } from 'common/grid';
|
||||||
import {
|
import {
|
||||||
AnyValueTypes,
|
AnyValueTypes,
|
||||||
|
EmailActionTypes,
|
||||||
EmailFormItem,
|
EmailFormItem,
|
||||||
SelectOption,
|
SelectOption,
|
||||||
WindowNewslettersList,
|
WindowNewslettersList,
|
||||||
@ -42,12 +43,14 @@ export const EmailOpenStatisticsFields: React.FunctionComponent<Props> = ({ filt
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ((segment.operator !== AnyValueTypes.ANY)
|
if ((segment.operator !== AnyValueTypes.ANY)
|
||||||
&& (segment.operator !== AnyValueTypes.ALL)
|
&& (segment.operator !== AnyValueTypes.ALL)
|
||||||
&& (segment.operator !== AnyValueTypes.NONE)
|
&& ((segment.operator !== AnyValueTypes.NONE)
|
||||||
|
|| (segment.action === EmailActionTypes.MACHINE_OPENED)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
updateSegmentFilter({ operator: AnyValueTypes.ANY }, filterIndex);
|
updateSegmentFilter({ operator: AnyValueTypes.ANY }, filterIndex);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
segment.newsletter_id,
|
segment.action,
|
||||||
segment.operator,
|
segment.operator,
|
||||||
filterIndex,
|
filterIndex,
|
||||||
updateSegmentFilter,
|
updateSegmentFilter,
|
||||||
@ -66,7 +69,7 @@ export const EmailOpenStatisticsFields: React.FunctionComponent<Props> = ({ filt
|
|||||||
>
|
>
|
||||||
<option value={AnyValueTypes.ANY}>{MailPoet.I18n.t('anyOf')}</option>
|
<option value={AnyValueTypes.ANY}>{MailPoet.I18n.t('anyOf')}</option>
|
||||||
<option value={AnyValueTypes.ALL}>{MailPoet.I18n.t('allOf')}</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>
|
</Select>
|
||||||
</Grid.CenteredRow>
|
</Grid.CenteredRow>
|
||||||
<Grid.CenteredRow>
|
<Grid.CenteredRow>
|
||||||
|
@ -63,7 +63,7 @@ class DynamicSegmentsResponseBuilder {
|
|||||||
}
|
}
|
||||||
if (($filter['segmentType'] === DynamicSegmentFilterData::TYPE_EMAIL)) {
|
if (($filter['segmentType'] === DynamicSegmentFilterData::TYPE_EMAIL)) {
|
||||||
// compatibility with older filters
|
// 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'])) {
|
if (isset($filter['newsletter_id']) && !isset($filter['newsletters'])) {
|
||||||
// make sure the newsletters are an array
|
// make sure the newsletters are an array
|
||||||
$filter['newsletters'] = [intval($filter['newsletter_id'])];
|
$filter['newsletters'] = [intval($filter['newsletter_id'])];
|
||||||
|
@ -153,7 +153,7 @@ class FilterDataMapper {
|
|||||||
'operator' => $data['operator'] ?? DynamicSegmentFilterData::OPERATOR_ANY,
|
'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);
|
if (empty($data['newsletter_id'])) throw new InvalidFilterException('Missing newsletter id', InvalidFilterException::MISSING_NEWSLETTER_ID);
|
||||||
$filterData['newsletter_id'] = $data['newsletter_id'];
|
$filterData['newsletter_id'] = $data['newsletter_id'];
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,7 +107,7 @@ class EmailAction implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function applyForOpenedActions(QueryBuilder $queryBuilder, DynamicSegmentFilterData $filterData, string $parameterSuffix) {
|
private function applyForOpenedActions(QueryBuilder $queryBuilder, DynamicSegmentFilterData $filterData, string $parameterSuffix) {
|
||||||
$operator = $filterData->getParam('operator');
|
$operator = $filterData->getParam('operator') ?? DynamicSegmentFilterData::OPERATOR_ANY;
|
||||||
$action = $filterData->getAction();
|
$action = $filterData->getAction();
|
||||||
|
|
||||||
if ($action === self::ACTION_NOT_OPENED) {
|
if ($action === self::ACTION_NOT_OPENED) {
|
||||||
@ -130,7 +130,7 @@ class EmailAction implements Filter {
|
|||||||
|
|
||||||
$where = '1';
|
$where = '1';
|
||||||
|
|
||||||
if (($action === EmailAction::ACTION_OPENED) && ($operator === DynamicSegmentFilterData::OPERATOR_NONE)) {
|
if ($operator === DynamicSegmentFilterData::OPERATOR_NONE) {
|
||||||
$queryBuilder = $queryBuilder->innerJoin(
|
$queryBuilder = $queryBuilder->innerJoin(
|
||||||
$subscribersTable,
|
$subscribersTable,
|
||||||
$statsSentTable,
|
$statsSentTable,
|
||||||
@ -143,7 +143,7 @@ class EmailAction implements Filter {
|
|||||||
"statssent.subscriber_id = stats.subscriber_id AND stats.newsletter_id IN (:newsletters" . $parameterSuffix . ')'
|
"statssent.subscriber_id = stats.subscriber_id AND stats.newsletter_id IN (:newsletters" . $parameterSuffix . ')'
|
||||||
)->setParameter('newsletters' . $parameterSuffix, $newsletters, Connection::PARAM_INT_ARRAY);
|
)->setParameter('newsletters' . $parameterSuffix, $newsletters, Connection::PARAM_INT_ARRAY);
|
||||||
$where .= ' AND stats.id IS NULL';
|
$where .= ' AND stats.id IS NULL';
|
||||||
} elseif ($action === EmailAction::ACTION_OPENED) {
|
} else {
|
||||||
$queryBuilder = $queryBuilder->innerJoin(
|
$queryBuilder = $queryBuilder->innerJoin(
|
||||||
$subscribersTable,
|
$subscribersTable,
|
||||||
$statsTable,
|
$statsTable,
|
||||||
@ -155,13 +155,6 @@ class EmailAction implements Filter {
|
|||||||
$queryBuilder->groupBy('subscriber_id');
|
$queryBuilder->groupBy('subscriber_id');
|
||||||
$queryBuilder->having('COUNT(1) = ' . count($newsletters));
|
$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)) {
|
if (($action === EmailAction::ACTION_OPENED) && ($operator !== DynamicSegmentFilterData::OPERATOR_NONE)) {
|
||||||
$queryBuilder->andWhere('stats.user_agent_type = :userAgentType')
|
$queryBuilder->andWhere('stats.user_agent_type = :userAgentType')
|
||||||
|
@ -289,14 +289,14 @@ class EmailActionTest extends \MailPoetTest {
|
|||||||
$open->setUserAgent($userAgent);
|
$open->setUserAgent($userAgent);
|
||||||
$this->entityManager->flush();
|
$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();
|
$statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute();
|
||||||
$this->assertInstanceOf(Statement::class, $statement);
|
$this->assertInstanceOf(Statement::class, $statement);
|
||||||
$result = $statement->rowCount();
|
$result = $statement->rowCount();
|
||||||
expect($result)->equals(2);
|
expect($result)->equals(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMachineOpens() {
|
public function testMachineOpensAny() {
|
||||||
$subscriberOpenedMachine = $this->createSubscriber('opened_machine@example.com');
|
$subscriberOpenedMachine = $this->createSubscriber('opened_machine@example.com');
|
||||||
$this->createStatsNewsletter($subscriberOpenedMachine, $this->newsletter);
|
$this->createStatsNewsletter($subscriberOpenedMachine, $this->newsletter);
|
||||||
$open = $this->createStatisticsOpens($subscriberOpenedMachine, $this->newsletter);
|
$open = $this->createStatisticsOpens($subscriberOpenedMachine, $this->newsletter);
|
||||||
@ -306,7 +306,43 @@ class EmailActionTest extends \MailPoetTest {
|
|||||||
$open->setUserAgent($userAgent);
|
$open->setUserAgent($userAgent);
|
||||||
$this->entityManager->flush();
|
$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();
|
$statement = $this->emailAction->apply($this->getQueryBuilder(), $segmentFilter)->execute();
|
||||||
$this->assertInstanceOf(Statement::class, $statement);
|
$this->assertInstanceOf(Statement::class, $statement);
|
||||||
$result = $statement->rowCount();
|
$result = $statement->rowCount();
|
||||||
|
Reference in New Issue
Block a user