fixed shortcodes replacement for "global:" in newsletters

- extracted "get subscription pages urls" from models\Subscriber
- added unit tests for subscription\url class (not working because of WP/Codeception issue)
This commit is contained in:
Jonathan Labreuille
2016-03-15 15:21:21 +01:00
parent fdf9dd0fa3
commit 72882aaf2b
12 changed files with 193 additions and 65 deletions

View File

@ -9,6 +9,7 @@ settings:
bootstrap: _bootstrap.php bootstrap: _bootstrap.php
colors: true colors: true
memory_limit: 1024M memory_limit: 1024M
log: true
extensions: extensions:
enabled: enabled:
- Codeception\Extension\RunFailed - Codeception\Extension\RunFailed

View File

@ -70,8 +70,12 @@ class Populator {
if($page === null) { if($page === null) {
$mailpoet_page_id = Pages::createMailPoetPage(); $mailpoet_page_id = Pages::createMailPoetPage();
Setting::setValue('subscription.page', $mailpoet_page_id); } else {
$mailpoet_page_id = $page->ID;
} }
Setting::setValue('subscription.page', $mailpoet_page_id);
Setting::setValue('signup_confirmation.page', $mailpoet_page_id);
} }
private function createDefaultSettings() { private function createDefaultSettings() {

View File

@ -8,6 +8,9 @@ class Setting extends Model {
public static $defaults = null; public static $defaults = null;
const DEFAULT_SENDING_FREQUENCY_EMAILS = 25;
const DEFAULT_SENDING_FREQUENCY_INTERVAL = 15; // in minutes
function __construct() { function __construct() {
parent::__construct(); parent::__construct();
@ -25,6 +28,14 @@ class Setting extends Model {
public static function loadDefaults() { public static function loadDefaults() {
self::$defaults = array( self::$defaults = array(
'mta_group' => 'website',
'mta' => array(
'method' => 'PHPMail',
'frequency' => array(
'emails' => self::DEFAULT_SENDING_FREQUENCY_EMAILS,
'interval' => self::DEFAULT_SENDING_FREQUENCY_INTERVAL
)
),
'signup_confirmation' => array( 'signup_confirmation' => array(
'enabled' => true, 'enabled' => true,
'subject' => sprintf(__('Confirm your subscription to %1$s'), get_option('blogname')), 'subject' => sprintf(__('Confirm your subscription to %1$s'), get_option('blogname')),

View File

@ -2,6 +2,7 @@
namespace MailPoet\Models; namespace MailPoet\Models;
use MailPoet\Mailer\Mailer; use MailPoet\Mailer\Mailer;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
use MailPoet\Subscription;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@ -70,42 +71,6 @@ class Subscriber extends Model {
} }
} }
function getConfirmationUrl() {
$post = get_post(Setting::getValue('signup_confirmation.page'));
return $this->getSubscriptionUrl($post, 'confirm');
}
function getEditSubscriptionUrl() {
$post = get_post(Setting::getValue('subscription.page'));
return $this->getSubscriptionUrl($post, 'edit');
}
function getUnsubscribeUrl() {
$post = get_post(Setting::getValue('subscription.page'));
return $this->getSubscriptionUrl($post, 'unsubscribe');
}
private function getSubscriptionUrl($post = null, $action = null) {
if($post === null || $action === null) return;
$url = get_permalink($post);
$params = array(
'mailpoet_action='.$action,
'mailpoet_token='.self::generateToken($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() { function sendConfirmationEmail() {
if($this->status === self::STATUS_UNCONFIRMED) { if($this->status === self::STATUS_UNCONFIRMED) {
$signup_confirmation = Setting::getValue('signup_confirmation'); $signup_confirmation = Setting::getValue('signup_confirmation');
@ -131,7 +96,7 @@ class Subscriber extends Model {
'[/activation_link]' '[/activation_link]'
), ),
array( array(
'<a href="'.htmlentities($this->getConfirmationUrl()).'">', '<a href="'.esc_attr(Subscription\Url::getConfirmationUrl($this)).'">',
'</a>' '</a>'
), ),
$body $body

View File

@ -43,9 +43,12 @@ class Renderer {
} }
function renderBody($content) { function renderBody($content) {
$content = array_map(function ($content_block) { $content = array_map(function($content_block) {
$column_count = count($content_block['blocks']); $column_count = count($content_block['blocks']);
$column_data = $this->blocks_renderer->render($content_block, $column_count); $column_data = $this->blocks_renderer->render(
$content_block,
$column_count
);
return $this->columns_renderer->render( return $this->columns_renderer->render(
$content_block['styles'], $content_block['styles'],
$column_count, $column_count,

View File

@ -1,5 +1,6 @@
<?php <?php
namespace MailPoet\Newsletter\Shortcodes\Categories; namespace MailPoet\Newsletter\Shortcodes\Categories;
use MailPoet\Subscription;
require_once(ABSPATH . 'wp-includes/pluggable.php'); require_once(ABSPATH . 'wp-includes/pluggable.php');
@ -18,12 +19,27 @@ class Link {
shortcode: 'global:browser', shortcode: 'global:browser',
} }
*/ */
static function process($action) { static function process(
// TODO: implement $action,
$default_value,
$newsletter = false,
$subscriber = false
) {
$actions = array( $actions = array(
'unsubscribe' => '', 'unsubscribe' =>
'manage' => '', '<a
'browser' => '' target="_blank"
href="'.esc_attr(Subscription\Url::getUnsubscribeUrl($subscriber)).'">'.
__('Unsubscribe').
'</a>',
'manage' =>
'<a
target="_blank"
href="'.esc_attr(Subscription\Url::getManageUrl($subscriber)).'">'.
__('Manage subscription').
'</a>',
'browser' => 'TODO'
); );
return (isset($actions[$action])) ? $actions[$action] : false; return (isset($actions[$action])) ? $actions[$action] : false;
} }

View File

@ -43,10 +43,10 @@ class User {
if($subscriber && $subscriber['wp_user_id']) { if($subscriber && $subscriber['wp_user_id']) {
$wp_user = get_userdata($subscriber['wp_user_id']); $wp_user = get_userdata($subscriber['wp_user_id']);
return $wp_user->user_login; return $wp_user->user_login;
}; }
return $default_value; return $default_value;
case 'count': case 'count':
return Subscriber::count(); return Subscriber::filter('subscribed')->count();
default: default:
return false; return false;
} }

View File

@ -23,13 +23,20 @@ class Shortcodes {
function process($shortcodes) { function process($shortcodes) {
$processed_shortcodes = array_map( $processed_shortcodes = array_map(
function ($shortcode) { function ($shortcode) {
// TODO: discuss renaming "global". It is a reserved name in PHP.
if($shortcode === 'global') $shortcode = 'link';
preg_match( preg_match(
'/\[(?P<type>\w+):(?P<action>\w+)(?:.*?default:(?P<default>.*?))?\]/', '/\[(?P<type>\w+):(?P<action>\w+)(?:.*?default:(?P<default>.*?))?\]/',
$shortcode, $shortcode,
$shortcode_details $shortcode_details
); );
// TODO: discuss renaming "global". It is a reserved name in PHP.
if(
isset($shortcode_details['type'])
&& $shortcode_details['type'] === 'global'
) {
$shortcode_details['type'] = 'link';
}
$shortcode_class = $shortcode_class =
__NAMESPACE__ . '\\Categories\\' . ucfirst($shortcode_details['type']); __NAMESPACE__ . '\\Categories\\' . ucfirst($shortcode_details['type']);
if(!class_exists($shortcode_class)) return false; if(!class_exists($shortcode_class)) return false;
@ -41,7 +48,7 @@ class Shortcodes {
$this->subscriber $this->subscriber
); );
}, $shortcodes); }, $shortcodes);
return array_filter($processed_shortcodes); return $processed_shortcodes;
} }
function replace() { function replace() {

View File

@ -8,6 +8,7 @@ use \MailPoet\Models\Setting;
use \MailPoet\Models\Segment; use \MailPoet\Models\Segment;
use \MailPoet\Util\Helpers; use \MailPoet\Util\Helpers;
use \MailPoet\Util\Url; use \MailPoet\Util\Url;
use \MailPoet\Subscription;
class Pages { class Pages {
const DEMO_EMAIL = 'demo@mailpoet.com'; const DEMO_EMAIL = 'demo@mailpoet.com';
@ -67,8 +68,8 @@ class Pages {
return $this->getConfirmTitle($subscriber); return $this->getConfirmTitle($subscriber);
break; break;
case 'edit': case 'manage':
return $this->getEditTitle($subscriber); return $this->getManageTitle($subscriber);
break; break;
case 'unsubscribe': case 'unsubscribe':
@ -92,8 +93,8 @@ class Pages {
case 'confirm': case 'confirm':
$content = $this->getConfirmContent($subscriber); $content = $this->getConfirmContent($subscriber);
break; break;
case 'edit': case 'manage':
$content = $this->getEditContent($subscriber); $content = $this->getManageContent($subscriber);
break; break;
case 'unsubscribe': case 'unsubscribe':
$content = $this->getUnsubscribeContent($subscriber); $content = $this->getUnsubscribeContent($subscriber);
@ -132,7 +133,7 @@ class Pages {
return $title; return $title;
} }
private function getEditTitle($subscriber) { private function getManageTitle($subscriber) {
if($this->isPreview()) { if($this->isPreview()) {
return sprintf( return sprintf(
__('Edit your subscriber profile: %s'), __('Edit your subscriber profile: %s'),
@ -159,7 +160,7 @@ class Pages {
} }
} }
private function getEditContent($subscriber) { private function getManageContent($subscriber) {
if($this->isPreview()) { if($this->isPreview()) {
$subscriber = Subscriber::create(); $subscriber = Subscriber::create();
$subscriber->hydrate(array( $subscriber->hydrate(array(
@ -310,7 +311,7 @@ class Pages {
$content .= '<p><strong>'. $content .= '<p><strong>'.
str_replace( str_replace(
array('[link]', '[/link]'), array('[link]', '[/link]'),
array('<a href="'.$subscriber->getConfirmationUrl().'">', '</a>'), array('<a href="'.Subscription\Url::getConfirmationUrl($subscriber).'">', '</a>'),
__('You made a mistake? [link]Undo unsubscribe.[/link]') __('You made a mistake? [link]Undo unsubscribe.[/link]')
). ).
'</strong></p>'; '</strong></p>';

52
lib/Subscription/Url.php Normal file
View File

@ -0,0 +1,52 @@
<?php
namespace MailPoet\Subscription;
use \MailPoet\Models\Subscriber;
use \MailPoet\Models\Setting;
class Url {
static function getConfirmationUrl($subscriber = false) {
$post = get_post(Setting::getValue('signup_confirmation.page'));
return self::getSubscriptionUrl($post, 'confirm', $subscriber);
}
static function getManageUrl($subscriber = false) {
$post = get_post(Setting::getValue('subscription.page'));
return self::getSubscriptionUrl($post, 'manage', $subscriber);
}
static function getUnsubscribeUrl($subscriber = false) {
$post = get_post(Setting::getValue('subscription.page'));
return self::getSubscriptionUrl($post, 'unsubscribe', $subscriber);
}
private static function getSubscriptionUrl(
$post = null, $action = null, $subscriber = false
) {
if($post === null || $action === null) return;
$url = get_permalink($post);
if($subscriber !== false) {
$params = array(
'mailpoet_action='.$action,
'mailpoet_token='.Subscriber::generateToken($subscriber->email),
'mailpoet_email='.$subscriber->email
);
} else {
$params = array(
'mailpoet_action='.$action,
'preview'
);
}
// 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;
}
}

View File

@ -1,13 +1,13 @@
<?php <?php
/*
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
class ShortcodesCest { class ShortcodesCest {
/* public $rendered_newsletter; public $rendered_newsletter;
public $newsletter; public $newsletter;
public $subscriber; public $subscriber;
function __construct() { function _before() {
$this->wp_user = $this->_createWPUser(); $this->wp_user = $this->_createWPUser();
$this->subscriber = $this->_createSubscriber(); $this->subscriber = $this->_createSubscriber();
$this->newsletter['subject'] = 'some subject'; $this->newsletter['subject'] = 'some subject';
@ -30,7 +30,7 @@ class ShortcodesCest {
Month text: [date:mtext]. Month text: [date:mtext].
Year: [date:y] Year: [date:y]
You can usubscribe here: [global:unsubscribe]. You can unsubscribe here: [global:unsubscribe].
Manage your subscription here: [global:manage]. Manage your subscription here: [global:manage].
View this newsletter in browser: [global:browser].'; View this newsletter in browser: [global:browser].';
$this->shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes( $this->shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes(
@ -71,7 +71,7 @@ class ShortcodesCest {
Month text: {$date->format('F')}. Month text: {$date->format('F')}.
Year: {$date->format('Y')} Year: {$date->format('Y')}
You can usubscribe here: [global:unsubscribe]. You can unsubscribe here: [global:unsubscribe].
Manage your subscription here: [global:manage]. Manage your subscription here: [global:manage].
View this newsletter in browser: [global:browser]."); View this newsletter in browser: [global:browser].");
} }
@ -92,6 +92,7 @@ class ShortcodesCest {
'first_name' => 'Donald', 'first_name' => 'Donald',
'last_name' => 'Trump', 'last_name' => 'Trump',
'email' => 'mister@trump.com', 'email' => 'mister@trump.com',
'status' => Subscriber::STATUS_SUBSCRIBED,
'wp_user_id' => $this->wp_user 'wp_user_id' => $this->wp_user
) )
); );
@ -100,6 +101,6 @@ class ShortcodesCest {
} }
function _after() { function _after() {
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); Subscriber::deleteMany();
}*/ }
} }*/

View File

@ -0,0 +1,67 @@
<?php
/*
use \MailPoet\Subscription\Url;
use \MailPoet\Models\Subscriber;
use \MailPoet\Models\Setting;
use \MailPoet\Config\Populator;
class UrlCest {
function _before() {
$populator = new Populator();
$populator->up();
}
function itReturnsTheConfirmationUrl() {
// preview
$url = Url::getConfirmationUrl(false);
expect($url)->contains('mailpoet_action=confirm');
expect($url)->contains('preview');
// actual subscriber
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'john@mailpoet.com'
));
$url = Url::getConfirmationUrl($subscriber);
expect($url)->contains('mailpoet_action=confirm');
expect($url)->contains('mailpoet_token=');
expect($url)->contains('mailpoet_email=');
}
function itReturnsTheManageSubscriptionUrl() {
// preview
$url = Url::getManageUrl(false);
expect($url)->contains('mailpoet_action=manage');
expect($url)->contains('preview');
// actual subscriber
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'john@mailpoet.com'
));
$url = Url::getManageUrl($subscriber);
expect($url)->contains('mailpoet_action=manage');
expect($url)->contains('mailpoet_token=');
expect($url)->contains('mailpoet_email=');
}
function itReturnsTheUnsubscribeUrl() {
// preview
$url = Url::getUnsubscribeUrl(false);
expect($url)->contains('mailpoet_action=unsubscribe');
expect($url)->contains('preview');
// actual subscriber
$subscriber = Subscriber::createOrUpdate(array(
'email' => 'john@mailpoet.com'
));
$url = Url::getUnsubscribeUrl($subscriber);
expect($url)->contains('mailpoet_action=unsubscribe');
expect($url)->contains('mailpoet_token=');
expect($url)->contains('mailpoet_email=');
}
function _after() {
Setting::deleteMany();
Subscriber::deleteMany();
}
}
*/