Compare commits

...

23 Commits

Author SHA1 Message Date
856c636089 Releasing 3.0.0-rc.2.0.1 2017-08-30 16:06:39 +00:00
8f9e8ea185 Merge pull request #1075 from mailpoet/forms-bug
Fix form issue when using list selection field [MAILPOET-1077]
2017-08-30 18:10:33 +03:00
b0b88693f1 Merge pull request #1071 from mailpoet/initializer_cleanup
Fixes activation on MS environments and cleans up Initializer [MAILPOET-1076]
2017-08-30 17:56:16 +03:00
9916eb9da8 updated tests 2017-08-30 14:52:17 +00:00
79b5426e01 Fix a constant name [MAILPOET-1076] 2017-08-30 17:47:53 +03:00
5807fd2e02 Merge pull request #1067 from mailpoet/emoji
Add emoji support to newsletter body [MAILPOET-1009]
2017-08-30 10:04:26 -04:00
0ee39143f4 Runs hooks setup only when plugin is initilized 2017-08-30 09:50:49 -04:00
10c39bd650 Removes unused constructor 2017-08-30 09:47:34 -04:00
20593cc5a5 Fix form issue when using list selection field 2017-08-30 13:29:41 +00:00
cb4b599d97 Merge pull request #1073 from mailpoet/fix-notice
Fix php notice
2017-08-30 16:25:50 +03:00
53f7953566 Fix browser preview bypassing emoji encoding [MAILPOET-1009] 2017-08-30 14:39:38 +03:00
61ae2da1e3 Fix a constant not defined in PHP 5.3 [MAILPOET-1009] 2017-08-30 14:02:29 +03:00
36abd8e5e6 Don't show network activation notice for other plugins
[MAILPOET-1072]
2017-08-30 11:39:42 +02:00
7e9de1fd07 Fix php notice 2017-08-30 11:25:42 +02:00
7ac5e65963 Fix php notice 2017-08-30 10:30:16 +02:00
cf992852b5 Validate for unsubscribe link only for MSS sending method [MAILPOET-1050] 2017-08-30 10:16:24 +02:00
59482b2bfa Uses init hook to initilize AccessControl 2017-08-29 23:30:35 -04:00
053f9e0cdf Adds higher priority to init hook so that it fires before the widgets hook 2017-08-29 23:20:46 -04:00
e1cc25239b Maintains code consistency when setting up JSON API
Updates exception handler return statement
2017-08-29 20:33:50 -04:00
2f4452ad36 Removes redundant exception handler 2017-08-29 20:28:20 -04:00
f453d685d6 Fixes translation not being picked up by makepot 2017-08-29 20:24:04 -04:00
2d2b4ca7f0 Moves setup actions from plugins_loaded hook to init hook
Rearranges class methods to follow the order by which they are called
2017-08-29 20:22:19 -04:00
b9bdc86fd9 Add emoji support to newsletter body [MAILPOET-1009] 2017-08-28 19:07:17 +03:00
18 changed files with 309 additions and 122 deletions

View File

