Add updating last engagement within clicks tracking

[MAILPOET-3762]
This commit is contained in:
Rostislav Wolny
2021-08-31 12:55:37 +02:00
committed by Veljko V
parent ed8de3eb17
commit 9c3fc95a6d
4 changed files with 111 additions and 14 deletions

View File

@@ -13,6 +13,7 @@ use MailPoet\Newsletter\Shortcodes\Shortcodes;
use MailPoet\Settings\SettingsController;
use MailPoet\Statistics\StatisticsClicksRepository;
use MailPoet\Statistics\UserAgentsRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Util\Cookies;
use MailPoet\WP\Functions as WPFunctions;
@@ -45,6 +46,9 @@ class Clicks {
/** @var UserAgentsRepository */
private $userAgentsRepository;
/** @var SubscribersRepository */
private $subscribersRepository;
public function __construct(
SettingsController $settingsController,
Cookies $cookies,
@@ -52,7 +56,8 @@ class Clicks {
Opens $opens,
StatisticsClicksRepository $statisticsClicksRepository,
UserAgentsRepository $userAgentsRepository,
LinkShortcodeCategory $linkShortcodeCategory
LinkShortcodeCategory $linkShortcodeCategory,
SubscribersRepository $subscribersRepository
) {
$this->settingsController = $settingsController;
$this->cookies = $cookies;
@@ -61,6 +66,7 @@ class Clicks {
$this->opens = $opens;
$this->statisticsClicksRepository = $statisticsClicksRepository;
$this->userAgentsRepository = $userAgentsRepository;
$this->subscribersRepository = $subscribersRepository;
}
/**
@@ -102,6 +108,8 @@ class Clicks {
$this->sendAbandonedCartCookie($subscriber);
// track open event
$this->opens->track($data, $displayImage = false);
// Update engagement date
$this->subscribersRepository->maybeUpdateLastEngagement($subscriber, $userAgent ?? null);
}
$url = $this->processUrl($link->getUrl(), $newsletter, $subscriber, $queue, $wpUserPreview);
$this->redirectToUrl($url);

View File

@@ -10,7 +10,6 @@ use MailPoet\Entities\UserAgentEntity;
use MailPoet\Statistics\StatisticsOpensRepository;
use MailPoet\Statistics\UserAgentsRepository;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoetVendor\Carbon\Carbon;
class Opens {
/** @var StatisticsOpensRepository */
@@ -63,7 +62,7 @@ class Opens {
$this->statisticsOpensRepository->flush();
}
}
$this->maybeUpdateLastEngagement($subscriber, $userAgent ?? null);
$this->subscribersRepository->maybeUpdateLastEngagement($subscriber, $userAgent ?? null);
return $this->returnResponse($displayImage);
}
$statistics = new StatisticsOpenEntity($newsletter, $queue, $subscriber);
@@ -74,21 +73,12 @@ class Opens {
}
$this->statisticsOpensRepository->persist($statistics);
$this->statisticsOpensRepository->flush();
$this->maybeUpdateLastEngagement($subscriber, $userAgent ?? null);
$this->subscribersRepository->maybeUpdateLastEngagement($subscriber, $userAgent ?? null);
$this->statisticsOpensRepository->recalculateSubscriberScore($subscriber);
}
return $this->returnResponse($displayImage);
}
private function maybeUpdateLastEngagement(SubscriberEntity $subscriberEntity, ?UserAgentEntity $userAgent): void {
if ($userAgent instanceof UserAgentEntity && $userAgent->getUserAgentType() === UserAgentEntity::USER_AGENT_TYPE_MACHINE) {
return;
}
// Update last engagement for human (and also unknown) user agent
$subscriberEntity->setLastEngagementAt(Carbon::now());
$this->subscribersRepository->flush();
}
public function returnResponse($displayImage) {
if (!$displayImage) return;
// return 1x1 pixel transparent gif image

View File

@@ -7,6 +7,7 @@ use MailPoet\Entities\SegmentEntity;
use MailPoet\Entities\SubscriberCustomFieldEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Entities\SubscriberSegmentEntity;
use MailPoet\Entities\UserAgentEntity;
use MailPoet\WP\Functions as WPFunctions;
use MailPoetVendor\Carbon\Carbon;
use MailPoetVendor\Doctrine\DBAL\Connection;
@@ -306,4 +307,13 @@ class SubscribersRepository extends Repository {
->setMaxResults($limit)
->getResult();
}
public function maybeUpdateLastEngagement(SubscriberEntity $subscriberEntity, ?UserAgentEntity $userAgent): void {
if ($userAgent instanceof UserAgentEntity && $userAgent->getUserAgentType() === UserAgentEntity::USER_AGENT_TYPE_MACHINE) {
return;
}
// Update last engagement for human (and also unknown) user agent
$subscriberEntity->setLastEngagementAt(Carbon::now());
$this->flush();
}
}

