- Implements tracking of unsubscribe events

This commit is contained in:
Vlad
2016-04-25 11:06:01 -04:00
parent a8e3dd424e
commit 4b29b04bd1
10 changed files with 400 additions and 7 deletions

View File

@ -85,6 +85,7 @@ class Initializer {
$statistics_newsletters = Env::$db_prefix . 'statistics_newsletters'; $statistics_newsletters = Env::$db_prefix . 'statistics_newsletters';
$statistics_clicks = Env::$db_prefix . 'statistics_clicks'; $statistics_clicks = Env::$db_prefix . 'statistics_clicks';
$statistics_opens = Env::$db_prefix . 'statistics_opens'; $statistics_opens = Env::$db_prefix . 'statistics_opens';
$statistics_unsubscribes = Env::$db_prefix . 'statistics_unsubscribes';
define('MP_SETTINGS_TABLE', $settings); define('MP_SETTINGS_TABLE', $settings);
define('MP_SEGMENTS_TABLE', $segments); define('MP_SEGMENTS_TABLE', $segments);
@ -103,6 +104,7 @@ class Initializer {
define('MP_STATISTICS_NEWSLETTERS_TABLE', $statistics_newsletters); define('MP_STATISTICS_NEWSLETTERS_TABLE', $statistics_newsletters);
define('MP_STATISTICS_CLICKS_TABLE', $statistics_clicks); define('MP_STATISTICS_CLICKS_TABLE', $statistics_clicks);
define('MP_STATISTICS_OPENS_TABLE', $statistics_opens); define('MP_STATISTICS_OPENS_TABLE', $statistics_opens);
define('MP_STATISTICS_UNSUBSCRIBES_TABLE', $statistics_unsubscribes);
} }
function runMigrator() { function runMigrator() {

View File

@ -26,7 +26,8 @@ class Migrator {
'forms', 'forms',
'statistics_newsletters', 'statistics_newsletters',
'statistics_clicks', 'statistics_clicks',
'statistics_opens' 'statistics_opens',
'statistics_unsubscribes'
); );
} }
@ -287,7 +288,6 @@ class Migrator {
'link_id mediumint(9) NOT NULL,', 'link_id mediumint(9) NOT NULL,',
'count mediumint(9) NOT NULL,', 'count mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)', 'PRIMARY KEY (id)',
); );
@ -301,8 +301,18 @@ class Migrator {
'subscriber_id mediumint(9) NOT NULL,', 'subscriber_id mediumint(9) NOT NULL,',
'queue_id mediumint(9) NOT NULL,', 'queue_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'deleted_at TIMESTAMP NULL DEFAULT NULL,', 'PRIMARY KEY (id)',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', );
return $this->sqlify(__FUNCTION__, $attributes);
}
function statistics_unsubscribes() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,',
'subscriber_id mediumint(9) NOT NULL,',
'queue_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'PRIMARY KEY (id)', 'PRIMARY KEY (id)',
); );
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);

View File

