Send confirmation email + page

This commit is contained in:
Jonathan Labreuille
2016-02-24 10:56:47 +01:00
parent cf6466197a
commit 14fe333678
5 changed files with 225 additions and 30 deletions

View File

@ -208,6 +208,16 @@ const bulk_actions = [
);
}
},
{
name: 'sendConfirmationEmail',
label: 'Resend confirmation email',
onSuccess: function(response) {
MailPoet.Notice.success(
'%$1d confirmation emails have been sent.'
.replace('%$1d', ~~response)
);
}
},
{
name: 'trash',
label: 'Trash',
@ -272,13 +282,13 @@ const SubscriberList = React.createClass({
subscriber.subscriptions.map((subscription) => {
const segment = this.getSegmentFromId(subscription.segment_id);
if(segment === false) return;
if (subscription.status === 'subscribed') {
subscribed_segments.push(segment.name);
} else {
} else if (subscription.status === 'unsubscribed') {
unsubscribed_segments.push(segment.name);
}
});
segments = (
<span>
<span className="mailpoet_segments_subscribed">

View File

@ -1,12 +1,17 @@
<?php
namespace MailPoet\Models;
use MailPoet\Mailer\Mailer;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class Subscriber extends Model {
public static $_table = MP_SUBSCRIBERS_TABLE;
const STATUS_SUBSCRIBED = 'subscribed';
const STATUS_UNSUBSCRIBED = 'unsubscribed';
const STATUS_UNCONFIRMED = 'unconfirmed';
function __construct() {
parent::__construct();
@ -16,13 +21,22 @@ class Subscriber extends Model {
));
}
static function findOne($id = null) {
if(is_int($id) || (string)(int)$id === $id) {
return parent::findOne($id);
} else {
return parent::where('email', $id)->findOne();
}
}
function segments() {
return $this->has_many_through(
__NAMESPACE__.'\Segment',
__NAMESPACE__.'\SubscriberSegment',
'subscriber_id',
'segment_id'
)->where(MP_SUBSCRIBER_SEGMENT_TABLE.'.status', 'subscribed');
)
->where(MP_SUBSCRIBER_SEGMENT_TABLE.'.status', self::STATUS_SUBSCRIBED);
}
function delete() {
@ -56,10 +70,99 @@ class Subscriber extends Model {
}
}
function sendConfirmationEmail() {
$this->set('status', 'unconfirmed');
function getConfirmationUrl() {
$post = get_post(Setting::getValue('signup_confirmation.page'));
// TODO
if($post === null) {
// create page
return '';
} else {
$url = get_permalink($post);
$params = array(
'mailpoet_action=confirm',
'mailpoet_token='.md5(AUTH_KEY.$this->email),
'mailpoet_email='.$this->email
);
// add parameters
$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?').join('&', $params);
$url_params = parse_url($url);
if(empty($url_params['scheme'])) {
$url = get_bloginfo('url').$url;
}
return $url;
}
}
function sendConfirmationEmail() {
if($this->status === self::STATUS_UNCONFIRMED) {
$signup_confirmation = Setting::getValue('signup_confirmation');
$segments = $this->segments()->findMany();
$segment_names = array_map(function($segment) {
return $segment->name;
}, $segments);
$body = nl2br($signup_confirmation['body']);
// replace list of segments shortcode
$body = str_replace(
'[lists_to_confirm]',
'<strong>'.join(', ', $segment_names).'</strong>',
$body
);
// replace activation link
$body = str_replace(
array(
'[activation_link]',
'[/activation_link]'
),
array(
'<a href="'.htmlentities($this->getConfirmationUrl()).'">',
'</a>'
),
$body
);
// build email data
$email = array(
'subject' => $signup_confirmation['subject'],
'body' => array(
'html' => $body,
'text' => $body
)
);
// convert subsdriber to array
$subscriber = $this->asArray();
// set from
$from = (!empty($signup_confirmation['from'])
? $signup_confirmation['from']
: false
);
// set reply to
$reply_to = (!empty($signup_confirmation['reply_to'])
? $signup_confirmation['reply_to']
: false
);
// send email
$mailer = new Mailer(
false,
$from,
$reply_to
);
print '<pre>';
print_r($mailer);
print '</pre>';
exit();
return $mailer->send($email, $subscriber);
}
return false;
}
static function subscribe($subscriber_data = array(), $segment_ids = array()) {
@ -76,11 +179,11 @@ class Subscriber extends Model {
}
if((bool)Setting::getValue('signup_confirmation.enabled')) {
if($subscriber->status !== 'subscribed') {
if($subscriber->status !== self::STATUS_SUBSCRIBED) {
$subscriber->sendConfirmationEmail();
}
} else {
$subscriber->set('status', 'subscribed');
$subscriber->set('status', self::STATUS_SUBSCRIBED);
}
if($subscriber->save()) {
@ -162,19 +265,19 @@ class Subscriber extends Model {
'count' => self::getPublished()->count()
),
array(
'name' => 'subscribed',
'name' => self::STATUS_SUBSCRIBED,
'label' => __('Subscribed'),
'count' => self::filter('subscribed')->count()
'count' => self::filter(self::STATUS_SUBSCRIBED)->count()
),
array(
'name' => 'unconfirmed',
'name' => self::STATUS_UNCONFIRMED,
'label' => __('Unconfirmed'),
'count' => self::filter('unconfirmed')->count()
'count' => self::filter(self::STATUS_UNCONFIRMED)->count()
),
array(
'name' => 'unsubscribed',
'name' => self::STATUS_UNSUBSCRIBED,
'label' => __('Unsubscribed'),
'count' => self::filter('unsubscribed')->count()
'count' => self::filter(self::STATUS_UNSUBSCRIBED)->count()
),
array(
'name' => 'trash',
@ -413,21 +516,23 @@ class Subscriber extends Model {
static function bulkConfirmUnconfirmed($orm) {
$subscribers = $orm->findResultSet();
$subscribers->set('status', 'subscribed')->save();
$subscribers->set('status', self::STATUS_SUBSCRIBED)->save();
return $subscribers->count();
}
static function bulkResendConfirmationEmail($orm) {
static function bulkSendConfirmationEmail($orm) {
$subscribers = $orm
->where('status', 'unconfirmed')
->findResultSet();
->where('status', self::STATUS_UNCONFIRMED)
->findMany();
$emails_sent = 0;
if(!empty($subscribers)) {
foreach($subscribers as $subscriber) {
$subscriber->sendConfirmationEmail();
if($subscriber->sendConfirmationEmail()) {
$emails_sent++;
}
}
return $subscribers->count();
return $emails_sent;
}
return false;
}
@ -468,19 +573,19 @@ class Subscriber extends Model {
static function subscribed($orm) {
return $orm
->whereNull('deleted_at')
->where('status', 'subscribed');
->where('status', self::STATUS_SUBSCRIBED);
}
static function unsubscribed($orm) {
return $orm
->whereNull('deleted_at')
->where('status', 'unsubscribed');
->where('status', self::STATUS_UNSUBSCRIBED);
}
static function unconfirmed($orm) {
return $orm
->whereNull('deleted_at')
->where('status', 'unconfirmed');
->where('status', self::STATUS_UNCONFIRMED);
}
static function withoutSegments($orm) {

View File

@ -1,6 +1,7 @@
<?php
namespace MailPoet\Router;
use \MailPoet\Util\Security;
use \MailPoet\Models\Subscriber;
if(!defined('ABSPATH')) exit;
@ -17,6 +18,7 @@ class Router {
'wp_ajax_mailpoet',
array($this, 'setup')
);
$this->setupPublic();
}
function setup() {
@ -36,6 +38,84 @@ class Router {
}
}
function setupPublic() {
if(isset($_GET['mailpoet_page'])) {
$mailpoet_page = $_GET['mailpoet_page'];
add_filter('wp_title', array($this,'setWindowTitle'));
add_filter('the_title', array($this,'setPageTitle'));
add_filter('the_content', array($this,'setPageContent'));
}
}
function setWindowTitle() {
}
function setPageTitle($title) {
$action = (isset($_GET['mailpoet_action']))
? $_GET['mailpoet_action']
: null;
switch($action) {
case 'confirm':
$token = (isset($_GET['mailpoet_token']))
? $_GET['mailpoet_token']
: null;
$email = (isset($_GET['mailpoet_email']))
? $_GET['mailpoet_email']
: null;
if(empty($token) || empty($token)) {
$title = sprintf(
__("You've subscribed to: %s"),
'demo'
);
} else {
// check token validity
if(md5(AUTH_KEY.$email) !== $token) {
$title = __('Your confirmation link expired, please subscribe again.');
} else {
$subscriber = Subscriber::findOne($email);
if($subscriber !== false) {
if($subscriber->status !== Subscriber::STATUS_SUBSCRIBED) {
$subscriber->status = Subscriber::STATUS_SUBSCRIBED;
$subscriber->save();
}
$segments = $subscriber->segments()->findMany();
$segment_names = array_map(function($segment) {
return $segment->name;
}, $segments);
$title = sprintf(
__("You've subscribed to: %s"),
join(', ', $segment_names)
);
}
}
}
break;
case 'manage':
// TODO
break;
case 'unsubscribe':
// TODO
break;
}
return $title;
}
function setPageContent($content) {
return __(
"Yup, we've added you to our list. ".
"You'll hear from us shortly."
);
}
function setToken() {
$global = '<script type="text/javascript">';
$global .= 'var mailpoet_token = "'.Security::generateToken().'";';

View File

@ -16,10 +16,10 @@ class Pages {
'show_ui' => true,
'show_in_menu' => false,
'rewrite' => false,
'show_in_nav_menus'=>false,
'can_export'=>false,
'publicly_queryable'=>true,
'exclude_from_search'=>true
'show_in_nav_menus' => false,
'can_export' => false,
'publicly_queryable' => true,
'exclude_from_search' => true
));
}

View File

@ -163,7 +163,7 @@
<% for page in pages %>
<option
value="<%= page.id %>"
data-preview-url="<%= page.preview_url|raw %>"
data-preview-url="<%= page.preview_url|raw %>&amp;mailpoet_action=confirm"
data-edit-url="<%= page.edit_url|raw %>"
<% if(page.id == settings.signup_confirmation.page) %>
selected="selected"