- Implements link extraction, processing, replacement and saving

This commit is contained in:
Vlad
2016-04-13 20:07:01 -04:00
parent 809be415c5
commit f1b955d74a
8 changed files with 304 additions and 128 deletions

View File

@ -68,35 +68,37 @@ class Initializer {
'SET TIME_ZONE = "' . Env::$db_timezone_offset. '"' 'SET TIME_ZONE = "' . Env::$db_timezone_offset. '"'
)); ));
$subscribers = Env::$db_prefix . 'subscribers';
$settings = Env::$db_prefix . 'settings'; $settings = Env::$db_prefix . 'settings';
$newsletters = Env::$db_prefix . 'newsletters';
$newsletter_templates = Env::$db_prefix . 'newsletter_templates';
$segments = Env::$db_prefix . 'segments'; $segments = Env::$db_prefix . 'segments';
$forms = Env::$db_prefix . 'forms'; $forms = Env::$db_prefix . 'forms';
$subscriber_segment = Env::$db_prefix . 'subscriber_segment';
$newsletter_segment = Env::$db_prefix . 'newsletter_segment';
$custom_fields = Env::$db_prefix . 'custom_fields'; $custom_fields = Env::$db_prefix . 'custom_fields';
$subscribers = Env::$db_prefix . 'subscribers';
$subscriber_segment = Env::$db_prefix . 'subscriber_segment';
$subscriber_custom_field = Env::$db_prefix . 'subscriber_custom_field'; $subscriber_custom_field = Env::$db_prefix . 'subscriber_custom_field';
$newsletter_segment = Env::$db_prefix . 'newsletter_segment';
$sending_queues = Env::$db_prefix . 'sending_queues';
$newsletters = Env::$db_prefix . 'newsletters';
$newsletter_templates = Env::$db_prefix . 'newsletter_templates';
$newsletter_option_fields = Env::$db_prefix . 'newsletter_option_fields'; $newsletter_option_fields = Env::$db_prefix . 'newsletter_option_fields';
$newsletter_option = Env::$db_prefix . 'newsletter_option'; $newsletter_option = Env::$db_prefix . 'newsletter_option';
$sending_queues = Env::$db_prefix . 'sending_queues';
$newsletter_statistics = Env::$db_prefix . 'newsletter_statistics'; $newsletter_statistics = Env::$db_prefix . 'newsletter_statistics';
$newsletter_links = Env::$db_prefix . 'newsletter_links';
define('MP_SUBSCRIBERS_TABLE', $subscribers);
define('MP_SETTINGS_TABLE', $settings); define('MP_SETTINGS_TABLE', $settings);
define('MP_NEWSLETTERS_TABLE', $newsletters);
define('MP_SEGMENTS_TABLE', $segments); define('MP_SEGMENTS_TABLE', $segments);
define('MP_FORMS_TABLE', $forms); define('MP_FORMS_TABLE', $forms);
define('MP_CUSTOM_FIELDS_TABLE', $custom_fields);
define('MP_SUBSCRIBERS_TABLE', $subscribers);
define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment); define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
define('MP_SENDING_QUEUES_TABLE', $sending_queues);
define('MP_NEWSLETTERS_TABLE', $newsletters);
define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates); define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates);
define('MP_NEWSLETTER_SEGMENT_TABLE', $newsletter_segment); define('MP_NEWSLETTER_SEGMENT_TABLE', $newsletter_segment);
define('MP_CUSTOM_FIELDS_TABLE', $custom_fields);
define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
define('MP_NEWSLETTER_OPTION_FIELDS_TABLE', $newsletter_option_fields); define('MP_NEWSLETTER_OPTION_FIELDS_TABLE', $newsletter_option_fields);
define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option);
define('MP_SENDING_QUEUES_TABLE', $sending_queues);
define('MP_NEWSLETTER_STATISTICS_TABLE', $newsletter_statistics); define('MP_NEWSLETTER_STATISTICS_TABLE', $newsletter_statistics);
define('MP_NEWSLETTER_LINKS_TABLE', $newsletter_links);
define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option);
} }
function runMigrator() { function runMigrator() {

View File

@ -10,19 +10,20 @@ class Migrator {
$this->prefix = Env::$db_prefix; $this->prefix = Env::$db_prefix;
$this->charset = Env::$db_charset; $this->charset = Env::$db_charset;
$this->models = array( $this->models = array(
'subscribers', 'segments',
'settings', 'settings',
'custom_fields',
'sending_queues',
'subscribers',
'subscriber_segment',
'subscriber_custom_field',
'newsletters', 'newsletters',
'newsletter_templates', 'newsletter_templates',
'segments',
'subscriber_segment',
'newsletter_segment',
'custom_fields',
'subscriber_custom_field',
'newsletter_option_fields', 'newsletter_option_fields',
'newsletter_option', 'newsletter_option',
'sending_queues', 'newsletter_segment',
'newsletter_statistics', 'newsletter_statistics',
'newsletter_links',
'forms' 'forms'
); );
} }
@ -49,6 +50,72 @@ class Migrator {
array_map($drop_table, $this->models); array_map($drop_table, $this->models);
} }
function segments() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(90) NOT NULL,',
'type varchar(90) NOT NULL DEFAULT "default",',
'description varchar(250) 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),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function settings() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(20) NOT NULL,',
'value longtext,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function custom_fields() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(90) NOT NULL,',
'type varchar(90) NOT NULL,',
'params longtext NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function sending_queues() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,',
'newsletter_rendered_body longtext,',
'newsletter_rendered_body_hash varchar(250) NULL DEFAULT NULL,',
'newsletter_rendered_subject varchar(250) NULL DEFAULT NULL,',
'subscribers longtext,',
'status varchar(12) NULL DEFAULT NULL,',
'priority mediumint(9) NOT NULL DEFAULT 0,',
'count_total mediumint(9) NOT NULL DEFAULT 0,',
'count_processed mediumint(9) NOT NULL DEFAULT 0,',
'count_to_process mediumint(9) NOT NULL DEFAULT 0,',
'count_failed mediumint(9) NOT NULL DEFAULT 0,',
'scheduled_at TIMESTAMP NOT NULL DEFAULT 0,',
'processed_at TIMESTAMP NOT NULL DEFAULT 0,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
'PRIMARY KEY (id)',
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function subscribers() { function subscribers() {
$attributes = array( $attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'id mediumint(9) NOT NULL AUTO_INCREMENT,',
@ -66,15 +133,30 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
function settings() { function subscriber_segment() {
$attributes = array( $attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(20) NOT NULL,', 'subscriber_id mediumint(9) NOT NULL,',
'value longtext,', 'segment_id mediumint(9) NOT NULL,',
'status varchar(12) NOT NULL DEFAULT "subscribed",',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'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),',
'UNIQUE KEY name (name)' 'UNIQUE KEY subscriber_segment (subscriber_id,segment_id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function subscriber_custom_field() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'subscriber_id mediumint(9) NOT NULL,',
'custom_field_id mediumint(9) NOT NULL,',
'value varchar(255) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY subscriber_id_custom_field_id (subscriber_id,custom_field_id)'
); );
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
@ -113,76 +195,6 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
function segments() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(90) NOT NULL,',
'type varchar(90) NOT NULL DEFAULT "default",',
'description varchar(250) 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),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function subscriber_segment() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'subscriber_id mediumint(9) NOT NULL,',
'segment_id mediumint(9) NOT NULL,',
'status varchar(12) NOT NULL DEFAULT "subscribed",',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY subscriber_segment (subscriber_id,segment_id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function newsletter_segment() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,',
'segment_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY newsletter_segment (newsletter_id,segment_id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function custom_fields() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(90) NOT NULL,',
'type varchar(90) NOT NULL,',
'params longtext NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function subscriber_custom_field() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'subscriber_id mediumint(9) NOT NULL,',
'custom_field_id mediumint(9) NOT NULL,',
'value varchar(255) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY subscriber_id_custom_field_id (subscriber_id,custom_field_id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function newsletter_option_fields() { function newsletter_option_fields() {
$attributes = array( $attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'id mediumint(9) NOT NULL AUTO_INCREMENT,',
@ -210,26 +222,15 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
function sending_queues() { function newsletter_segment() {
$attributes = array( $attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,', 'newsletter_id mediumint(9) NOT NULL,',
'newsletter_rendered_body longtext,', 'segment_id mediumint(9) NOT NULL,',
'newsletter_rendered_body_hash varchar(250) NULL DEFAULT NULL,',
'newsletter_rendered_subject varchar(250) NULL DEFAULT NULL,',
'subscribers longtext,',
'status varchar(12) NULL DEFAULT NULL,',
'priority mediumint(9) NOT NULL DEFAULT 0,',
'count_total mediumint(9) NOT NULL DEFAULT 0,',
'count_processed mediumint(9) NOT NULL DEFAULT 0,',
'count_to_process mediumint(9) NOT NULL DEFAULT 0,',
'count_failed mediumint(9) NOT NULL DEFAULT 0,',
'scheduled_at TIMESTAMP NOT NULL DEFAULT 0,',
'processed_at TIMESTAMP NOT NULL DEFAULT 0,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'deleted_at TIMESTAMP NULL DEFAULT NULL,', 'PRIMARY KEY (id),',
'PRIMARY KEY (id)', 'UNIQUE KEY newsletter_segment (newsletter_id,segment_id)'
); );
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
@ -246,6 +247,20 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
function newsletter_links() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,',
'queue_id mediumint(9) NOT NULL,',
'url varchar(255) NOT NULL,',
'hash varchar(20) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)',
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function forms() { function forms() {
$attributes = array( $attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'id mediumint(9) NOT NULL AUTO_INCREMENT,',

View File

@ -4,9 +4,11 @@ namespace MailPoet\Cron\Workers;
use MailPoet\Cron\CronHelper; use MailPoet\Cron\CronHelper;
use MailPoet\Mailer\Mailer; use MailPoet\Mailer\Mailer;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink;
use MailPoet\Models\NewsletterStatistics; use MailPoet\Models\NewsletterStatistics;
use MailPoet\Models\Setting; use MailPoet\Models\Setting;
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
use MailPoet\Newsletter\Links\Links;
use MailPoet\Newsletter\Renderer\Renderer; use MailPoet\Newsletter\Renderer\Renderer;
use MailPoet\Newsletter\Shortcodes\Shortcodes; use MailPoet\Newsletter\Shortcodes\Shortcodes;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
@ -17,6 +19,7 @@ class SendingQueue {
public $mta_config; public $mta_config;
public $mta_log; public $mta_log;
public $processing_method; public $processing_method;
public $divider = '***MailPoet***';
private $timer; private $timer;
const batch_size = 50; const batch_size = 50;
@ -38,7 +41,7 @@ class SendingQueue {
continue; continue;
} }
$newsletter = $newsletter->asArray(); $newsletter = $newsletter->asArray();
$newsletter['body'] = $this->getNewsletterBodyAndSubject($queue, $newsletter); $newsletter['body'] = $this->getOrRenderNewsletterBody($queue, $newsletter);
$queue->subscribers = (object) unserialize($queue->subscribers); $queue->subscribers = (object) unserialize($queue->subscribers);
if(!isset($queue->subscribers->processed)) { if(!isset($queue->subscribers->processed)) {
$queue->subscribers->processed = array(); $queue->subscribers->processed = array();
@ -67,11 +70,20 @@ class SendingQueue {
} }
} }
function getNewsletterBodyAndSubject($queue, $newsletter) { function getOrRenderNewsletterBody($queue, $newsletter) {
// check if newsletter has been rendered, in which case return its contents // check if newsletter has been rendered, in which case return its contents
// or render & and for future use // or render and save for future reuse
if($queue->newsletter_rendered_body === null) { if($queue->newsletter_rendered_body === null) {
$newsletter['body'] = $this->renderNewsletter($newsletter); // render newsletter
$rendered_newsletter = $this->renderNewsletter($newsletter);
// extract and replace links
$processed_newsletter = $this->processLinks(
$this->joinObject($rendered_newsletter),
$newsletter['id'],
$queue->id
);
list($newsletter['body']['html'], $newsletter['body']['text']) =
$this->splitObject($processed_newsletter);
$queue->newsletter_rendered_body = json_encode($newsletter['body']); $queue->newsletter_rendered_body = json_encode($newsletter['body']);
$queue->newsletter_rendered_body_hash = md5($newsletter['body']['text']); $queue->newsletter_rendered_body_hash = md5($newsletter['body']['text']);
$queue->save(); $queue->save();
@ -84,7 +96,7 @@ class SendingQueue {
function processBulkSubscribers($mailer, $newsletter, $subscribers, $queue) { function processBulkSubscribers($mailer, $newsletter, $subscribers, $queue) {
foreach($subscribers as $subscriber) { foreach($subscribers as $subscriber) {
$processed_newsletters[] = $processed_newsletters[] =
$this->processNewsletter($newsletter, $subscriber); $this->processNewsletter($newsletter, $subscriber, $queue);
$transformed_subscribers[] = $transformed_subscribers[] =
$mailer->transformSubscriber($subscriber); $mailer->transformSubscriber($subscriber);
} }
@ -125,8 +137,8 @@ class SendingQueue {
function processIndividualSubscriber($mailer, $newsletter, $subscribers, $queue) { function processIndividualSubscriber($mailer, $newsletter, $subscribers, $queue) {
foreach($subscribers as $subscriber) { foreach($subscribers as $subscriber) {
$this->checkSendingLimit(); $this->checkSendingLimit();
$processed_newsletter = $this->processNewsletter($newsletter, $subscriber); $processed_newsletter = $this->processNewsletter($newsletter, $subscriber, $queue);
if (!$queue->newsletter_rendered_subject) { if(!$queue->newsletter_rendered_subject) {
$queue->newsletter_rendered_subject = $processed_newsletter['subject']; $queue->newsletter_rendered_subject = $processed_newsletter['subject'];
} }
$transformed_subscriber = $mailer->transformSubscriber($subscriber); $transformed_subscriber = $mailer->transformSubscriber($subscriber);
@ -162,22 +174,61 @@ class SendingQueue {
return $renderer->render(); return $renderer->render();
} }
function processNewsletter($newsletter, $subscriber = false) { function processLinks($text, $newsletter_id, $queue_id) {
$divider = '***MailPoet***'; $links = new Links();
$data_for_shortcodes = list($text, $processed_links) = $links->replace($text);
array_merge(array($newsletter['subject']), $newsletter['body']); foreach($processed_links as $link) {
$body = implode($divider, $data_for_shortcodes); // save extracted and processed links
$shortcodes = new Shortcodes( $newsletter_link = NewsletterLink::create();
$newsletter_link->newsletter_id = $newsletter_id;
$newsletter_link->queue_id = $queue_id;
$newsletter_link->hash = $link['hash'];
$newsletter_link->url = $link['url'];
$newsletter_link->save();
}
return $text;
}
function processNewsletter($newsletter, $subscriber = false, $queue) {
$data_for_shortcodes = array(
$newsletter['subject'],
$newsletter['body']['html'],
$newsletter['body']['text']
);
$processed_newsletter = $this->replaceShortcodes(
$newsletter, $newsletter,
$subscriber $subscriber,
$this->joinObject($data_for_shortcodes)
);
$processed_newsletter = $this->replaceLinks(
$newsletter['id'],
$subscriber['id'],
$queue->id,
$processed_newsletter
); );
list($newsletter['subject'], list($newsletter['subject'],
$newsletter['body']['html'], $newsletter['body']['html'],
$newsletter['body']['text'] $newsletter['body']['text']
) = explode($divider, $shortcodes->replace($body)); ) = $this->splitObject($processed_newsletter);
return $newsletter; return $newsletter;
} }
function replaceLinks($newsletter_id, $subscriber_id, $queue_id, $body) {
return str_replace(
'[mailpoet_data]',
sprintf('%s-%s-%s', $newsletter_id, $subscriber_id, $queue_id),
$body
);
}
function replaceShortcodes($newsletter, $subscriber, $body) {
$shortcodes = new Shortcodes(
$newsletter,
$subscriber
);
return $shortcodes->replace($body);
}
function sendNewsletter($mailer, $newsletter, $subscriber) { function sendNewsletter($mailer, $newsletter, $subscriber) {
return $mailer->mailer_instance->send( return $mailer->mailer_instance->send(
$newsletter, $newsletter,
@ -284,4 +335,12 @@ class SendingQueue {
} }
return; return;
} }
private function joinObject($object = array()) {
return implode($this->divider, $object);
}
private function splitObject($object = array()) {
return explode($this->divider, $object);
}
} }

View File

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

View File

@ -3,8 +3,8 @@ namespace MailPoet\Models;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class NewsletterStatistics extends Model { class StatisticsNewsletters extends Model {
public static $_table = MP_NEWSLETTER_STATISTICS_TABLE; public static $_table = MP_STATISTICS_NEWSLETTERS_TABLE;
function __construct() { function __construct() {
parent::__construct(); parent::__construct();
@ -12,7 +12,7 @@ class NewsletterStatistics extends Model {
static function createMultiple($data) { static function createMultiple($data) {
return self::rawExecute( return self::rawExecute(
'INSERT INTO `' . NewsletterStatistics::$_table . '` ' . 'INSERT INTO `' . self::$_table . '` ' .
'(newsletter_id, subscriber_id, queue_id) ' . '(newsletter_id, subscriber_id, queue_id) ' .
'VALUES ' . rtrim( 'VALUES ' . rtrim(
str_repeat('(?,?,?), ', count($data)/3), str_repeat('(?,?,?), ', count($data)/3),

View File

@ -0,0 +1,24 @@
<?php
namespace MailPoet\Models;
if(!defined('ABSPATH')) exit;
class StatisticsNewsletters extends Model {
public static $_table = MP_STATISTICS_NEWSLETTERS_TABLE;
function __construct() {
parent::__construct();
}
static function createMultiple($data) {
return self::rawExecute(
'INSERT INTO `' . self::$_table . '` ' .
'(newsletter_id, subscriber_id, queue_id) ' .
'VALUES ' . rtrim(
str_repeat('(?,?,?), ', count($data)/3),
', '
),
$data
);
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace MailPoet\Newsletter\Links;
use MailPoet\Util\Security;
class Links {
public $newsletter_id;
public $queue_id;
public $subscriber_id;
function __construct(
$newsletter_id = false,
$subscriber_id = false,
$queue_id = false) {
$this->newsletter_id = $newsletter_id;
$this->queue_id = $queue_id;
$this->subscriber_id = $subscriber_id;
}
function extract($text) {
// adopted from WP's wp_extract_urls() function & modified to work on hrefs
$regex = '#(?:href.*?=.*?)(["\']?)('
. '(?:([\w-]+:)?//?)'
. '[^\s()<>]+'
. '[.]'
. '(?:'
. '\([\w\d]+\)|'
. '(?:'
. '[^`!()\[\]{};:\'".,<>«»“”‘’\s]|'
. '(?:[:]\d+)?/?'
. ')+'
. ')'
. ')\\1#';
preg_match_all($regex, $text, $links);
preg_match_all('/\[\w+:\w+\]/', $text, $shortcodes);
return array_merge(
array_unique($links[2]),
array_unique($shortcodes[0])
);
}
function replace($text, $links = false) {
$links = ($links) ? $links : $this->extract($text);
$processed_links = array();
foreach($links as $link) {
$hash = Security::generateRandomString(5);
$processed_links[] = array(
'hash' => $hash,
'url' => $link
);
$encoded_link = sprintf(
'%s/?mailpoet&endpoint=track&data=%s',
home_url(),
'[mailpoet_data]-'.$hash
);
$link_regex = '/' . preg_quote($link, '/') . '/';
$text = preg_replace($link_regex, $encoded_link, $text);
}
return array($text, $processed_links);
}
}

View File

@ -26,9 +26,12 @@ class Shortcodes {
$shortcode, $shortcode,
$shortcode_details $shortcode_details
); );
$shortcode_class = $shortcode_type = ucfirst($shortcode_details['type']);
__NAMESPACE__ . '\\Categories\\' . ucfirst($shortcode_details['type']);
$shortcode_action = $shortcode_details['action']; $shortcode_action = $shortcode_details['action'];
// do not process subscription management links
if ($shortcode_type === 'Subscription') return $shortcode;
$shortcode_class =
__NAMESPACE__ . '\\Categories\\' . $shortcode_type;
$shortcode_default_value = isset($shortcode_details['default']) $shortcode_default_value = isset($shortcode_details['default'])
? $shortcode_details['default'] : false; ? $shortcode_details['default'] : false;
if(!class_exists($shortcode_class)) return false; if(!class_exists($shortcode_class)) return false;