View File

@@ -23,19 +23,31 @@ use MailPoet\Statistics\Track\Clicks;
use MailPoet\Statistics\Track\Opens;
use MailPoet\Statistics\UserAgentsRepository;
use MailPoet\Subscribers\LinkTokens;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoet\Tasks\Sending as SendingTask;
use MailPoet\Util\Cookies;
use MailPoetVendor\Carbon\Carbon;
class ClicksTest extends \MailPoetTest {
/** @var \stdClass */
public $trackData;
/** @var NewsletterLinkEntity */
public $link;
/** @var SendingQueueEntity */
public $queue;
/** @var SubscriberEntity */
public $subscriber;
/** @var NewsletterEntity */
public $newsletter;
/** @var Clicks */
private $clicks;
/** @var SettingsController */
private $settingsController;
public function _before() {
@@ -94,7 +106,8 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(Opens::class),
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class)
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class)
);
}
@@ -108,6 +121,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'abort' => Expected::exactly(2),
], $this);
@@ -132,6 +146,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -150,6 +165,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -170,6 +186,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -192,6 +209,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -218,6 +236,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -258,6 +277,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -298,6 +318,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -331,6 +352,7 @@ class ClicksTest extends \MailPoetTest {
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -366,6 +388,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => Expected::exactly(1),
], $this);
@@ -381,6 +404,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
@@ -410,6 +434,7 @@ class ClicksTest extends \MailPoetTest {
$this->diContainer->get(StatisticsClicksRepository::class),
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'abort' => Expected::exactly(1),
], $this);
@@ -456,6 +481,70 @@ class ClicksTest extends \MailPoetTest {
expect($link)->equals('http://example.com/?email=test@example.com&newsletter_subject=Subject');
}
public function testItUpdatesSubscriberEngagementForHumanAgent() {
Carbon::setTestNow($now = Carbon::now());
$clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class);
$data = $this->trackData;
$data->userAgent = 'User Agent';
$clicks = Stub::construct($this->clicks, [
$this->settingsController,
new Cookies(),
$this->diContainer->get(Shortcodes::class),
$this->diContainer->get(Opens::class),
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
$clicks->track($data);
expect($this->subscriber->getLastEngagementAt())->equals($now);
Carbon::setTestNow();
}
public function testItUpdatesSubscriberEngagementForUnknownAgent() {
Carbon::setTestNow($now = Carbon::now());
$clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class);
$data = $this->trackData;
$data->userAgent = null;
$clicks = Stub::construct($this->clicks, [
$this->settingsController,
new Cookies(),
$this->diContainer->get(Shortcodes::class),
$this->diContainer->get(Opens::class),
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
$clicks->track($data);
expect($this->subscriber->getLastEngagementAt())->equals($now);
Carbon::setTestNow();
}
public function testItWontUpdateSubscriberEngagementForMachineAgent() {
$clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class);
$data = $this->trackData;
$data->userAgent = UserAgentEntity::MACHINE_USER_AGENTS[0];
$clicks = Stub::construct($this->clicks, [
$this->settingsController,
new Cookies(),
$this->diContainer->get(Shortcodes::class),
$this->diContainer->get(Opens::class),
$clicksRepository,
$this->diContainer->get(UserAgentsRepository::class),
$this->diContainer->get(LinkShortcodeCategory::class),
$this->diContainer->get(SubscribersRepository::class),
], [
'redirectToUrl' => null,
], $this);
$clicks->track($data);
expect($this->subscriber->getLastEngagementAt())->null();
}
public function cleanup() {
$this->truncateEntity(NewsletterEntity::class);
$this->truncateEntity(SubscriberEntity::class);