Compare commits
23 Commits
3.0.0-rc.2
...
3.0.0-rc.2
Author | SHA1 | Date | |
---|---|---|---|
856c636089 | |||
8f9e8ea185 | |||
b0b88693f1 | |||
9916eb9da8 | |||
79b5426e01 | |||
5807fd2e02 | |||
0ee39143f4 | |||
10c39bd650 | |||
20593cc5a5 | |||
cb4b599d97 | |||
53f7953566 | |||
61ae2da1e3 | |||
36abd8e5e6 | |||
7e9de1fd07 | |||
7ac5e65963 | |||
cf992852b5 | |||
59482b2bfa | |||
053f9e0cdf | |||
e1cc25239b | |||
2f4452ad36 | |||
f453d685d6 | |||
2d2b4ca7f0 | |||
b9bdc86fd9 |
@ -74,6 +74,8 @@ class Subscribers extends APIEndpoint {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = $this->deobfuscateFormPayload($data);
|
||||||
|
|
||||||
$segment_ids = (!empty($data['segments'])
|
$segment_ids = (!empty($data['segments'])
|
||||||
? (array)$data['segments']
|
? (array)$data['segments']
|
||||||
: array()
|
: array()
|
||||||
@ -81,7 +83,6 @@ class Subscribers extends APIEndpoint {
|
|||||||
$segment_ids = $form->filterSegments($segment_ids);
|
$segment_ids = $form->filterSegments($segment_ids);
|
||||||
unset($data['segments']);
|
unset($data['segments']);
|
||||||
|
|
||||||
$data = $this->deobfuscateFormPayload($data);
|
|
||||||
|
|
||||||
if(empty($segment_ids)) {
|
if(empty($segment_ids)) {
|
||||||
return $this->badRequest(array(
|
return $this->badRequest(array(
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Config;
|
namespace MailPoet\Config;
|
||||||
|
|
||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
|
|
||||||
class Hooks {
|
class Hooks {
|
||||||
function __construct() {
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$this->setupWPUsers();
|
$this->setupWPUsers();
|
||||||
$this->setupImageSize();
|
$this->setupImageSize();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Config;
|
namespace MailPoet\Config;
|
||||||
|
|
||||||
use MailPoet\API;
|
use MailPoet\API;
|
||||||
@ -13,18 +14,16 @@ if(!defined('ABSPATH')) exit;
|
|||||||
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
||||||
|
|
||||||
class Initializer {
|
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 $access_control;
|
||||||
|
private $renderer;
|
||||||
|
|
||||||
|
const INITIALIZED = 'MAILPOET_INITIALIZED';
|
||||||
|
|
||||||
function __construct($params = array(
|
function __construct($params = array(
|
||||||
'file' => '',
|
'file' => '',
|
||||||
'version' => '1.0.0'
|
'version' => '1.0.0'
|
||||||
)) {
|
)) {
|
||||||
Env::init($params['file'], $params['version']);
|
Env::init($params['file'], $params['version']);
|
||||||
$this->access_control = new AccessControl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@ -40,8 +39,8 @@ class Initializer {
|
|||||||
$this->setupDB();
|
$this->setupDB();
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return WPNotice::displayError(Helpers::replaceLinkTags(
|
return WPNotice::displayError(Helpers::replaceLinkTags(
|
||||||
__(self::UNABLE_TO_CONNECT, 'mailpoet'),
|
__('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'),
|
||||||
self::SOLVE_DB_ISSUE_URL,
|
'//beta.docs.mailpoet.com/article/200-solving-database-connection-issues',
|
||||||
array('target' => '_blank')
|
array('target' => '_blank')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -50,8 +49,8 @@ class Initializer {
|
|||||||
register_activation_hook(
|
register_activation_hook(
|
||||||
Env::$file,
|
Env::$file,
|
||||||
array(
|
array(
|
||||||
'MailPoet\Config\Activator',
|
$this,
|
||||||
'activate'
|
'runActivator'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,27 +59,20 @@ class Initializer {
|
|||||||
'action'
|
'action'
|
||||||
), 10, 2);
|
), 10, 2);
|
||||||
|
|
||||||
add_action('admin_init', array(
|
|
||||||
new DeferredAdminNotices,
|
|
||||||
'printAndClean'
|
|
||||||
));
|
|
||||||
|
|
||||||
add_action('plugins_loaded', array(
|
|
||||||
$this,
|
|
||||||
'setup'
|
|
||||||
));
|
|
||||||
add_action('init', array(
|
add_action('init', array(
|
||||||
$this,
|
$this,
|
||||||
'onInit'
|
'onInit'
|
||||||
));
|
), 0);
|
||||||
add_action('widgets_init', array(
|
|
||||||
$this,
|
|
||||||
'setupWidget'
|
|
||||||
));
|
|
||||||
add_action('wp_loaded', array(
|
add_action('wp_loaded', array(
|
||||||
$this,
|
$this,
|
||||||
'setupHooks'
|
'setupHooks'
|
||||||
));
|
));
|
||||||
|
|
||||||
|
add_action('admin_init', array(
|
||||||
|
new DeferredAdminNotices,
|
||||||
|
'printAndClean'
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRequirements() {
|
function checkRequirements() {
|
||||||
@ -88,47 +80,45 @@ class Initializer {
|
|||||||
return $requirements->checkAllRequirements();
|
return $requirements->checkAllRequirements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function runActivator() {
|
||||||
|
$activator = new Activator();
|
||||||
|
return $activator->activate();
|
||||||
|
}
|
||||||
|
|
||||||
function setupDB() {
|
function setupDB() {
|
||||||
$database = new Database();
|
$database = new Database();
|
||||||
$database->init();
|
$database->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup() {
|
function onInit() {
|
||||||
try {
|
try {
|
||||||
|
$this->setupAccessControl();
|
||||||
|
|
||||||
$this->maybeDbUpdate();
|
$this->maybeDbUpdate();
|
||||||
$this->setupRenderer();
|
|
||||||
$this->setupInstaller();
|
$this->setupInstaller();
|
||||||
$this->setupUpdater();
|
$this->setupUpdater();
|
||||||
|
|
||||||
|
$this->setupRenderer();
|
||||||
|
$this->setupWidget();
|
||||||
$this->setupLocalizer();
|
$this->setupLocalizer();
|
||||||
$this->setupMenu();
|
$this->setupMenu();
|
||||||
$this->setupChangelog();
|
|
||||||
$this->setupShortcodes();
|
$this->setupShortcodes();
|
||||||
$this->setupImages();
|
$this->setupImages();
|
||||||
|
|
||||||
|
$this->setupChangelog();
|
||||||
$this->setupCronTrigger();
|
$this->setupCronTrigger();
|
||||||
$this->setupConflictResolver();
|
$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->setupJSONAPI();
|
||||||
$this->setupRouter();
|
$this->setupRouter();
|
||||||
$this->setupPages();
|
$this->setupPages();
|
||||||
|
|
||||||
|
do_action('mailpoet_initialized', MAILPOET_VERSION);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$this->handleFailedInitialization($e);
|
return $this->handleFailedInitialization($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
define('MAILPOET_INITIALIZED', true);
|
define(self::INITIALIZED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeDbUpdate() {
|
function maybeDbUpdate() {
|
||||||
@ -139,28 +129,12 @@ class Initializer {
|
|||||||
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
|
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
|
||||||
throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
|
throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
|
||||||
}
|
}
|
||||||
$activator = new Activator();
|
$this->runActivator();
|
||||||
$activator->activate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupWidget() {
|
function setupAccessControl() {
|
||||||
if(!$this->plugin_initialized) {
|
$this->access_control = new AccessControl();
|
||||||
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 setupInstaller() {
|
function setupInstaller() {
|
||||||
@ -184,6 +158,17 @@ class Initializer {
|
|||||||
$updater->init();
|
$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() {
|
function setupLocalizer() {
|
||||||
$localizer = new Localizer($this->renderer);
|
$localizer = new Localizer($this->renderer);
|
||||||
$localizer->init();
|
$localizer->init();
|
||||||
@ -194,41 +179,18 @@ class Initializer {
|
|||||||
$menu->init();
|
$menu->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupChangelog() {
|
|
||||||
$changelog = new Changelog();
|
|
||||||
$changelog->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupPages() {
|
|
||||||
$pages = new \MailPoet\Settings\Pages();
|
|
||||||
$pages->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupShortcodes() {
|
function setupShortcodes() {
|
||||||
$shortcodes = new Shortcodes();
|
$shortcodes = new Shortcodes();
|
||||||
$shortcodes->init();
|
$shortcodes->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupHooks() {
|
function setupImages() {
|
||||||
if(!$this->plugin_initialized) {
|
add_image_size('mailpoet_newsletter_max', 1320);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
function setupChangelog() {
|
||||||
$hooks = new Hooks();
|
$changelog = new Changelog();
|
||||||
$hooks->init();
|
$changelog->init();
|
||||||
} catch(\Exception $e) {
|
|
||||||
$this->handleFailedInitialization($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupJSONAPI() {
|
|
||||||
API\API::JSON($this->access_control)->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupRouter() {
|
|
||||||
$router = new Router\Router($this->access_control);
|
|
||||||
$router->init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupCronTrigger() {
|
function setupCronTrigger() {
|
||||||
@ -239,17 +201,38 @@ class Initializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupImages() {
|
|
||||||
add_image_size('mailpoet_newsletter_max', 1320);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupConflictResolver() {
|
function setupConflictResolver() {
|
||||||
$conflict_resolver = new ConflictResolver();
|
$conflict_resolver = new ConflictResolver();
|
||||||
$conflict_resolver->init();
|
$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) {
|
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')) {
|
if(function_exists('wp_get_current_user')) {
|
||||||
Menu::addErrorPage($this->access_control);
|
Menu::addErrorPage($this->access_control);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,11 @@ class Menu {
|
|||||||
if(self::isOnMailPoetAdminPage()) {
|
if(self::isOnMailPoetAdminPage()) {
|
||||||
do_action('mailpoet_conflict_resolver_styles');
|
do_action('mailpoet_conflict_resolver_styles');
|
||||||
do_action('mailpoet_conflict_resolver_scripts');
|
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
|
// 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() {
|
function welcome() {
|
||||||
if((bool)(defined('DOING_AJAX') && DOING_AJAX)) return;
|
if((bool)(defined('DOING_AJAX') && DOING_AJAX)) return;
|
||||||
|
|
||||||
@ -541,7 +551,8 @@ class Menu {
|
|||||||
'shortcodes' => ShortcodesHelper::getShortcodes(),
|
'shortcodes' => ShortcodesHelper::getShortcodes(),
|
||||||
'settings' => Setting::getAll(),
|
'settings' => Setting::getAll(),
|
||||||
'current_wp_user' => Subscriber::getCurrentWPUser(),
|
'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_media();
|
||||||
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
|
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
|
||||||
|
@ -12,7 +12,7 @@ class PluginActivatedHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function action($plugin, $network_wide) {
|
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 don’t support it.', 'mailpoet'));
|
$this->deferred_admin_notices->addNetworkAdminNotice(__('We noticed that you\'re using an unsupported environment. While MailPoet might work within a MultiSite environment, we don’t support it.', 'mailpoet'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use Carbon\Carbon;
|
|||||||
use MailPoet\Newsletter\Renderer\Renderer;
|
use MailPoet\Newsletter\Renderer\Renderer;
|
||||||
use MailPoet\Util\Helpers;
|
use MailPoet\Util\Helpers;
|
||||||
use MailPoet\Util\Security;
|
use MailPoet\Util\Security;
|
||||||
|
use MailPoet\WP\Emoji;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
@ -79,11 +80,15 @@ class Newsletter extends Model {
|
|||||||
$this->set_expr('deleted_at', 'NULL');
|
$this->set_expr('deleted_at', 'NULL');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set('body',
|
if(isset($this->body)) {
|
||||||
is_array($this->body)
|
if(is_array($this->body)) {
|
||||||
? json_encode($this->body)
|
$this->body = json_encode($this->body);
|
||||||
: $this->body
|
}
|
||||||
|
$this->set(
|
||||||
|
'body',
|
||||||
|
Emoji::encodeForUTF8Column(self::$_table, 'body', $this->body)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$this->set('hash',
|
$this->set('hash',
|
||||||
($this->hash)
|
($this->hash)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Models;
|
namespace MailPoet\Models;
|
||||||
|
|
||||||
|
use MailPoet\WP\Emoji;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class SendingQueue extends Model {
|
class SendingQueue extends Model {
|
||||||
@ -55,7 +57,10 @@ class SendingQueue extends Model {
|
|||||||
$this->set('subscribers', serialize($this->subscribers));
|
$this->set('subscribers', serialize($this->subscribers));
|
||||||
}
|
}
|
||||||
if(!is_serialized($this->newsletter_rendered_body) && !is_null($this->newsletter_rendered_body)) {
|
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
|
// set the default priority to medium
|
||||||
if(!$this->priority) {
|
if(!$this->priority) {
|
||||||
@ -81,12 +86,34 @@ class SendingQueue extends Model {
|
|||||||
function getNewsletterRenderedBody($type = false) {
|
function getNewsletterRenderedBody($type = false) {
|
||||||
$rendered_newsletter = (!is_serialized($this->newsletter_rendered_body)) ?
|
$rendered_newsletter = (!is_serialized($this->newsletter_rendered_body)) ?
|
||||||
$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])) ?
|
return ($type && !empty($rendered_newsletter[$type])) ?
|
||||||
$rendered_newsletter[$type] :
|
$rendered_newsletter[$type] :
|
||||||
$rendered_newsletter;
|
$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) {
|
function isSubscriberProcessed($subscriber_id) {
|
||||||
$subscribers = $this->getSubscribers();
|
$subscribers = $this->getSubscribers();
|
||||||
return in_array($subscriber_id, $subscribers['processed']);
|
return in_array($subscriber_id, $subscribers['processed']);
|
||||||
|
@ -149,7 +149,11 @@ class Subscriber extends Model {
|
|||||||
|
|
||||||
static function generateToken($email = null) {
|
static function generateToken($email = null) {
|
||||||
if($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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,12 @@ class Security {
|
|||||||
|
|
||||||
static function generateHash($length = false) {
|
static function generateHash($length = false) {
|
||||||
$length = ($length) ? $length : self::HASH_LENGTH;
|
$length = ($length) ? $length : self::HASH_LENGTH;
|
||||||
|
$auth_key = '';
|
||||||
|
if(defined('AUTH_KEY')) {
|
||||||
|
$auth_key = AUTH_KEY;
|
||||||
|
}
|
||||||
return substr(
|
return substr(
|
||||||
md5(AUTH_KEY . self::generateRandomString(64)),
|
md5($auth_key . self::generateRandomString(64)),
|
||||||
0,
|
0,
|
||||||
$length
|
$length
|
||||||
);
|
);
|
||||||
|
32
lib/WP/Emoji.php
Normal file
32
lib/WP/Emoji.php
Normal 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};|[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;
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Plugin Name: MailPoet 3 (new)
|
* 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
|
* Plugin URI: http://www.mailpoet.com
|
||||||
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
|
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
|
||||||
* Author: MailPoet
|
* Author: MailPoet
|
||||||
@ -21,7 +21,7 @@ if(!defined('ABSPATH')) exit;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$mailpoet_plugin = array(
|
$mailpoet_plugin = array(
|
||||||
'version' => '3.0.0-rc.2.0.0',
|
'version' => '3.0.0-rc.2.0.1',
|
||||||
'filename' => __FILE__,
|
'filename' => __FILE__,
|
||||||
'path' => dirname(__FILE__),
|
'path' => dirname(__FILE__),
|
||||||
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
||||||
|
@ -4,7 +4,7 @@ Tags: newsletter, email, welcome email, post notification, autoresponder, signup
|
|||||||
Requires at least: 4.6
|
Requires at least: 4.6
|
||||||
Tested up to: 4.8
|
Tested up to: 4.8
|
||||||
Requires PHP: 5.3
|
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.
|
Create and send beautiful emails and newsletters from WordPress.
|
||||||
|
|
||||||
== Description ==
|
== Description ==
|
||||||
@ -94,6 +94,12 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
|
|||||||
|
|
||||||
== Changelog ==
|
== 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 =
|
= 3.0.0-rc.2.0.0 - 2017-08-29 =
|
||||||
* Improved: MailPoet updates on high traffic sites now use less resources;
|
* Improved: MailPoet updates on high traffic sites now use less resources;
|
||||||
* Improved: newsletter is saved when "next" button is pressed in newsletter editor;
|
* Improved: newsletter is saved when "next" button is pressed in newsletter editor;
|
||||||
|
@ -14,6 +14,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
function _before() {
|
function _before() {
|
||||||
$obfuscator = new FieldNameObfuscator();
|
$obfuscator = new FieldNameObfuscator();
|
||||||
$this->obfuscatedEmail = $obfuscator->obfuscate('email');
|
$this->obfuscatedEmail = $obfuscator->obfuscate('email');
|
||||||
|
$this->obfuscatedSegments = $obfuscator->obfuscate('segments');
|
||||||
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
|
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
|
||||||
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
|
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
|
||||||
|
|
||||||
@ -433,7 +434,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'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);
|
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||||
}
|
}
|
||||||
@ -470,7 +471,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'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);
|
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||||
@ -482,7 +483,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'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
|
// exists in table and in the form
|
||||||
'first_name' => 'aaa',
|
'first_name' => 'aaa',
|
||||||
// exists in table, but not in the form
|
// exists in table, but not in the form
|
||||||
@ -503,14 +504,14 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'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 {
|
try {
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
$this->obfuscatedEmail => 'tata@mailpoet.com',
|
$this->obfuscatedEmail => 'tata@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'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');
|
$this->fail('It should not be possible to subscribe a second time so soon');
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
|
@ -5,6 +5,10 @@ use MailPoet\Config\Env;
|
|||||||
|
|
||||||
class EnvTest extends \MailPoetTest {
|
class EnvTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
|
// Back up original environment values
|
||||||
|
$this->file = Env::$file;
|
||||||
|
$this->version = Env::$version;
|
||||||
|
|
||||||
Env::init('file', '1.0.0');
|
Env::init('file', '1.0.0');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,4 +84,9 @@ class EnvTest extends \MailPoetTest {
|
|||||||
expect(Env::getDbTimezoneOffset('+11'))->equals("+11:00");
|
expect(Env::getDbTimezoneOffset('+11'))->equals("+11:00");
|
||||||
expect(Env::getDbTimezoneOffset('-5.5'))->equals("-05:30");
|
expect(Env::getDbTimezoneOffset('-5.5'))->equals("-05:30");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _after() {
|
||||||
|
// Restore the original environment
|
||||||
|
Env::init($this->file, $this->version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,10 @@ class PluginActivatedHookTest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$hook = new PluginActivatedHook($deferred_admin_notices);
|
$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(
|
$deferred_admin_notices = Stub::makeEmpty(
|
||||||
'MailPoet\Config\DeferredAdminNotices',
|
'MailPoet\Config\DeferredAdminNotices',
|
||||||
array(
|
array(
|
||||||
@ -29,7 +29,19 @@ class PluginActivatedHookTest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$hook = new PluginActivatedHook($deferred_admin_notices);
|
$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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
42
tests/unit/Models/SendingQueueTest.php
Normal file
42
tests/unit/Models/SendingQueueTest.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
51
tests/unit/WP/EmojiTest.php
Normal file
51
tests/unit/WP/EmojiTest.php
Normal 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: 😃😵💪, not emojis: .Ž";
|
||||||
|
$this->data_decoded = "Emojis: 😃😵💪, not emojis: .Ž";
|
||||||
|
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
@ -1200,7 +1200,7 @@
|
|||||||
height: '768px'
|
height: '768px'
|
||||||
},
|
},
|
||||||
validation: {
|
validation: {
|
||||||
validateUnsubscribeLinkPresent: true, // TODO: Add validation based on whether Mailpoet MTA is used or not
|
validateUnsubscribeLinkPresent: <%= mss_active ? 'true' : 'false' %>,
|
||||||
},
|
},
|
||||||
urls: {
|
urls: {
|
||||||
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | intval)) %>',
|
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | intval)) %>',
|
||||||
|
Reference in New Issue
Block a user