Add tracking cookie
[MAILPOET-1961]
This commit is contained in:
@@ -78,8 +78,10 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
// Router
|
||||
$container->autowire(\MailPoet\Router\Endpoints\CronDaemon::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Router\Endpoints\Subscription::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Router\Endpoints\Track::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Router\Endpoints\ViewInBrowser::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Router\Endpoints\Track::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Statistics\Track\Clicks::class);
|
||||
$container->autowire(\MailPoet\Statistics\Track\Opens::class);
|
||||
$container->autowire(\MailPoet\Router\Router::class)
|
||||
->setArgument('$container', new Reference(ContainerWrapper::class));
|
||||
// Mailer
|
||||
|
@@ -27,14 +27,23 @@ class Track {
|
||||
'global' => AccessControl::NO_ACCESS_RESTRICTION
|
||||
);
|
||||
|
||||
/** @var Clicks */
|
||||
private $clicks;
|
||||
|
||||
/** @var Opens */
|
||||
private $opens;
|
||||
|
||||
public function __construct(Clicks $clicks, Opens $opens) {
|
||||
$this->clicks = $clicks;
|
||||
$this->opens = $opens;
|
||||
}
|
||||
|
||||
function click($data) {
|
||||
$click_event = new Clicks();
|
||||
return $click_event->track($this->_processTrackData($data));
|
||||
return $this->clicks->track($this->_processTrackData($data));
|
||||
}
|
||||
|
||||
function open($data) {
|
||||
$open_event = new Opens();
|
||||
return $open_event->track($this->_processTrackData($data));
|
||||
return $this->opens->track($this->_processTrackData($data));
|
||||
}
|
||||
|
||||
function _processTrackData($data) {
|
||||
|
@@ -4,11 +4,22 @@ namespace MailPoet\Statistics\Track;
|
||||
use MailPoet\Models\StatisticsClicks;
|
||||
use MailPoet\Newsletter\Shortcodes\Categories\Link;
|
||||
use MailPoet\Newsletter\Shortcodes\Shortcodes;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
class Clicks {
|
||||
|
||||
const REVENUE_TRACKING_COOKIE_EXPIRY = 60 * 60 * 24 * 14;
|
||||
|
||||
/** @var SettingsController */
|
||||
private $settings_controller;
|
||||
|
||||
public function __construct(SettingsController $settings_controller) {
|
||||
$this->settings_controller = $settings_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass|null $data
|
||||
*/
|
||||
@@ -24,12 +35,13 @@ class Clicks {
|
||||
// log statistics only if the action did not come from
|
||||
// a WP user previewing the newsletter
|
||||
if (!$wp_user_preview) {
|
||||
StatisticsClicks::createOrUpdateClickCount(
|
||||
$statistics_clicks = StatisticsClicks::createOrUpdateClickCount(
|
||||
$link->id,
|
||||
$subscriber->id,
|
||||
$newsletter->id,
|
||||
$queue->id
|
||||
);
|
||||
$this->sendRevenueCookie($statistics_clicks);
|
||||
// track open event
|
||||
$open_event = new Opens();
|
||||
$open_event->track($data, $display_image = false);
|
||||
@@ -38,6 +50,20 @@ class Clicks {
|
||||
$this->redirectToUrl($url);
|
||||
}
|
||||
|
||||
private function sendRevenueCookie(StatisticsClicks $clicks) {
|
||||
if ($this->settings_controller->get('accept_cookie_revenue_tracking')) {
|
||||
setcookie(
|
||||
'mailpoet_revenue_tracking',
|
||||
serialize([
|
||||
'statistics_clicks' => $clicks->id,
|
||||
'created_at' => time(),
|
||||
]),
|
||||
time() + self::REVENUE_TRACKING_COOKIE_EXPIRY,
|
||||
'/'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function processUrl($url, $newsletter, $subscriber, $queue, $wp_user_preview) {
|
||||
if (preg_match('/\[link:(?P<action>.*?)\]/', $url, $shortcode)) {
|
||||
if (!$shortcode['action']) $this->abort();
|
||||
|
@@ -50,6 +50,11 @@ class Settings {
|
||||
return $this;
|
||||
}
|
||||
|
||||
function withTrackingEnabled() {
|
||||
$this->settings->set('tracking.enabled', true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
function withTodayInstallationDate() {
|
||||
$this->settings->set('installed_at', date("Y-m-d H:i:s"));
|
||||
}
|
||||
@@ -84,4 +89,9 @@ class Settings {
|
||||
$this->settings->set('mta_log.error.error_message', $error_message);
|
||||
return $this;
|
||||
}
|
||||
|
||||
function withCookieRevenueTracking() {
|
||||
$this->settings->set('accept_cookie_revenue_tracking', true);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
40
tests/acceptance/RevenueTrackingCookieCest.php
Normal file
40
tests/acceptance/RevenueTrackingCookieCest.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Test\Acceptance;
|
||||
|
||||
use Codeception\Util\Locator;
|
||||
use MailPoet\Test\DataFactories\Newsletter;
|
||||
use MailPoet\Test\DataFactories\Settings;
|
||||
|
||||
require_once __DIR__ . '/../DataFactories/Newsletter.php';
|
||||
require_once __DIR__ . '/../DataFactories/Settings.php';
|
||||
|
||||
class RevenueTrackingCookieCest {
|
||||
|
||||
function cookieIsStoredOnClick(\AcceptanceTester $I) {
|
||||
$I->wantTo('Test Revenue cookie is saved');
|
||||
$newsletter_subject = 'Receive Test';
|
||||
$newsletter = (new Newsletter())->withSubject($newsletter_subject)->create();
|
||||
(new Settings())->withCookieRevenueTracking()->withTrackingEnabled();
|
||||
$segment_name = $I->createListWithSubscriber();
|
||||
|
||||
$I->login();
|
||||
$I->amEditingNewsletter($newsletter->id);
|
||||
$I->click('Next');
|
||||
|
||||
$I->waitForElement('[data-automation-id="newsletter_send_form"]');
|
||||
$I->selectOptionInSelect2($segment_name);
|
||||
$I->click('Send');
|
||||
$I->waitForElement('.mailpoet_progress_label');
|
||||
|
||||
$I->logOut();
|
||||
$I->amOnMailboxAppPage();
|
||||
$I->waitForText($newsletter_subject);
|
||||
$I->click(Locator::contains('span.subject', $newsletter_subject));
|
||||
$I->switchToIframe('preview-html');
|
||||
$I->click('Read the post');
|
||||
$I->switchToNextTab();
|
||||
$I->canSeeCookie('mailpoet_revenue_tracking');
|
||||
}
|
||||
|
||||
}
|
@@ -9,6 +9,9 @@ use MailPoet\Models\ScheduledTaskSubscriber;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Router\Endpoints\Track;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Statistics\Track\Clicks;
|
||||
use MailPoet\Statistics\Track\Opens;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
|
||||
class TrackTest extends \MailPoetTest {
|
||||
@@ -47,7 +50,7 @@ class TrackTest extends \MailPoetTest {
|
||||
'preview' => false
|
||||
);
|
||||
// instantiate class
|
||||
$this->track = new Track($this->track_data);
|
||||
$this->track = new Track(new Clicks(new SettingsController()), new Opens());
|
||||
}
|
||||
|
||||
function testItReturnsFalseWhenTrackDataIsMissing() {
|
||||
@@ -75,7 +78,7 @@ class TrackTest extends \MailPoetTest {
|
||||
)
|
||||
);
|
||||
$data->subscriber->email = 'random@email.com';
|
||||
$track = Stub::make(new Track(), ['terminate' => function($code) {
|
||||
$track = Stub::make(Track::class, ['terminate' => function($code) {
|
||||
expect($code)->equals(403);
|
||||
}]);
|
||||
$track->_validateTrackData($data);
|
||||
|
@@ -10,6 +10,7 @@ use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\StatisticsClicks;
|
||||
use MailPoet\Models\StatisticsOpens;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Statistics\Track\Clicks;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
|
||||
@@ -18,6 +19,8 @@ class ClicksTest extends \MailPoetTest {
|
||||
/** @var Clicks */
|
||||
private $clicks;
|
||||
|
||||
private $settings_controller;
|
||||
|
||||
function _before() {
|
||||
parent::_before();
|
||||
// create newsletter
|
||||
@@ -54,12 +57,15 @@ class ClicksTest extends \MailPoetTest {
|
||||
'preview' => false
|
||||
);
|
||||
// instantiate class
|
||||
$this->clicks = new Clicks();
|
||||
$this->settings_controller = Stub::makeEmpty(SettingsController::class, [
|
||||
'get' => false,
|
||||
], $this);
|
||||
$this->clicks = new Clicks($this->settings_controller);
|
||||
}
|
||||
|
||||
function testItAbortsWhenTrackDataIsEmptyOrMissingLink() {
|
||||
// abort function should be called twice:
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'abort' => Expected::exactly(2)
|
||||
), $this);
|
||||
$data = $this->track_data;
|
||||
@@ -74,8 +80,8 @@ class ClicksTest extends \MailPoetTest {
|
||||
$data = $this->track_data;
|
||||
$data->subscriber->wp_user_id = 99;
|
||||
$data->preview = true;
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
'redirectToUrl' => null
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'redirectToUrl' => null,
|
||||
), $this);
|
||||
$clicks->track($data);
|
||||
expect(StatisticsClicks::findMany())->isEmpty();
|
||||
@@ -84,8 +90,8 @@ class ClicksTest extends \MailPoetTest {
|
||||
|
||||
function testItTracksClickAndOpenEvent() {
|
||||
$data = $this->track_data;
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
'redirectToUrl' => null
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'redirectToUrl' => null,
|
||||
), $this);
|
||||
$clicks->track($data);
|
||||
expect(StatisticsClicks::findMany())->notEmpty();
|
||||
@@ -93,15 +99,15 @@ class ClicksTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItRedirectsToUrlAfterTracking() {
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'redirectToUrl' => Expected::exactly(1)
|
||||
), $this);
|
||||
$clicks->track($this->track_data);
|
||||
}
|
||||
|
||||
function testItIncrementsClickEventCount() {
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
'redirectToUrl' => null
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'redirectToUrl' => null,
|
||||
), $this);
|
||||
$clicks->track($this->track_data);
|
||||
expect(StatisticsClicks::findMany()[0]->count)->equals(1);
|
||||
@@ -121,7 +127,7 @@ class ClicksTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItFailsToConvertsInvalidShortcodeToUrl() {
|
||||
$clicks = Stub::make($this->clicks, array(
|
||||
$clicks = Stub::construct($this->clicks, [$this->settings_controller], array(
|
||||
'abort' => Expected::exactly(1)
|
||||
), $this);
|
||||
// should call abort() method if shortcode action does not exist
|
||||
|
Reference in New Issue
Block a user