- Implements open tracking
This commit is contained in:
@ -84,6 +84,7 @@ class Initializer {
|
||||
$newsletter_links = Env::$db_prefix . 'newsletter_links';
|
||||
$statistics_newsletters = Env::$db_prefix . 'statistics_newsletters';
|
||||
$statistics_clicks = Env::$db_prefix . 'statistics_clicks';
|
||||
$statistics_opens = Env::$db_prefix . 'statistics_opens';
|
||||
|
||||
define('MP_SETTINGS_TABLE', $settings);
|
||||
define('MP_SEGMENTS_TABLE', $segments);
|
||||
@ -101,6 +102,7 @@ class Initializer {
|
||||
define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option);
|
||||
define('MP_STATISTICS_NEWSLETTERS_TABLE', $statistics_newsletters);
|
||||
define('MP_STATISTICS_CLICKS_TABLE', $statistics_clicks);
|
||||
define('MP_STATISTICS_OPENS_TABLE', $statistics_opens);
|
||||
}
|
||||
|
||||
function runMigrator() {
|
||||
|
@ -26,6 +26,7 @@ class Migrator {
|
||||
'forms',
|
||||
'statistics_newsletters',
|
||||
'statistics_clicks',
|
||||
'statistics_opens'
|
||||
);
|
||||
}
|
||||
|
||||
@ -293,6 +294,20 @@ class Migrator {
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
}
|
||||
|
||||
function statistics_opens() {
|
||||
$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,',
|
||||
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
}
|
||||
|
||||
private function sqlify($model, $attributes) {
|
||||
$table = $this->prefix . $model;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\Cron\Daemon;
|
||||
use MailPoet\Statistics\Track\Opens;
|
||||
use MailPoet\Subscription;
|
||||
use MailPoet\Statistics\Track\Clicks;
|
||||
use MailPoet\Util\Helpers;
|
||||
@ -54,6 +55,9 @@ class PublicAPI {
|
||||
if($this->action === 'click') {
|
||||
$track_class = new Clicks($this->data);
|
||||
}
|
||||
if($this->action === 'open') {
|
||||
$track_class = new Opens($this->data);
|
||||
}
|
||||
if(!isset($track_class)) return;
|
||||
$track_class->track();
|
||||
} catch(\Exception $e) {
|
||||
|
@ -9,6 +9,7 @@ use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\StatisticsNewsletters;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Links\Links;
|
||||
use MailPoet\Newsletter\Renderer\PostProcess\OpenTracking;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Newsletter\Shortcodes\Shortcodes;
|
||||
use MailPoet\Util\Helpers;
|
||||
@ -74,6 +75,10 @@ class SendingQueue {
|
||||
// check if newsletter has been rendered, in which case return its contents
|
||||
// or render and save for future reuse
|
||||
if($queue->newsletter_rendered_body === null) {
|
||||
// insert tracking code
|
||||
add_filter('mailpoet_rendering_post_process', function($template) {
|
||||
return OpenTracking::process($template);
|
||||
});
|
||||
// render newsletter
|
||||
$rendered_newsletter = $this->renderNewsletter($newsletter);
|
||||
if((boolean) Setting::getValue('tracking.enabled')) {
|
||||
|
@ -3,8 +3,8 @@ namespace MailPoet\Models;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class StatisticsClicks extends Model {
|
||||
public static $_table = MP_STATISTICS_CLICKS_TABLE;
|
||||
class StatisticsOpens extends Model {
|
||||
public static $_table = MP_STATISTICS_OPENS_TABLE;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
@ -2,12 +2,14 @@
|
||||
namespace MailPoet\Newsletter\Renderer\PostProcess;
|
||||
|
||||
class OpenTracking {
|
||||
static function process($template, $user_id) {
|
||||
static function process($template) {
|
||||
$DOM = new \pQuery();
|
||||
$DOM = $DOM->parseStr($template);
|
||||
$template = $DOM->query('body');
|
||||
$open_tracking_link = sprintf(
|
||||
'<img alt="" src="%s/?mailpoet&endpoint=track&action=open&data=[mailpoet_data]',
|
||||
home_url()
|
||||
'<img alt="" class="" src="%s/%s"/>',
|
||||
home_url(),
|
||||
htmlentities('?mailpoet&endpoint=track&action=open&data=[mailpoet_data]')
|
||||
);
|
||||
$template->html($template->html() . $open_tracking_link);
|
||||
return $DOM->__toString();
|
||||
|
@ -1,60 +1,39 @@
|
||||
<?php
|
||||
namespace MailPoet\Statistics\Track;
|
||||
|
||||
use MailPoet\Models\NewsletterLink;
|
||||
use MailPoet\Models\StatisticsClicks;
|
||||
use MailPoet\Models\StatisticsOpens;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Subscription\Url as SubscriptionUrl;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Opens {
|
||||
public $url;
|
||||
public $data;
|
||||
|
||||
function __construct($url) {
|
||||
$this->url = $url;
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function track($url = false) {
|
||||
$url = ($url) ? $url : $this->url;
|
||||
if(!preg_match('/\d+-\d+-\d+$/', $url)) $this->abort();
|
||||
list ($newsletter_id, $subscriber_id, $queue_id) = explode('-', $url);
|
||||
function track($data = false) {
|
||||
$data = ($data) ? $data : $this->data;
|
||||
if(!preg_match('/\d+-\d+-\d+/', $data)) $this->abort();
|
||||
list ($newsletter_id, $subscriber_id, $queue_id) = explode('-', $data);
|
||||
$subscriber = Subscriber::findOne($subscriber_id);
|
||||
if(!$subscriber) return;
|
||||
$statistics = StatisticsOpens::where('link_id', $link->id)
|
||||
->where('subscriber_id', $subscriber_id)
|
||||
$statistics = StatisticsOpens::where('subscriber_id', $subscriber_id)
|
||||
->where('newsletter_id', $newsletter_id)
|
||||
->where('queue_id', $queue_id)
|
||||
->findOne();
|
||||
if(!$statistics) {
|
||||
$statistics = StatisticsClicks::create();
|
||||
$statistics = StatisticsOpens::create();
|
||||
$statistics->newsletter_id = $newsletter_id;
|
||||
$statistics->link_id = $link->id;
|
||||
$statistics->subscriber_id = $subscriber_id;
|
||||
$statistics->queue_id = $queue_id;
|
||||
$statistics->count = 1;
|
||||
$statistics->save();
|
||||
} else {
|
||||
$statistics->count++;
|
||||
$statistics->save();
|
||||
}
|
||||
$url = (preg_match('/\[subscription:.*?\]/', $link->url)) ?
|
||||
$this->processSubscriptionUrl($link->url, $subscriber) :
|
||||
$link->url;
|
||||
header('Location: ' . $url, true, 302);
|
||||
}
|
||||
|
||||
function processSubscriptionUrl($url, $subscriber) {
|
||||
preg_match('/\[subscription:(.*?)\]/', $url, $match);
|
||||
$action = $match[1];
|
||||
if(preg_match('/unsubscribe/', $action)) {
|
||||
$url = SubscriptionUrl::getUnsubscribeUrl($subscriber);
|
||||
}
|
||||
if(preg_match('/manage/', $action)) {
|
||||
$url = SubscriptionUrl::getManageUrl($subscriber);
|
||||
}
|
||||
return $url;
|
||||
header('Content-Type: image/gif');
|
||||
// return 1x1 pixel transparent gif image
|
||||
echo "\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";
|
||||
exit;
|
||||
}
|
||||
|
||||
private function abort() {
|
||||
|
Reference in New Issue
Block a user