diff --git a/lib/Newsletter/Shortcodes/Categories/Link.php b/lib/Newsletter/Shortcodes/Categories/Link.php
index 21bde82433..3c920c7613 100644
--- a/lib/Newsletter/Shortcodes/Categories/Link.php
+++ b/lib/Newsletter/Shortcodes/Categories/Link.php
@@ -1,55 +1,55 @@
',-
- shortcode: 'subscription:unsubscribe',
- },
- {
- text: '<%= __('Manage subscription') %>',
- shortcode: 'subscription:manage',
- },
- {
- text: '<%= __('View in browser link') %>',
- shortcode: 'newsletter:view_in_browser',
- }
- */
- static function process($action,
- $default_value = false,
- $newsletter,
- $subscriber,
- $queue = false
- ) {
- switch($action) {
- case 'subscription_unsubscribe':
- $action = 'subscription_unsubscribe_url';
- $url = self::processUrl(
- $action,
- esc_attr(SubscriptionUrl::getUnsubscribeUrl($subscriber))
- );
- return sprintf(
- '%s',
- $url,
- __('Unsubscribe')
- );
- break;
+class Link {
+ /*
+ {
+ text: '<%= __('Unsubscribe') %>',-
+ shortcode: 'subscription:unsubscribe',
+ },
+ {
+ text: '<%= __('Manage subscription') %>',
+ shortcode: 'subscription:manage',
+ },
+ {
+ text: '<%= __('View in browser link') %>',
+ shortcode: 'newsletter:view_in_browser',
+ }
+ */
+ static function process($action,
+ $default_value = false,
+ $newsletter,
+ $subscriber,
+ $queue = false
+ ) {
+ switch($action) {
+ case 'subscription_unsubscribe':
+ $action = 'subscription_unsubscribe_url';
+ $url = self::processUrl(
+ $action,
+ esc_attr(SubscriptionUrl::getUnsubscribeUrl($subscriber))
+ );
+ return sprintf(
+ '%s',
+ $url,
+ __('Unsubscribe')
+ );
+ break;
- case 'subscription_unsubscribe_url':
- return self::processUrl(
- $action,
- SubscriptionUrl::getUnsubscribeUrl($subscriber)
- );
- break;
+ case 'subscription_unsubscribe_url':
+ return self::processUrl(
+ $action,
+ SubscriptionUrl::getUnsubscribeUrl($subscriber)
+ );
+ break;
- case 'subscription_manage':
- $url = self::processUrl(
+ case 'subscription_manage':
+ $url = self::processUrl(
$action = 'subscription_manage_url',
esc_attr(SubscriptionUrl::getManageUrl($subscriber))
);
@@ -81,20 +81,21 @@ namespace MailPoet\Newsletter\Shortcodes\Categories;
case 'newsletter_view_in_browser_url':
$url = self::getViewInBrowserUrl($newsletter, $subscriber, $queue);
return self::processUrl($action, $url);
- break;
+ break;
default:
+ $shortcode = self::getShortcode($action);
$url = apply_filters(
- 'mailpoet_shortcode_link',
- $action,
+ 'mailpoet_newsletter_shortcode_link',
+ $shortcode,
$newsletter,
$subscriber,
$queue
);
- return ($url !== $action) ?
+ return ($url !== $shortcode) ?
self::processUrl($action, $url) :
false;
- break;
+ break;
}
}
@@ -130,7 +131,7 @@ namespace MailPoet\Newsletter\Shortcodes\Categories;
}
}
return ((boolean) Setting::getValue('tracking.enabled')) ?
- '[link:' . $action . ']' :
+ self::getShortcode($action) :
$url;
}
@@ -153,9 +154,10 @@ namespace MailPoet\Newsletter\Shortcodes\Categories;
$url = Link::getViewInBrowserUrl($newsletter, $subscriber, $queue);
break;
default:
+ $shortcode = self::getShortcode($shortcode_action);
$url = apply_filters(
- 'mailpoet_shortcode_link',
- $shortcode_action,
+ 'mailpoet_newsletter_shortcode_link',
+ $shortcode,
$newsletter,
$subscriber,
$queue
@@ -165,4 +167,8 @@ namespace MailPoet\Newsletter\Shortcodes\Categories;
}
return $url;
}
+
+ private static function getShortcode($action) {
+ return sprintf('[link:%s]', $action);
+ }
}
\ No newline at end of file
diff --git a/lib/Newsletter/Shortcodes/Categories/Newsletter.php b/lib/Newsletter/Shortcodes/Categories/Newsletter.php
index c3ff7d9863..cda51c0c51 100644
--- a/lib/Newsletter/Shortcodes/Categories/Newsletter.php
+++ b/lib/Newsletter/Shortcodes/Categories/Newsletter.php
@@ -34,7 +34,7 @@ class Newsletter {
$newsletter,
$subscriber,
$queue = false,
- $text
+ $content
) {
switch($action) {
case 'subject':
@@ -42,11 +42,11 @@ class Newsletter {
break;
case 'total':
- return substr_count($text, 'data-post-id');
+ return substr_count($content, 'data-post-id');
break;
case 'post_title':
- preg_match_all('/data-post-id="(\w+)"/ism', $text, $posts);
+ preg_match_all('/data-post-id="(\d+)"/ism', $content, $posts);
$post_ids = array_unique($posts[1]);
$latest_post = self::getLatestWPPost($post_ids);
return ($latest_post) ? $latest_post['post_title'] : false;
diff --git a/lib/Newsletter/Shortcodes/Shortcodes.php b/lib/Newsletter/Shortcodes/Shortcodes.php
index 243a738811..c08826e794 100644
--- a/lib/Newsletter/Shortcodes/Shortcodes.php
+++ b/lib/Newsletter/Shortcodes/Shortcodes.php
@@ -34,24 +34,36 @@ class Shortcodes {
function match($shortcode) {
preg_match(
- '/\[(?P\w+):(?P\w+)(?:.*?default:(?P.*?))?\]/',
+ '/\[(?P\w+):(?P\w+)(?:.*?\|.*?default:(?P\w+))?\]/ism',
$shortcode,
$match
);
return $match;
}
- function process($shortcodes, $content) {
+ function process($shortcodes, $content = false) {
$processed_shortcodes = array_map(
function($shortcode) use($content) {
$shortcode_details = $this->match($shortcode);
- $shortcode_type = ucfirst($shortcode_details['type']);
+ $shortcode_category = ucfirst($shortcode_details['category']);
$shortcode_action = $shortcode_details['action'];
$shortcode_class =
- __NAMESPACE__ . '\\Categories\\' . $shortcode_type;
+ __NAMESPACE__ . '\\Categories\\' . $shortcode_category;
$shortcode_default_value = isset($shortcode_details['default'])
? $shortcode_details['default'] : false;
- if(!class_exists($shortcode_class)) return false;
+ if(!class_exists($shortcode_class)) {
+ $custom_shortcode = apply_filters(
+ 'mailpoet_newsletter_shortcode',
+ $shortcode,
+ $this->newsletter,
+ $this->subscriber,
+ $this->queue,
+ $content
+ );
+ return ($custom_shortcode === $shortcode) ?
+ false :
+ $custom_shortcode;
+ }
return $shortcode_class::process(
$shortcode_action,
$shortcode_default_value,
diff --git a/tests/unit/Newsletter/ShortcodesTest.php b/tests/unit/Newsletter/ShortcodesTest.php
index 14d1ccf994..1dfed165fb 100644
--- a/tests/unit/Newsletter/ShortcodesTest.php
+++ b/tests/unit/Newsletter/ShortcodesTest.php
@@ -1,11 +1,13 @@
up();
- $this->wp_user = $this->_createWPUser();
+ $this->WP_user = $this->_createWPUser();
+ $this->WP_post = $this->_createWPPost();
$this->subscriber = $this->_createSubscriber();
$this->newsletter = array(
'subject' => 'some subject',
'type' => 'notification',
'id' => 2
);
- $this->post_data = array(
- 'post_title' => 'Sample Post',
- 'post_content' => 'contents',
- 'post_status' => 'publish',
- );
- $this->post_id = wp_insert_post($this->post_data);
- $this->rendered_newsletter = "
- Hello [user:displayname | default:member].
- Your first name is [user:firstname | default:First Name].
- Your last name is [user:lastname | default:Last Name].
- Thank you for subscribing with [user:email].
- We already have [user:count] users.
-
- some post
- post_id}\">another post
-
- There are [newsletter:total] posts in this newsletter.
- You are reading [newsletter:subject].
- The latest post in this newsletter is called [newsletter:post_title].
- The issue number of this newsletter is [newsletter:number].
-
- Date: [date:d].
- Ordinal date: [date:dordinal].
- Date text: [date:dtext].
- Month: [date:m].
- Month text: [date:mtext].
- Year: [date:y]
-
- You can unsubscribe here: [link:subscription_unsubscribe_url].
- Manage your subscription here: [link:subscription_manage_url].
- View this newsletter in browser: [link:newsletter_view_in_browser_url].";
$this->shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes(
$this->newsletter,
$this->subscriber
);
+ Setting::setValue('tracking.enabled', false);
}
function testItCanExtractShortcodes() {
- $shortcodes = $this->shortcodes_object->extract($this->rendered_newsletter);
- expect(count($shortcodes))->equals(18);
+ $content = '[category:action] [notshortcode]';
+ $shortcodes = $this->shortcodes_object->extract($content);
+ expect(count($shortcodes))->equals(1);
}
- function testItCanProcessShortcodes() {
- $wp_user = get_userdata($this->wp_user);
+ function testItCanExtractOnlySelectShortcodes() {
+ $content = '[link:action] [newsletter:action]';
+ $limit = array('link');
+ $shortcodes = $this->shortcodes_object->extract($content, $limit);
+ expect(count($shortcodes))->equals(1);
+ expect(preg_match('/link/', $shortcodes[0]))->equals(1);
+ }
- $queue = SendingQueue::create();
- $queue->newsletter_id = $this->newsletter['id'];
- $queue->save();
- $issue_number = 1;
+ function testItCanMatchShortcodeDetails() {
+ $content = '[category:action]';
+ $details = $this->shortcodes_object->match($content);
+ expect($details['category'])->equals('category');
+ expect($details['action'])->equals('action');
+ $content = '[category:action|default:default_value]';
+ $details = $this->shortcodes_object->match($content);
+ expect($details['category'])->equals('category');
+ expect($details['action'])->equals('action');
+ expect($details['default'])->equals('default_value');
+ $content = '[category:action|default]';
+ $details = $this->shortcodes_object->match($content);
+ expect($details)->isEmpty();
+ $content = '[category|default:default_value]';
+ $details = $this->shortcodes_object->match($content);
+ expect($details)->isEmpty();
+ }
- $number_of_posts = 2;
+ function testItCanProcessCustomShortcodes() {
+ $shortcode = array('[some:shortcode]');
+ $result = $this->shortcodes_object->process($shortcode);
+ expect($result[0])->false();
+ add_filter('mailpoet_newsletter_shortcode', function (
+ $shortcode, $newsletter, $subscriber, $queue, $content) {
+ if($shortcode === '[some:shortcode]') return 'success';
+ }, 10, 5);
+ $result = $this->shortcodes_object->process($shortcode);
+ expect($result[0])->equals('success');
+ }
+ function testItCanProcessDateShortcodes() {
$date = new \DateTime('now');
- $subscriber_count = Subscriber::count();
- $newsletter_with_replaced_shortcodes = $this->shortcodes_object->replace(
- $this->rendered_newsletter
+ expect(Date::process('d'))->equals($date->format('d'));
+ expect(Date::process('dordinal'))->equals($date->format('dS'));
+ expect(Date::process('dtext'))->equals($date->format('D'));
+ expect(Date::process('m'))->equals($date->format('m'));
+ expect(Date::process('mtext'))->equals($date->format('F'));
+ expect(Date::process('y'))->equals($date->format('Y'));
+ }
+
+ function testItCanProcessNewsletterShortcodes() {
+ $content =
+ 'latest post' .
+ 'another post' .
+ 'not post';
+ $result =
+ $this->shortcodes_object->process(array('[newsletter:subject]'));
+ expect($result[0])->equals($this->newsletter['subject']);
+ $result =
+ $this->shortcodes_object->process(array('[newsletter:total]'), $content);
+ expect($result[0])->equals(2);
+ $result =
+ $this->shortcodes_object->process(array('[newsletter:post_title]'));
+ $wp_post = get_post($this->WP_post);
+ expect($result['0'])->equals($wp_post->post_title);
+ $result =
+ $this->shortcodes_object->process(array('[newsletter:number]'));
+ expect($result['0'])->equals(1);
+ $queue = $this->_createQueue();
+ $result =
+ $this->shortcodes_object->process(array('[newsletter:number]'));
+ expect($result['0'])->equals(2);
+ }
+
+ function testItCanProcessUserShortcodes() {
+ $result =
+ $this->shortcodes_object->process(array('[user:firstname]'));
+ expect($result[0])->equals($this->subscriber->first_name);
+ $result =
+ $this->shortcodes_object->process(array('[user:lastname]'));
+ expect($result[0])->equals($this->subscriber->last_name);
+ $result =
+ $this->shortcodes_object->process(array('[user:displayname]'));
+ expect($result[0])->equals($this->WP_user->user_login);
+ $subscribers = Subscriber::where('status', 'subscribed')
+ ->findMany();
+ $subscriber_count = count($subscribers);
+ $result =
+ $this->shortcodes_object->process(array('[user:count]'));
+ expect($result[0])->equals($subscriber_count);
+ $this->subscriber->status = 'unsubscribed';
+ $this->subscriber->save();
+ $result =
+ $this->shortcodes_object->process(array('[user:count]'));
+ expect($result[0])->equals(--$subscriber_count);
+ }
+
+ function testItCanProcessLinkShortcodes() {
+ $result =
+ $this->shortcodes_object->process(array('[link:subscription_unsubscribe]'));
+ expect(preg_match('/^$/', $result['0']))->equals(1);
+ expect(preg_match('/action=unsubscribe/', $result['0']))->equals(1);
+ $result =
+ $this->shortcodes_object->process(array('[link:subscription_unsubscribe_url]'));
+ expect(preg_match('/^http.*?action=unsubscribe/', $result['0']))->equals(1);
+ $result =
+ $this->shortcodes_object->process(array('[link:subscription_manage]'));
+ expect(preg_match('/^$/', $result['0']))->equals(1);
+ expect(preg_match('/action=manage/', $result['0']))->equals(1);
+ $result =
+ $this->shortcodes_object->process(array('[link:subscription_manage_url]'));
+ expect(preg_match('/^http.*?action=manage/', $result['0']))->equals(1);
+ $result =
+ $this->shortcodes_object->process(array('[link:newsletter_view_in_browser]'));
+ expect(preg_match('/^$/', $result['0']))->equals(1);
+ expect(preg_match('/endpoint=view_in_browser/', $result['0']))->equals(1);
+ $result =
+ $this->shortcodes_object->process(array('[link:newsletter_view_in_browser_url]'));
+ expect(preg_match('/^http.*?endpoint=view_in_browser/', $result['0']))->equals(1);
+ }
+
+ function testItReturnsShortcodeWhenTrackingEnabled() {
+ $shortcode = '[link:subscription_unsubscribe_url]';
+ $result =
+ $this->shortcodes_object->process(array($shortcode));
+ expect(preg_match('/^http.*?action=unsubscribe/', $result['0']))->equals(1);
+ Setting::setValue('tracking.enabled', true);
+ $shortcodes = array(
+ '[link:subscription_unsubscribe]',
+ '[link:subscription_unsubscribe_url]',
+ '[link:subscription_manage]',
+ '[link:subscription_manage_url]',
+ '[link:newsletter_view_in_browser]',
+ '[link:newsletter_view_in_browser_url]'
);
+ $result =
+ $this->shortcodes_object->process($shortcodes);
+ // all returned shortcodes must end with url
+ $result = join(',', $result);
+ expect(substr_count($result, '_url'))->equals(count($shortcodes));
+ }
- $unsubscribe_url = SubscriptionUrl::getUnsubscribeUrl($this->subscriber);
- $manage_url = SubscriptionUrl::getManageUrl($this->subscriber);
+ function testItCanProcessCustomLinkShortcodes() {
+ $shortcode = '[link:shortcode]';
+ $result = $this->shortcodes_object->process(array($shortcode));
+ expect($result[0])->false();
+ add_filter('mailpoet_newsletter_shortcode_link', function (
+ $shortcode, $newsletter, $subscriber, $queue) {
+ if($shortcode === '[link:shortcode]') return 'success';
+ }, 10, 4);
+ $result = $this->shortcodes_object->process(array($shortcode));
+ expect($result[0])->equals('success');
+ Setting::setValue('tracking.enabled', true);
+ $result = $this->shortcodes_object->process(array($shortcode));
+ expect($result[0])->equals($shortcode);
+ }
+ function _createWPPost() {
$data = array(
- 'newsletter' => $this->newsletter['id'],
- 'subscriber' => $this->subscriber->id,
- 'subscriber_token' => Subscriber::generateToken($this->subscriber->email),
- 'queue' => false
- );
- $data = rtrim(base64_encode(serialize($data)), '=');
- $view_in_browser_url =
- home_url() . '/?mailpoet&endpoint=view_in_browser&data=' . $data;
-
- expect($newsletter_with_replaced_shortcodes)->equals("
- Hello {$wp_user->user_login}.
- Your first name is {$this->subscriber->first_name}.
- Your last name is {$this->subscriber->last_name}.
- Thank you for subscribing with {$this->subscriber->email}.
- We already have {$subscriber_count} users.
-
- some post
- post_id}\">another post
-
- There are {$number_of_posts} posts in this newsletter.
- You are reading {$this->newsletter['subject']}.
- The latest post in this newsletter is called {$this->post_data['post_title']}.
- The issue number of this newsletter is {$issue_number}.
-
- Date: {$date->format('d')}.
- Ordinal date: {$date->format('dS')}.
- Date text: {$date->format('D')}.
- Month: {$date->format('m')}.
- Month text: {$date->format('F')}.
- Year: {$date->format('Y')}
-
- You can unsubscribe here: {$unsubscribe_url}.
- Manage your subscription here: {$manage_url}.
- View this newsletter in browser: {$view_in_browser_url}.");
-}
+ 'post_title' => 'Sample Post',
+ 'post_content' => 'contents',
+ 'post_status' => 'publish',
+ );
+ return wp_insert_post($data);
+ }
function _createWPUser() {
- $wp_user = wp_create_user('phoenix_test_user', 'pass', 'phoenix@test.com');
- if(is_wp_error($wp_user)) {
- $wp_user = get_user_by('login', 'phoenix_test_user');
- $wp_user = $wp_user->ID;
- }
- return $wp_user;
+ $WP_user = wp_create_user('phoenix_test_user', 'pass', 'phoenix@test.com');
+ $WP_user = get_user_by('login', 'phoenix_test_user');
+ return $WP_user;
}
function _createSubscriber() {
@@ -137,15 +216,25 @@ class ShortcodesTest extends MailPoetTest {
'last_name' => 'Trump',
'email' => 'mister@trump.com',
'status' => Subscriber::STATUS_SUBSCRIBED,
- 'wp_user_id' => $this->wp_user
+ 'WP_user_id' => $this->WP_user->ID
)
);
$subscriber->save();
return Subscriber::findOne($subscriber->id);
}
+ function _createQueue() {
+ $queue = SendingQueue::create();
+ $queue->newsletter_id = $this->newsletter['id'];
+ $queue->status = 'completed';
+ $queue->save();
+ return $queue;
+ }
+
function _after() {
- Subscriber::deleteMany();
- wp_delete_post($this->post_id, true);
+ ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
+ ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
+ wp_delete_post($this->WP_post, true);
+ wp_delete_user($this->WP_user->ID);
}
}
\ No newline at end of file