@ -74,6 +74,8 @@ class Subscribers extends APIEndpoint {
));
}
$data = $this->deobfuscateFormPayload($data);
$segment_ids = (!empty($data['segments'])
? (array)$data['segments']
: array()
@ -81,7 +83,6 @@ class Subscribers extends APIEndpoint {
$segment_ids = $form->filterSegments($segment_ids);
unset($data['segments']);
$data = $this->deobfuscateFormPayload($data);
if(empty($segment_ids)) {
return $this->badRequest(array(

View File

@ -1,11 +1,10 @@
<?php
namespace MailPoet\Config;
use MailPoet\Models\Setting;
class Hooks {
function __construct() {
}
function init() {
$this->setupWPUsers();
$this->setupImageSize();

View File

@ -1,4 +1,5 @@
<?php
namespace MailPoet\Config;
use MailPoet\API;
@ -13,18 +14,16 @@ if(!defined('ABSPATH')) exit;
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
class Initializer {
const UNABLE_TO_CONNECT = 'Unable to connect to the database (the database is unable to open a file or folder), the connection is likely not configured correctly. Please read our [link] Knowledge Base article [/link] for steps how to resolve it.';
const SOLVE_DB_ISSUE_URL = 'http://beta.docs.mailpoet.com/article/200-solving-database-connection-issues';
protected $plugin_initialized = false;
private $access_control;
private $renderer;
const INITIALIZED = 'MAILPOET_INITIALIZED';
function __construct($params = array(
'file' => '',
'version' => '1.0.0'
)) {
Env::init($params['file'], $params['version']);
$this->access_control = new AccessControl();
}
function init() {
@ -40,8 +39,8 @@ class Initializer {
$this->setupDB();
} catch(\Exception $e) {
return WPNotice::displayError(Helpers::replaceLinkTags(
__(self::UNABLE_TO_CONNECT, 'mailpoet'),
self::SOLVE_DB_ISSUE_URL,
__('Unable to connect to the database (the database is unable to open a file or folder), the connection is likely not configured correctly. Please read our [link] Knowledge Base article [/link] for steps how to resolve it.', 'mailpoet'),
'//beta.docs.mailpoet.com/article/200-solving-database-connection-issues',
array('target' => '_blank')
));
}
@ -50,8 +49,8 @@ class Initializer {
register_activation_hook(
Env::$file,
array(
'MailPoet\Config\Activator',
'activate'
$this,
'runActivator'
)
);
@ -60,27 +59,20 @@ class Initializer {
'action'
), 10, 2);
add_action('admin_init', array(
new DeferredAdminNotices,
'printAndClean'
));
add_action('plugins_loaded', array(
$this,
'setup'
));
add_action('init', array(
$this,
'onInit'
));
add_action('widgets_init', array(
$this,
'setupWidget'
));
), 0);
add_action('wp_loaded', array(
$this,
'setupHooks'
));
add_action('admin_init', array(
new DeferredAdminNotices,
'printAndClean'
));
}
function checkRequirements() {
@ -88,47 +80,45 @@ class Initializer {
return $requirements->checkAllRequirements();
}
function runActivator() {
$activator = new Activator();
return $activator->activate();
}
function setupDB() {
$database = new Database();
$database->init();
}
function setup() {
function onInit() {
try {
$this->setupAccessControl();
$this->maybeDbUpdate();
$this->setupRenderer();
$this->setupInstaller();
$this->setupUpdater();
$this->setupRenderer();
$this->setupWidget();
$this->setupLocalizer();
$this->setupMenu();
$this->setupChangelog();
$this->setupShortcodes();
$this->setupImages();
$this->setupChangelog();
$this->setupCronTrigger();
$this->setupConflictResolver();
$this->plugin_initialized = true;
do_action('mailpoet_initialized', MAILPOET_VERSION);
} catch(\Exception $e) {
$this->handleFailedInitialization($e);
}
}
function onInit() {
if(!$this->plugin_initialized) {
define('MAILPOET_INITIALIZED', false);
return;
}
try {
$this->setupJSONAPI();
$this->setupRouter();
$this->setupPages();
do_action('mailpoet_initialized', MAILPOET_VERSION);
} catch(\Exception $e) {
$this->handleFailedInitialization($e);
return $this->handleFailedInitialization($e);
}
define('MAILPOET_INITIALIZED', true);
define(self::INITIALIZED, true);
}
function maybeDbUpdate() {
@ -139,28 +129,12 @@ class Initializer {
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
}
$activator = new Activator();
$activator->activate();
$this->runActivator();
}
}
function setupWidget() {
if(!$this->plugin_initialized) {
return;
}
try {
$widget = new Widget($this->renderer);
$widget->init();
} catch(\Exception $e) {
$this->handleFailedInitialization($e);
}
}
function setupRenderer() {
$caching = !WP_DEBUG;
$debugging = WP_DEBUG;
$this->renderer = new Renderer($caching, $debugging);
function setupAccessControl() {
$this->access_control = new AccessControl();
}
function setupInstaller() {
@ -184,6 +158,17 @@ class Initializer {
$updater->init();
}
function setupRenderer() {
$caching = !WP_DEBUG;
$debugging = WP_DEBUG;
$this->renderer = new Renderer($caching, $debugging);
}
function setupWidget() {
$widget = new Widget($this->renderer);
$widget->init();
}
function setupLocalizer() {
$localizer = new Localizer($this->renderer);
$localizer->init();
@ -194,41 +179,18 @@ class Initializer {
$menu->init();
}
function setupChangelog() {
$changelog = new Changelog();
$changelog->init();
}
function setupPages() {
$pages = new \MailPoet\Settings\Pages();
$pages->init();
}
function setupShortcodes() {
$shortcodes = new Shortcodes();
$shortcodes->init();
}
function setupHooks() {
if(!$this->plugin_initialized) {
return;
}
try {
$hooks = new Hooks();
$hooks->init();
} catch(\Exception $e) {
$this->handleFailedInitialization($e);
}
function setupImages() {
add_image_size('mailpoet_newsletter_max', 1320);
}
function setupJSONAPI() {
API\API::JSON($this->access_control)->init();
}
function setupRouter() {
$router = new Router\Router($this->access_control);
$router->init();
function setupChangelog() {
$changelog = new Changelog();
$changelog->init();
}
function setupCronTrigger() {
@ -239,20 +201,41 @@ class Initializer {
}
}
function setupImages() {
add_image_size('mailpoet_newsletter_max', 1320);
}
function setupConflictResolver() {
$conflict_resolver = new ConflictResolver();
$conflict_resolver->init();
}
function setupJSONAPI() {
$json_api = API\API::JSON($this->access_control);
$json_api->init();
}
function setupRouter() {
$router = new Router\Router($this->access_control);
$router->init();
}
function setupPages() {
$pages = new \MailPoet\Settings\Pages();
$pages->init();
}
function setupHooks() {
if(!defined(self::INITIALIZED)) return;
try {
$hooks = new Hooks();
$hooks->init();
} catch(\Exception $e) {
$this->handleFailedInitialization($e);
}
}
function handleFailedInitialization($exception) {
// Check if we are able to add pages at this point
// check if we are able to add pages at this point
if(function_exists('wp_get_current_user')) {
Menu::addErrorPage($this->access_control);
}
return WPNotice::displayError($exception);
}
}
}

View File

@ -59,6 +59,11 @@ class Menu {
if(self::isOnMailPoetAdminPage()) {
do_action('mailpoet_conflict_resolver_styles');
do_action('mailpoet_conflict_resolver_scripts');
if($_REQUEST['page'] === 'mailpoet-newsletter-editor') {
// Disable WP emojis to not interfere with the newsletter editor emoji handling
$this->disableWPEmojis();
}
}
// Main page
@ -314,6 +319,11 @@ class Menu {
);
}
function disableWPEmojis() {
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('admin_print_styles', 'print_emoji_styles');
}
function welcome() {
if((bool)(defined('DOING_AJAX') && DOING_AJAX)) return;
@ -541,7 +551,8 @@ class Menu {
'shortcodes' => ShortcodesHelper::getShortcodes(),
'settings' => Setting::getAll(),
'current_wp_user' => Subscriber::getCurrentWPUser(),
'sub_menu' => self::MAIN_PAGE_SLUG
'sub_menu' => self::MAIN_PAGE_SLUG,
'mss_active' => Bridge::isMPSendingServiceEnabled()
);
wp_enqueue_media();
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));

View File

@ -12,7 +12,7 @@ class PluginActivatedHook {
}
public function action($plugin, $network_wide) {
if($network_wide) {
if($plugin === plugin_basename(Env::$file) && $network_wide) {
$this->deferred_admin_notices->addNetworkAdminNotice(__('We noticed that you\'re using an unsupported environment. While MailPoet might work within a MultiSite environment, we dont support it.', 'mailpoet'));
}
}

View File

@ -4,6 +4,7 @@ use Carbon\Carbon;
use MailPoet\Newsletter\Renderer\Renderer;
use MailPoet\Util\Helpers;
use MailPoet\Util\Security;
use MailPoet\WP\Emoji;
if(!defined('ABSPATH')) exit;
@ -79,11 +80,15 @@ class Newsletter extends Model {
$this->set_expr('deleted_at', 'NULL');
}
$this->set('body',
is_array($this->body)
? json_encode($this->body)
: $this->body
);
if(isset($this->body)) {
if(is_array($this->body)) {
$this->body = json_encode($this->body);
}
$this->set(
'body',
Emoji::encodeForUTF8Column(self::$_table, 'body', $this->body)
);
}
$this->set('hash',
($this->hash)

View File

@ -1,6 +1,8 @@
<?php
namespace MailPoet\Models;
use MailPoet\WP\Emoji;
if(!defined('ABSPATH')) exit;
class SendingQueue extends Model {
@ -55,7 +57,10 @@ class SendingQueue extends Model {
$this->set('subscribers', serialize($this->subscribers));
}
if(!is_serialized($this->newsletter_rendered_body) && !is_null($this->newsletter_rendered_body)) {
$this->set('newsletter_rendered_body', serialize($this->newsletter_rendered_body));
$this->set(
'newsletter_rendered_body',
serialize($this->encodeEmojisInBody($this->newsletter_rendered_body))
);
}
// set the default priority to medium
if(!$this->priority) {
@ -81,12 +86,34 @@ class SendingQueue extends Model {
function getNewsletterRenderedBody($type = false) {
$rendered_newsletter = (!is_serialized($this->newsletter_rendered_body)) ?
$this->newsletter_rendered_body :
unserialize($this->newsletter_rendered_body);
$this->decodeEmojisInBody(unserialize($this->newsletter_rendered_body));
return ($type && !empty($rendered_newsletter[$type])) ?
$rendered_newsletter[$type] :
$rendered_newsletter;
}
function encodeEmojisInBody($newsletter_rendered_body) {
if(is_array($newsletter_rendered_body)) {
foreach($newsletter_rendered_body as $key => $value) {
$newsletter_rendered_body[$key] = Emoji::encodeForUTF8Column(
self::$_table,
'newsletter_rendered_body',
$value
);
}
}
return $newsletter_rendered_body;
}
function decodeEmojisInBody($newsletter_rendered_body) {
if(is_array($newsletter_rendered_body)) {
foreach($newsletter_rendered_body as $key => $value) {
$newsletter_rendered_body[$key] = Emoji::decodeEntities($value);
}
}
return $newsletter_rendered_body;
}
function isSubscriberProcessed($subscriber_id) {
$subscribers = $this->getSubscribers();
return in_array($subscriber_id, $subscribers['processed']);

View File

@ -149,7 +149,11 @@ class Subscriber extends Model {
static function generateToken($email = null) {
if($email !== null) {
return substr(md5(AUTH_KEY . $email), 0, self::SUBSCRIBER_TOKEN_LENGTH);
$auth_key = '';
if(defined('AUTH_KEY')) {
$auth_key = AUTH_KEY;
}
return substr(md5($auth_key . $email), 0, self::SUBSCRIBER_TOKEN_LENGTH);
}
return false;
}

View File

@ -22,8 +22,12 @@ class Security {
static function generateHash($length = false) {
$length = ($length) ? $length : self::HASH_LENGTH;
$auth_key = '';
if(defined('AUTH_KEY')) {
$auth_key = AUTH_KEY;
}
return substr(
md5(AUTH_KEY . self::generateRandomString(64)),
md5($auth_key . self::generateRandomString(64)),
0,
$length
);

32
lib/WP/Emoji.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace MailPoet\WP;
class Emoji {
static function encodeForUTF8Column($table, $field, $value) {
global $wpdb;
$charset = $wpdb->get_col_charset($table, $field);
if($charset === 'utf8') {
$value = wp_encode_emoji($value);
}
return $value;
}
static function decodeEntities($content) {
// Based on wp_staticize_emoji()
// Loosely match the Emoji Unicode range.
$regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/';
$matches = array();
if(preg_match_all($regex, $content, $matches)) {
if(!empty($matches[1])) {
foreach($matches[1] as $emoji) {
$entity = html_entity_decode($emoji, ENT_COMPAT, 'UTF-8');
$content = str_replace($emoji, $entity, $content);
}
}
}
return $content;
}
}

View File

@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
/*
* Plugin Name: MailPoet 3 (new)
* Version: 3.0.0-rc.2.0.0
* Version: 3.0.0-rc.2.0.1
* Plugin URI: http://www.mailpoet.com
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
* Author: MailPoet
@ -21,7 +21,7 @@ if(!defined('ABSPATH')) exit;
*/
$mailpoet_plugin = array(
'version' => '3.0.0-rc.2.0.0',
'version' => '3.0.0-rc.2.0.1',
'filename' => __FILE__,
'path' => dirname(__FILE__),
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',

View File

@ -4,7 +4,7 @@ Tags: newsletter, email, welcome email, post notification, autoresponder, signup
Requires at least: 4.6
Tested up to: 4.8
Requires PHP: 5.3
Stable tag: 3.0.0-rc.2.0.0
Stable tag: 3.0.0-rc.2.0.1
Create and send beautiful emails and newsletters from WordPress.
== Description ==
@ -94,6 +94,12 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
== Changelog ==
= 3.0.0-rc.2.0.1 - 2017-08-30 =
* Fixed: newsletters with emojis are properly saved and sent on certain hosts. Thanks Alison, Scott and Swann!
* Fixed: plugin activates on multisite environments;
* Fixed: subscription forms with list selection field are working now;
* Fixed: newsletter editor does not require "unsubscribe" link when a third-party sending method is used;
= 3.0.0-rc.2.0.0 - 2017-08-29 =
* Improved: MailPoet updates on high traffic sites now use less resources;
* Improved: newsletter is saved when "next" button is pressed in newsletter editor;

View File

@ -14,6 +14,7 @@ class SubscribersTest extends \MailPoetTest {
function _before() {
$obfuscator = new FieldNameObfuscator();
$this->obfuscatedEmail = $obfuscator->obfuscate('email');
$this->obfuscatedSegments = $obfuscator->obfuscate('segments');
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
@ -433,7 +434,7 @@ class SubscribersTest extends \MailPoetTest {
$response = $router->subscribe(array(
$this->obfuscatedEmail => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
));
expect($response->status)->equals(APIResponse::STATUS_OK);
}
@ -470,7 +471,7 @@ class SubscribersTest extends \MailPoetTest {
$response = $router->subscribe(array(
$this->obfuscatedEmail => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
));
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
@ -482,7 +483,7 @@ class SubscribersTest extends \MailPoetTest {
$response = $router->subscribe(array(
$this->obfuscatedEmail => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id),
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id),
// exists in table and in the form
'first_name' => 'aaa',
// exists in table, but not in the form
@ -503,14 +504,14 @@ class SubscribersTest extends \MailPoetTest {
$response = $router->subscribe(array(
$this->obfuscatedEmail => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
));
try {
$response = $router->subscribe(array(
$this->obfuscatedEmail => 'tata@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
));
$this->fail('It should not be possible to subscribe a second time so soon');
} catch(\Exception $e) {

View File

@ -5,6 +5,10 @@ use MailPoet\Config\Env;
class EnvTest extends \MailPoetTest {
function _before() {
// Back up original environment values
$this->file = Env::$file;
$this->version = Env::$version;
Env::init('file', '1.0.0');
}
@ -80,4 +84,9 @@ class EnvTest extends \MailPoetTest {
expect(Env::getDbTimezoneOffset('+11'))->equals("+11:00");
expect(Env::getDbTimezoneOffset('-5.5'))->equals("-05:30");
}
function _after() {
// Restore the original environment
Env::init($this->file, $this->version);
}
}

View File

@ -17,10 +17,10 @@ class PluginActivatedHookTest extends \MailPoetTest {
$this
);
$hook = new PluginActivatedHook($deferred_admin_notices);
$hook->action("mailpoet", true);
$hook->action("mailpoet/mailpoet.php", true);
}
public function testItDoesntAddsAMessageIfNoNetworkActivation() {
public function testItDoesntAddAMessageIfPluginNameDiffers() {
$deferred_admin_notices = Stub::makeEmpty(
'MailPoet\Config\DeferredAdminNotices',
array(
@ -29,7 +29,19 @@ class PluginActivatedHookTest extends \MailPoetTest {
$this
);
$hook = new PluginActivatedHook($deferred_admin_notices);
$hook->action("mailpoet", false);
$hook->action("some/plugin.php", true);
}
public function testItDoesntAddAMessageIfNoNetworkActivation() {
$deferred_admin_notices = Stub::makeEmpty(
'MailPoet\Config\DeferredAdminNotices',
array(
'addNetworkAdminNotice' => Stub::never(),
),
$this
);
$hook = new PluginActivatedHook($deferred_admin_notices);
$hook->action("mailpoet/mailpoet.php", false);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace MailPoet\Test\Models;
use AspectMock\Test as Mock;
use MailPoet\Models\SendingQueue;
class SendingQueueTest extends \MailPoetTest {
function _before() {
$this->queue = SendingQueue::create();
$this->queue->save();
$this->rendered_body = array(
'html' => 'some html',
'text' => 'some text'
);
}
function testItCanEncodeEmojisInBody() {
$mock = Mock::double('MailPoet\WP\Emoji', [
'encodeForUTF8Column' => function($params) {
return $params;
}
]);
$this->queue->encodeEmojisInBody($this->rendered_body);
$mock->verifyInvokedMultipleTimes('encodeForUTF8Column', 2);
}
function testItCanDecodeEmojisInBody() {
$mock = Mock::double('MailPoet\WP\Emoji', [
'decodeEntities' => function($params) {
return $params;
}
]);
$this->queue->decodeEmojisInBody($this->rendered_body);
$mock->verifyInvokedMultipleTimes('decodeEntities', 2);
}
function _after() {
Mock::clean();
\ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace MailPoet\Test\WP;
use MailPoet\Config\Env;
use MailPoet\WP\Emoji;
class EmojiTest extends \MailPoetTest {
function _before() {
$this->data_encoded = "Emojis: &#x1f603;&#x1f635;&#x1f4aa;, not emojis: &#046;&#0142;";
$this->data_decoded = "Emojis: 😃😵💪, not emojis: &#046;&#0142;";
$this->column = 'dummycol';
}
function testItCanEncodeForUTF8Column() {
$table = Env::$db_prefix . 'dummytable_utf8';
$this->createTable($table, 'utf8');
$result = Emoji::encodeForUTF8Column($table, $this->column, $this->data_decoded);
expect($result)->equals($this->data_encoded);
$this->dropTable($table);
}
function testItDoesNotEncodeForUTF8MB4Column() {
$table = Env::$db_prefix . 'dummytable_utf8mb4';
$this->createTable($table, 'utf8mb4');
$result = Emoji::encodeForUTF8Column($table, $this->column, $this->data_decoded);
expect($result)->equals($this->data_decoded);
$this->dropTable($table);
}
function testItCanDecodeEntities() {
$result = Emoji::decodeEntities($this->data_encoded);
expect($result)->equals($this->data_decoded);
}
private function createTable($table, $charset) {
\ORM::raw_execute(
'CREATE TABLE IF NOT EXISTS ' . $table
. ' (' . $this->column . ' TEXT) '
. 'DEFAULT CHARSET=' . $charset . ';'
);
}
private function dropTable($table) {
\ORM::raw_execute('DROP TABLE IF EXISTS ' . $table);
}
}

View File

@ -1200,7 +1200,7 @@
height: '768px'
},
validation: {
validateUnsubscribeLinkPresent: true, // TODO: Add validation based on whether Mailpoet MTA is used or not
validateUnsubscribeLinkPresent: <%= mss_active ? 'true' : 'false' %>,
},
urls: {
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | intval)) %>',