@ -0,0 +1,80 @@
<?php
namespace MailPoet\Config;
use MailPoet\Cron\Daemon;
<<<<<<< 378f6d803a9ad45c36cbea3bc268c3c4e9e05f86
use MailPoet\Statistics\Track\Clicks;
=======
use MailPoet\Subscription;
>>>>>>> Subscription pages
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class PublicAPI {
public $api;
public $endpoint;
public $action;
public $data;
function __construct() {
# http://example.com/?mailpoet&endpoint=&action=&data=
$this->api = isset($_GET['mailpoet']) ? true : false;
$this->endpoint = isset($_GET['endpoint']) ?
Helpers::underscoreToCamelCase($_GET['endpoint']) :
false;
$this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) :
false;
$this->data = (
(isset($_GET['data']))
? unserialize(base64_decode($_GET['data']))
: array()
);
}
function init() {
if(!$this->api && !$this->endpoint) return;
$this->_checkAndCallMethod($this, $this->endpoint, $terminate_request = true);
}
function queue() {
try {
$queue = new Daemon($this->data);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
}
}
<<<<<<< 378f6d803a9ad45c36cbea3bc268c3c4e9e05f86
function track() {
try {
if ($this->action === 'click') {
$track_class = new Clicks($this->data);
}
if (!isset($track_class)) return;
$track_class->track();
=======
function subscription() {
try {
$subscription = new Subscription\Pages($this->action, $this->data);
$this->_checkAndCallMethod($subscription, $this->action);
>>>>>>> Subscription pages
} catch(\Exception $e) {
}
}
private function _checkAndCallMethod($class, $method, $terminate_request = false) {
if(!method_exists($class, $method)) {
if(!$terminate_request) return;
header('HTTP/1.0 404 Not Found');
exit;
}
call_user_func(
array(
$class,
$method
)
);
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace MailPoet\Config;
use MailPoet\Cron\Daemon;
<<<<<<< 378f6d803a9ad45c36cbea3bc268c3c4e9e05f86
use MailPoet\Statistics\Track\Clicks;
=======
use MailPoet\Subscription;
>>>>>>> Subscription pages
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class PublicAPI {
public $api;
public $endpoint;
public $action;
public $data;
function __construct() {
# http://example.com/?mailpoet&endpoint=&action=&data=
$this->api = isset($_GET['mailpoet']) ? true : false;
$this->endpoint = isset($_GET['endpoint']) ?
Helpers::underscoreToCamelCase($_GET['endpoint']) :
false;
$this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) :
false;
$this->data = (
(isset($_GET['data']))
? unserialize(base64_decode($_GET['data']))
: array()
);
}
function init() {
if(!$this->api && !$this->endpoint) return;
$this->_checkAndCallMethod($this, $this->endpoint, $terminate_request = true);
}
function queue() {
try {
$queue = new Daemon($this->data);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
}
}
<<<<<<< 378f6d803a9ad45c36cbea3bc268c3c4e9e05f86
function track() {
try {
if ($this->action === 'click') {
$track_class = new Clicks($this->data);
}
if (!isset($track_class)) return;
$track_class->track();
=======
function subscription() {
try {
$subscription = new Subscription\Pages($this->action, $this->data);
$this->_checkAndCallMethod($subscription, $this->action);
>>>>>>> Subscription pages
} catch(\Exception $e) {
}
}
private function _checkAndCallMethod($class, $method, $terminate_request = false) {
if(!method_exists($class, $method)) {
if(!$terminate_request) return;
header('HTTP/1.0 404 Not Found');
exit;
}
call_user_func(
array(
$class,
$method
)
);
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace MailPoet\Config;
use MailPoet\Cron\Daemon;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class PublicAPI {
public $api;
public $endpoint;
public $action;
public $data;
function __construct() {
# http://example.com/?mailpoet&endpoint=&action=&data=
$this->api = isset($_GET['mailpoet']) ? true : false;
$this->endpoint = isset($_GET['endpoint']) ?
Helpers::underscoreToCamelCase($_GET['endpoint']) :
false;
$this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) :
false;
$this->data = isset($_GET['data']) ? $_GET['data'] : false;
}
function init() {
if(!$this->api && !$this->endpoint) return;
$this->_checkAndCallMethod($this, $this->endpoint, $terminate_request = true);
}
function queue() {
try {
$queue = new Daemon($this->data);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
}
}
private function _checkAndCallMethod($class, $method, $terminate_request = false) {
if(!method_exists($class, $method)) {
if(!$terminate_request) return;
header('HTTP/1.0 404 Not Found');
exit;
}
call_user_func(
array(
$class,
$method
)
);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace MailPoet\Config;
use MailPoet\Cron\Daemon;
use MailPoet\Statistics\Track\Clicks;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class PublicAPI {
public $api;
public $endpoint;
public $action;
public $data;
function __construct() {
# http://example.com/?mailpoet&endpoint=&action=&data=
$this->api = isset($_GET['mailpoet']) ? true : false;
$this->endpoint = isset($_GET['endpoint']) ?
Helpers::underscoreToCamelCase($_GET['endpoint']) :
false;
$this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) :
false;
$this->data = isset($_GET['data']) ? $_GET['data'] : false;
}
function init() {
if(!$this->api && !$this->endpoint) return;
$this->_checkAndCallMethod($this, $this->endpoint, $terminate_request = true);
}
function queue() {
try {
$queue = new Daemon($this->data);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
}
}
function track() {
try {
if ($this->action === 'click') {
$track_class = new Clicks($this->data);
}
if (!isset($track_class)) return;
$track_class->track();
} catch(\Exception $e) {
}
}
private function _checkAndCallMethod($class, $method, $terminate_request = false) {
if(!method_exists($class, $method)) {
if(!$terminate_request) return;
header('HTTP/1.0 404 Not Found');
exit;
}
call_user_func(
array(
$class,
$method
)
);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace MailPoet\Config;
use MailPoet\Cron\Daemon;
use MailPoet\Subscription;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class PublicAPI {
public $api;
public $endpoint;
public $action;
public $data;
function __construct() {
# http://example.com/?mailpoet&endpoint=&action=&data=
$this->api = isset($_GET['mailpoet']) ? true : false;
$this->endpoint = isset($_GET['endpoint']) ?
Helpers::underscoreToCamelCase($_GET['endpoint']) :
false;
$this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) :
false;
$this->data = (
(isset($_GET['data']))
? unserialize(base64_decode($_GET['data']))
: array()
);
}
function init() {
if(!$this->api && !$this->endpoint) return;
$this->_checkAndCallMethod($this, $this->endpoint, $terminate_request = true);
}
function queue() {
try {
$queue = new Daemon($this->data);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
}
}
function subscription() {
try {
$subscription = new Subscription\Pages($this->action, $this->data);
$this->_checkAndCallMethod($subscription, $this->action);
} catch(\Exception $e) {
}
}
private function _checkAndCallMethod($class, $method, $terminate_request = false) {
if(!method_exists($class, $method)) {
if(!$terminate_request) return;
header('HTTP/1.0 404 Not Found');
exit;
}
call_user_func(
array(
$class,
$method
)
);
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace MailPoet\Models;
if(!defined('ABSPATH')) exit;
class StatisticsUnsubscribes extends Model {
public static $_table = MP_STATISTICS_UNSUBSCRIBES_TABLE;
function __construct() {
parent::__construct();
}
}

View File

@ -45,16 +45,19 @@ class Clicks {
$statistics->save(); $statistics->save();
} }
$url = (preg_match('/\[subscription:.*?\]/', $link->url)) ? $url = (preg_match('/\[subscription:.*?\]/', $link->url)) ?
$this->processSubscriptionUrl($link->url, $subscriber) : $this->processSubscriptionUrl($link->url, $subscriber, $queue_id, $newsletter_id) :
$link->url; $link->url;
header('Location: ' . $url, true, 302); header('Location: ' . $url, true, 302);
} }
function processSubscriptionUrl($url, $subscriber) { function processSubscriptionUrl($url, $subscriber, $queue_id, $newsletter_id) {
preg_match('/\[subscription:(.*?)\]/', $url, $match); preg_match('/\[subscription:(.*?)\]/', $url, $match);
$action = $match[1]; $action = $match[1];
if(preg_match('/unsubscribe/', $action)) { if(preg_match('/unsubscribe/', $action)) {
$url = SubscriptionUrl::getUnsubscribeUrl($subscriber); $url = SubscriptionUrl::getUnsubscribeUrl($subscriber);
// track unsubscribe action
$unsubscribes = new Unsubscribes();
$unsubscribes->track($subscriber->id, $queue_id, $newsletter_id);
} }
if(preg_match('/manage/', $action)) { if(preg_match('/manage/', $action)) {
$url = SubscriptionUrl::getManageUrl($subscriber); $url = SubscriptionUrl::getManageUrl($subscriber);

View File

@ -0,0 +1,22 @@
<?php
namespace MailPoet\Statistics\Track;
use MailPoet\Models\StatisticsUnsubscribes;
if(!defined('ABSPATH')) exit;
class Unsubscribes {
function track($subscriber_id, $queue_id, $newsletter_id) {
$statistics = StatisticsUnsubscribes::where('subscriber_id', $subscriber_id)
->where('newsletter_id', $newsletter_id)
->where('queue_id', $queue_id)
->findOne();
if(!$statistics) {
$statistics = StatisticsUnsubscribes::create();
$statistics->newsletter_id = $newsletter_id;
$statistics->subscriber_id = $subscriber_id;
$statistics->queue_id = $queue_id;
$statistics->save();
}
}
}