diff --git a/lib/Subscribers/SubscribersRepository.php b/lib/Subscribers/SubscribersRepository.php index 7b10ecd994..9521a78ffc 100644 --- a/lib/Subscribers/SubscribersRepository.php +++ b/lib/Subscribers/SubscribersRepository.php @@ -312,6 +312,10 @@ class SubscribersRepository extends Repository { if ($userAgent instanceof UserAgentEntity && $userAgent->getUserAgentType() === UserAgentEntity::USER_AGENT_TYPE_MACHINE) { return; } + // Do not update engagement if was recently updated to avoid unnecessary updates in DB + if ($subscriberEntity->getLastEngagementAt() && $subscriberEntity->getLastEngagementAt() > Carbon::now()->subMinute()) { + return; + } // Update last engagement for human (and also unknown) user agent $subscriberEntity->setLastEngagementAt(Carbon::now()); $this->flush(); diff --git a/tests/integration/Statistics/Track/ClicksTest.php b/tests/integration/Statistics/Track/ClicksTest.php index 8083d8c52e..93c412c728 100644 --- a/tests/integration/Statistics/Track/ClicksTest.php +++ b/tests/integration/Statistics/Track/ClicksTest.php @@ -545,6 +545,28 @@ class ClicksTest extends \MailPoetTest { expect($this->subscriber->getLastEngagementAt())->null(); } + public function testItWontUpdateSubscriberThatWasRecentlyUpdated() { + $lastEngagement = Carbon::now()->subSeconds(10); + $clicksRepository = $this->diContainer->get(StatisticsClicksRepository::class); + $this->subscriber->setLastEngagementAt($lastEngagement); + $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())->equals($lastEngagement); + } + public function cleanup() { $this->truncateEntity(NewsletterEntity::class); $this->truncateEntity(SubscriberEntity::class);