- Implements tracking of unsubscribe events
This commit is contained in:
@ -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() {
|
||||||
|
@ -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);
|
||||||
|
80
lib/Config/PublicAPI.php.orig
Normal file
80
lib/Config/PublicAPI.php.orig
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
80
lib/Config/PublicAPI_BACKUP_4940.php
Normal file
80
lib/Config/PublicAPI_BACKUP_4940.php
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
53
lib/Config/PublicAPI_BASE_4940.php
Normal file
53
lib/Config/PublicAPI_BASE_4940.php
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
65
lib/Config/PublicAPI_LOCAL_4940.php
Normal file
65
lib/Config/PublicAPI_LOCAL_4940.php
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
66
lib/Config/PublicAPI_REMOTE_4940.php
Normal file
66
lib/Config/PublicAPI_REMOTE_4940.php
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
12
lib/Models/StatisticsUnsubscribes.php
Normal file
12
lib/Models/StatisticsUnsubscribes.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
22
lib/Statistics/Track/Unsubscribes.php
Normal file
22
lib/Statistics/Track/Unsubscribes.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user