Compare commits
55 Commits
3.0.0-rc.2
...
3.0.0
Author | SHA1 | Date | |
---|---|---|---|
c915fcfdff | |||
02966c3b93 | |||
84dc48daec | |||
12225004f4 | |||
320dfa2ec5 | |||
b5f3016085 | |||
cd53e369d0 | |||
6fc11af774 | |||
03d0de74e4 | |||
28c75c5b96 | |||
6f255854f2 | |||
91c5f9c43e | |||
62acd6404a | |||
adc1461771 | |||
66cc0964ce | |||
10d77720ad | |||
d831b2df55 | |||
16ff630e88 | |||
d35763662e | |||
10be411b12 | |||
6ecce192f7 | |||
ee07e60fe9 | |||
a35d7a1154 | |||
ebba8dbfd6 | |||
44c637c06b | |||
d54ba734bf | |||
b45fc22306 | |||
994935d4ae | |||
ceb5ce850c | |||
97b5ed945d | |||
873b322245 | |||
12ad9e41e7 | |||
96b418e455 | |||
8ea7861f77 | |||
821976c881 | |||
6f1443e43d | |||
09fcaecdfc | |||
efd72ca9f6 | |||
550b5e9aed | |||
4b7ae5fcff | |||
fa85e12127 | |||
1cce50902b | |||
2048fa5cf9 | |||
f438c8fd31 | |||
0bfa832dad | |||
483dfbe1ec | |||
561fee491d | |||
97d157192a | |||
6b14a8a057 | |||
d27b187f5e | |||
02d49ba2ca | |||
f3571a5855 | |||
3d5f0df213 | |||
595a201fe7 | |||
fd65117a5d |
@ -33,3 +33,6 @@ Custom styles for MailPoet pages.
|
||||
|
||||
p.top-space-triple
|
||||
margin-top: 3em
|
||||
|
||||
p.mailpoet-top-text
|
||||
margin-right: 0
|
||||
|
@ -62,6 +62,15 @@
|
||||
margin-bottom: 2em
|
||||
margin-top: 2em
|
||||
|
||||
.sending-free-plan-button
|
||||
background: #FF5301
|
||||
border-color: #e64c03
|
||||
text-shadow: 0 -1px 1px #e64c03
|
||||
box-shadow: 0 1px 0 #e64c03
|
||||
margin: 10px 0
|
||||
strong
|
||||
text-transform: uppercase
|
||||
|
||||
.mailpoet_success_item::before
|
||||
content '✔ '
|
||||
|
||||
|
@ -285,6 +285,7 @@ define(
|
||||
}
|
||||
return newField;
|
||||
});
|
||||
const sendButtonOptions = this.getSendButtonOptions();
|
||||
return (
|
||||
<div>
|
||||
<h1>{MailPoet.I18n.t('finalNewsletterStep')}</h1>
|
||||
@ -313,7 +314,7 @@ define(
|
||||
type="button"
|
||||
onClick={ this.handleSend }
|
||||
value={MailPoet.I18n.t('send')}
|
||||
{...this.getSendButtonOptions()}
|
||||
{...sendButtonOptions}
|
||||
/>
|
||||
}
|
||||
|
||||
@ -330,10 +331,12 @@ define(
|
||||
{MailPoet.I18n.t('goBackToDesign')}
|
||||
</a>.
|
||||
</p>
|
||||
<HelpTooltip
|
||||
tooltip={MailPoet.I18n.t('helpTooltipSendEmail')}
|
||||
tooltipId="helpTooltipSendEmail"
|
||||
/>
|
||||
{ !isPaused && sendButtonOptions['disabled'] && sendButtonOptions['disabled'] === 'disabled' && (
|
||||
<HelpTooltip
|
||||
tooltip={MailPoet.I18n.t('helpTooltipSendEmail')}
|
||||
tooltipId="helpTooltipSendEmail"
|
||||
/>
|
||||
) }
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
@ -13,6 +13,7 @@ class RequirementsChecker {
|
||||
const TEST_XML_EXTENSION = 'XmlExtension';
|
||||
const TEST_ZIP_EXTENSION = 'ZipExtension';
|
||||
const TEST_VENDOR_SOURCE = 'VendorSource';
|
||||
const TWIG_SUPPORTED_VERSIONS = '1.26.0-1.34.4';
|
||||
|
||||
public $display_error_notice;
|
||||
public $vendor_classes = array(
|
||||
@ -22,7 +23,6 @@ class RequirementsChecker {
|
||||
'\Twig_Loader_Filesystem',
|
||||
'\Twig_Lexer',
|
||||
'\Twig_Extension',
|
||||
'\Twig_Extension_GlobalsInterface',
|
||||
'\Twig_SimpleFunction',
|
||||
'\Swift_Mailer',
|
||||
'\Swift_SmtpTransport',
|
||||
@ -141,13 +141,30 @@ class RequirementsChecker {
|
||||
$dependency_path
|
||||
);
|
||||
|
||||
return $this->processError($error);
|
||||
$return_error = true;
|
||||
|
||||
// if a Twig dependency is loaded by another plugin, check for valid version
|
||||
if(strpos($dependency, '\Twig_') === 0) {
|
||||
$return_error = ($this->isValidTwigVersion()) ? false : $return_error;
|
||||
}
|
||||
|
||||
if($return_error) return $this->processError($error);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isValidTwigVersion() {
|
||||
list($minimum_version, $maximum_version) = explode('-', self::TWIG_SUPPORTED_VERSIONS);
|
||||
return (
|
||||
class_exists('\Twig_Environment') &&
|
||||
defined('\Twig_Environment::VERSION') &&
|
||||
version_compare(\Twig_Environment::VERSION, $minimum_version, '>=') &&
|
||||
version_compare(\Twig_Environment::VERSION, $maximum_version, '<=')
|
||||
);
|
||||
}
|
||||
|
||||
private function getDependencyPath($namespaced_class) {
|
||||
try {
|
||||
$reflector = new \ReflectionClass($namespaced_class);
|
||||
@ -163,4 +180,4 @@ class RequirementsChecker {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ if(!defined('ABSPATH')) exit;
|
||||
class CronHelper {
|
||||
const DAEMON_EXECUTION_LIMIT = 20; // seconds
|
||||
const DAEMON_EXECUTION_TIMEOUT = 35; // seconds
|
||||
const DAEMON_REQUEST_TIMEOUT = 2; // seconds
|
||||
const DAEMON_REQUEST_TIMEOUT = 5; // seconds
|
||||
const DAEMON_SETTING = 'cron_daemon';
|
||||
|
||||
static function createDaemon($token) {
|
||||
@ -49,45 +49,53 @@ class CronHelper {
|
||||
}
|
||||
|
||||
static function pingDaemon() {
|
||||
$url = Router::buildRequest(
|
||||
CronDaemonEndpoint::ENDPOINT,
|
||||
$url = self::getCronUrl(
|
||||
CronDaemonEndpoint::ACTION_PING_RESPONSE
|
||||
);
|
||||
$url = str_replace(home_url(), self::getSiteUrl(), $url);
|
||||
$args = array(
|
||||
'blocking' => true,
|
||||
'sslverify' => false,
|
||||
'timeout' => self::DAEMON_REQUEST_TIMEOUT,
|
||||
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
|
||||
);
|
||||
$result = wp_remote_get($url, $args);
|
||||
return wp_remote_retrieve_body($result);
|
||||
$result = self::queryCronUrl($url);
|
||||
return (is_wp_error($result)) ?
|
||||
$result->get_error_message() :
|
||||
wp_remote_retrieve_body($result);
|
||||
}
|
||||
|
||||
static function accessDaemon($token, $timeout = self::DAEMON_REQUEST_TIMEOUT) {
|
||||
static function accessDaemon($token) {
|
||||
$data = array('token' => $token);
|
||||
$url = Router::buildRequest(
|
||||
CronDaemonEndpoint::ENDPOINT,
|
||||
$url = self::getCronUrl(
|
||||
CronDaemonEndpoint::ACTION_RUN,
|
||||
$data
|
||||
);
|
||||
$url = str_replace(home_url(), self::getSiteUrl(), $url);
|
||||
$args = array(
|
||||
'blocking' => true,
|
||||
'sslverify' => false,
|
||||
'timeout' => $timeout,
|
||||
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
|
||||
);
|
||||
$result = wp_remote_get($url, $args);
|
||||
$result = self::queryCronUrl($url);
|
||||
return wp_remote_retrieve_body($result);
|
||||
}
|
||||
|
||||
static function queryCronUrl($url) {
|
||||
$args = WPHooks::applyFilters(
|
||||
'mailpoet_cron_request_args',
|
||||
array(
|
||||
'blocking' => true,
|
||||
'sslverify' => false,
|
||||
'timeout' => self::DAEMON_REQUEST_TIMEOUT,
|
||||
'user-agent' => 'MailPoet Cron'
|
||||
)
|
||||
);
|
||||
return wp_remote_get($url, $args);
|
||||
}
|
||||
|
||||
static function getCronUrl($action, $data = false) {
|
||||
$url = Router::buildRequest(
|
||||
CronDaemonEndpoint::ENDPOINT,
|
||||
$action,
|
||||
$data
|
||||
);
|
||||
$custom_cron_url = WPHooks::applyFilters('mailpoet_cron_request_url', $url);
|
||||
return ($custom_cron_url === $url) ?
|
||||
str_replace(home_url(), self::getSiteUrl(), $url) :
|
||||
$custom_cron_url;
|
||||
}
|
||||
|
||||
static function getSiteUrl($site_url = false) {
|
||||
// additional check for some sites running inside a virtual machine or behind
|
||||
// proxy where there could be different ports (e.g., host:8080 => guest:80)
|
||||
$custom_cron_url = WPHooks::applyFilters('mailpoet_cron_request_url', null);
|
||||
if($custom_cron_url) return $custom_cron_url;
|
||||
|
||||
$site_url = ($site_url) ? $site_url : home_url();
|
||||
$parsed_url = parse_url($site_url);
|
||||
$scheme = '';
|
||||
|
@ -13,7 +13,6 @@ class Daemon {
|
||||
public $daemon;
|
||||
public $request_data;
|
||||
public $timer;
|
||||
const REQUEST_TIMEOUT = 5; // seconds
|
||||
|
||||
function __construct($request_data = false) {
|
||||
$this->request_data = $request_data;
|
||||
@ -100,7 +99,7 @@ class Daemon {
|
||||
}
|
||||
|
||||
function callSelf() {
|
||||
CronHelper::accessDaemon($this->token, self::REQUEST_TIMEOUT);
|
||||
CronHelper::accessDaemon($this->token);
|
||||
return $this->terminateRequest();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Router\Endpoints\CronDaemon;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -20,12 +21,14 @@ class Beacon {
|
||||
CronDaemon::ACTION_PING
|
||||
);
|
||||
$cron_ping_url = str_replace(home_url(), CronHelper::getSiteUrl(), $cron_ping_url);
|
||||
$premium_key = Setting::getValue(Bridge::PREMIUM_KEY_SETTING_NAME) ?: Setting::getValue(Bridge::API_KEY_SETTING_NAME);
|
||||
return array(
|
||||
'name' => $current_user->display_name,
|
||||
'email' => $current_user->user_email,
|
||||
'PHP version' => PHP_VERSION,
|
||||
'MailPoet Free version' => MAILPOET_VERSION,
|
||||
'MailPoet Premium version' => (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A',
|
||||
'MailPoet Premium/MSS key' => $premium_key,
|
||||
'WordPress version' => get_bloginfo('version'),
|
||||
'Database version' => $db_version,
|
||||
'Web server' => (!empty($_SERVER["SERVER_SOFTWARE"])) ? $_SERVER["SERVER_SOFTWARE"] : 'N/A',
|
||||
|
@ -97,10 +97,10 @@ class WP {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
UPDATE IGNORE %s
|
||||
JOIN %susers as wu ON %s.wp_user_id = wu.id
|
||||
JOIN %s as wu ON %s.wp_user_id = wu.id
|
||||
SET email = user_email
|
||||
WHERE %s.wp_user_id IS NOT NULL
|
||||
', $subscribers_table, $wpdb->prefix, $subscribers_table, $subscribers_table));
|
||||
', $subscribers_table, $wpdb->users, $subscribers_table, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function insertSubscribers() {
|
||||
@ -108,10 +108,10 @@ class WP {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
INSERT IGNORE INTO %s(wp_user_id, email, status, created_at)
|
||||
SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %susers wu
|
||||
SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %s wu
|
||||
LEFT JOIN %s mps ON wu.id = mps.wp_user_id
|
||||
WHERE mps.wp_user_id IS NULL
|
||||
', $subscribers_table, $wpdb->prefix, $subscribers_table));
|
||||
', $subscribers_table, $wpdb->users, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function updateFirstNames() {
|
||||
@ -119,11 +119,11 @@ class WP {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
UPDATE %s
|
||||
JOIN %susermeta as wpum ON %s.wp_user_id = wpum.user_id AND meta_key = "first_name"
|
||||
JOIN %s as wpum ON %s.wp_user_id = wpum.user_id AND meta_key = "first_name"
|
||||
SET first_name = meta_value
|
||||
WHERE %s.first_name = ""
|
||||
AND %s.wp_user_id IS NOT NULL
|
||||
', $subscribers_table, $wpdb->prefix, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
', $subscribers_table, $wpdb->usermeta, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function updateLastNames() {
|
||||
@ -131,11 +131,11 @@ class WP {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
UPDATE %s
|
||||
JOIN %susermeta as wpum ON %s.wp_user_id = wpum.user_id AND meta_key = "last_name"
|
||||
JOIN %s as wpum ON %s.wp_user_id = wpum.user_id AND meta_key = "last_name"
|
||||
SET last_name = meta_value
|
||||
WHERE %s.last_name = ""
|
||||
AND %s.wp_user_id IS NOT NULL
|
||||
', $subscribers_table, $wpdb->prefix, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
', $subscribers_table, $wpdb->usermeta, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function updateFristNameIfMissing() {
|
||||
@ -143,11 +143,11 @@ class WP {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
UPDATE %s
|
||||
JOIN %susers wu ON %s.wp_user_id = wu.id
|
||||
JOIN %s wu ON %s.wp_user_id = wu.id
|
||||
SET first_name = display_name
|
||||
WHERE %s.first_name = ""
|
||||
AND %s.wp_user_id IS NOT NULL
|
||||
', $subscribers_table, $wpdb->prefix, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
', $subscribers_table, $wpdb->users, $subscribers_table, $subscribers_table, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function insertUsersToSegment() {
|
||||
@ -157,14 +157,14 @@ class WP {
|
||||
Subscriber::raw_execute(sprintf('
|
||||
INSERT IGNORE INTO %s(subscriber_id, segment_id, created_at)
|
||||
SELECT mps.id, "%s", CURRENT_TIMESTAMP() FROM %s mps
|
||||
WHERE mps.wp_user_id IS NOT NULL
|
||||
WHERE mps.wp_user_id > 0
|
||||
', $wp_mailpoet_subscriber_segment_table, $wp_segment->id, $subscribers_table));
|
||||
}
|
||||
|
||||
private static function removeFromTrash() {
|
||||
$subscribers_table = Subscriber::$_table;
|
||||
Subscriber::raw_execute(sprintf('
|
||||
UPDATE %s
|
||||
UPDATE %s
|
||||
SET deleted_at = NULL
|
||||
WHERE %s.wp_user_id IS NOT NULL
|
||||
', $subscribers_table, $subscribers_table));
|
||||
@ -175,13 +175,13 @@ class WP {
|
||||
// e.g. if wp users were deleted directly from the database
|
||||
global $wpdb;
|
||||
|
||||
Subscriber::table_alias('wpms')
|
||||
->leftOuterJoin($wpdb->prefix . 'users', array('wpms.wp_user_id', '=', 'wu.id'), 'wu')
|
||||
$wp_segment = Segment::getWPSegment();
|
||||
|
||||
$wp_segment->subscribers()
|
||||
->leftOuterJoin($wpdb->users, array(MP_SUBSCRIBERS_TABLE . '.wp_user_id', '=', 'wu.id'), 'wu')
|
||||
->whereNull('wu.id')
|
||||
->findResultSet()
|
||||
->set('wp_user_id', null)
|
||||
->delete();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
use MailPoet\Analytics\Reporter;
|
||||
@ -7,11 +8,6 @@ use MailPoet\Analytics\Analytics as AnalyticsGenerator;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Analytics extends \Twig_Extension {
|
||||
|
||||
public function getName() {
|
||||
return 'analytics';
|
||||
}
|
||||
|
||||
public function getFunctions() {
|
||||
$analytics = new AnalyticsGenerator(new Reporter());
|
||||
return array(
|
||||
|
@ -1,25 +1,16 @@
|
||||
<?php
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
use MailPoet\Config\Env;
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Assets extends \Twig_Extension implements \Twig_Extension_GlobalsInterface {
|
||||
class Assets extends \Twig_Extension {
|
||||
private $_globals;
|
||||
|
||||
function __construct($globals) {
|
||||
$this->_globals = $globals;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return 'assets';
|
||||
}
|
||||
|
||||
function getGlobals() {
|
||||
return $this->_globals;
|
||||
}
|
||||
|
||||
function getFunctions() {
|
||||
return array(
|
||||
new \Twig_SimpleFunction(
|
||||
|
@ -7,11 +7,6 @@ use MailPoet\Config\ServicesChecker;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Functions extends \Twig_Extension {
|
||||
|
||||
function getName() {
|
||||
return 'functions';
|
||||
}
|
||||
|
||||
function getFunctions() {
|
||||
return array(
|
||||
new \Twig_SimpleFunction(
|
||||
@ -173,4 +168,4 @@ class Functions extends \Twig_Extension {
|
||||
function isRtl() {
|
||||
return is_rtl();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Handlebars extends \Twig_Extension {
|
||||
|
||||
public function getName() {
|
||||
return 'handlebars';
|
||||
}
|
||||
|
||||
public function getFunctions() {
|
||||
return array(
|
||||
new \Twig_SimpleFunction(
|
||||
'partial',
|
||||
array($this, 'generatePartial'),
|
||||
array(
|
||||
$this,
|
||||
'generatePartial'
|
||||
),
|
||||
array(
|
||||
'needs_environment' => true,
|
||||
'needs_context' => true,
|
||||
'is_safe' => array('all'))
|
||||
'needs_context' => true,
|
||||
'is_safe' => array('all')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -41,23 +41,28 @@ class Handlebars extends \Twig_Extension {
|
||||
return;
|
||||
}
|
||||
|
||||
$output = array();
|
||||
$rendered_template = twig_include($env, $context, $file);
|
||||
|
||||
$output[] = '<script id="'.$id.'" type="text/x-handlebars-template">';
|
||||
$output[] = twig_include($env, $context, $file);
|
||||
$output[] = '</script>';
|
||||
$output = <<<EOL
|
||||
<script id="$id" type="text/x-handlebars-template">
|
||||
$rendered_template
|
||||
</script>
|
||||
EOL;
|
||||
|
||||
if($alias !== null) {
|
||||
$output[] = '<script type="text/javascript">';
|
||||
$output[] = 'jQuery(function($) {';
|
||||
$output[] = '$(function() {';
|
||||
$output[] = ' Handlebars.registerPartial(
|
||||
"'.$alias.'",
|
||||
jQuery("#'.$id.'").html());';
|
||||
$output[] = '});';
|
||||
$output[] = '});';
|
||||
$output[] = '</script>';
|
||||
$output .= <<<EOL
|
||||
<script type="text/javascript">
|
||||
jQuery(function($) {
|
||||
$(function() {
|
||||
Handlebars.registerPartial(
|
||||
'$alias',
|
||||
jQuery('#$id').html()
|
||||
);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
EOL;
|
||||
}
|
||||
return join("\n", $output);
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -1,14 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Helpscout extends \Twig_Extension {
|
||||
|
||||
public function getName() {
|
||||
return 'helpscout';
|
||||
}
|
||||
|
||||
public function getFunctions() {
|
||||
return array(
|
||||
new \Twig_SimpleFunction(
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -12,10 +13,6 @@ class I18n extends \Twig_Extension {
|
||||
$this->_text_domain = $text_domain;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return 'i18n';
|
||||
}
|
||||
|
||||
function getFunctions() {
|
||||
// twig custom functions
|
||||
$twig_functions = array();
|
||||
|
@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
/*
|
||||
* Plugin Name: MailPoet 3 (new)
|
||||
* Version: 3.0.0-rc.2.0.3
|
||||
* Version: 3.0.0
|
||||
* 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.3',
|
||||
'version' => '3.0.0',
|
||||
'filename' => __FILE__,
|
||||
'path' => dirname(__FILE__),
|
||||
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
||||
|
63
readme.txt
63
readme.txt
@ -1,42 +1,53 @@
|
||||
=== MailPoet 3 (new) ===
|
||||
=== MailPoet 3 (New) ===
|
||||
Contributors: mailpoet, wysija
|
||||
Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
|
||||
Requires at least: 4.6
|
||||
Tested up to: 4.8
|
||||
Requires PHP: 5.3
|
||||
Stable tag: 3.0.0-rc.2.0.3
|
||||
Stable tag: 3.0.0
|
||||
License: GPLv3
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Create and send beautiful emails and newsletters from WordPress.
|
||||
|
||||
== Description ==
|
||||
|
||||
This is the release candidate of our completely new email newsletter plugin.
|
||||
The new MailPoet is here! With our new free sending plan, send unlimited emails to up to 2,000 subscribers. All without ever leaving WordPress.
|
||||
|
||||
= What's new? =
|
||||
= What's inside? =
|
||||
|
||||
* New designer
|
||||
* Responsive templates
|
||||
* Send with MailPoet (optional)
|
||||
* New designer with responsive templates
|
||||
* Send your emails with MailPoet’s Sending Service (optional)
|
||||
* Improved user experience
|
||||
* Easier configuration
|
||||
* Easy configuration
|
||||
* Solid reliability
|
||||
* Import subscribers, lists, forms and settings from old MailPoet
|
||||
* Weekly releases
|
||||
|
||||
= See it in action. =
|
||||
[Test the demo](http://demo3.mailpoet.com/launch/) or [see the 2 min. video](https://vimeo.com/223581490)
|
||||
[vimeo https://vimeo.com/223581490]
|
||||
|
||||
= What is a release candidate? =
|
||||
= Before you install =
|
||||
|
||||
MailPoet version 3 is considered production ready and will soon replace version 2 officially. It's fully featured, stable and supported. We only expect minor issues. Further notes:
|
||||
Take note:
|
||||
* Not optimized for right-to-left (RTL) languages yet
|
||||
* Multisite works, but is not officially supported
|
||||
* Please check the translations in your language
|
||||
* Review [our minimum requirements](http://beta.docs.mailpoet.com/article/152-minimum-requirements-for-mailpoet-3)
|
||||
|
||||
* Weekly releases with bug fixes and improvements
|
||||
* Report bugs directly from the user interface
|
||||
* Not optimized for right-to-left (RTL) languages, but it works
|
||||
* Multisite works but is not officially supported
|
||||
= What about the Premium? =
|
||||
|
||||
= Premium version available =
|
||||
MailPoet is fully featured in its free version and works up until you have 2000 subscribers.
|
||||
|
||||
[Get in touch](https://www.mailpoet.com/support/sales-pre-sales-questions/) if you are an existing customer and you want to switch.
|
||||
The Premium version adds the following features:
|
||||
* for each newsletter, see which subscribers opened it and which links they clicked
|
||||
* ability to send Welcome Emails automatically; i.e. "Welcome to my Newsletter” autoresponders or multi-email courses
|
||||
* removes the small MailPoet logo in the footer of your emails
|
||||
* same day support (Monday to Friday)
|
||||
* send to over 2000 subscribers with your own sending method
|
||||
* see the [short video summary on the Premium](http://beta.docs.mailpoet.com/article/208-video-overview-of-mailpoet-premium)
|
||||
|
||||
Plus: if you sign up to one of our sending plans, you’ll get all of these fancy features for free. Visit the Premium page inside the plugin for more info.
|
||||
|
||||
= Translations =
|
||||
|
||||
@ -50,8 +61,15 @@ MailPoet version 3 is considered production ready and will soon replace version
|
||||
* Russian
|
||||
* Japanese
|
||||
* Persian (IR)
|
||||
* Norwegian
|
||||
* Swedish
|
||||
* Turkish
|
||||
|
||||
We welcome translators to translate directly on [our Transifex project](https://www.transifex.com/wysija/mp3/). Please note that any translations submitted via the "Translating WordPress" web site will not work!
|
||||
We welcome experienced translators to translate directly on [our Transifex project](https://www.transifex.com/wysija/mp3/). Please note that any translations submitted via the "Translating WordPress" web site will not work.
|
||||
|
||||
= Security =
|
||||
|
||||
[Security audits are made by LogicalTrust](https://logicaltrust.net/en/), an independent third party.
|
||||
|
||||
== Installation ==
|
||||
|
||||
@ -60,7 +78,7 @@ There are 3 ways to install this plugin:
|
||||
= 1. The super easy way =
|
||||
1. In your WordPress dashboard, navigate to Plugins > Add New
|
||||
1. Search for `MailPoet`
|
||||
1. Click on "install now" under "MailPoet 3 – Beta Version"
|
||||
1. Click on "install now"
|
||||
1. Activate the plugin
|
||||
1. A new `MailPoet` menu will appear in your WordPress dashboard
|
||||
|
||||
@ -82,7 +100,7 @@ There are 3 ways to install this plugin:
|
||||
|
||||
= Need help? =
|
||||
|
||||
Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You can write to us on the forums too.
|
||||
Stop by our [support site](https://www.mailpoet.com/support).
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
@ -94,6 +112,11 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.0.0 - 2017-09-20 =
|
||||
* Official launch of the new MailPoet. :)
|
||||
* Improved: MailPoet 3 now works with other plugins that use a supported version of Twig templating engine. Thanks @supsysticcom;
|
||||
* Added: we now offer a free sending plan for 2000 subscribers or less. Thx MailPoet!
|
||||
|
||||
= 3.0.0-rc.2.0.3 - 2017-09-12 =
|
||||
* Added: hook to override default cron URL. Thanks Fred;
|
||||
* Improved: WordPress user sync optimized for large membership sites; Thanks Nagui and @deltafactory!
|
||||
|
2
tasks/makepot/node_modules/grunt-wp-i18n/vendor/wp-i18n-tools/extract.php
generated
vendored
2
tasks/makepot/node_modules/grunt-wp-i18n/vendor/wp-i18n-tools/extract.php
generated
vendored
@ -289,7 +289,7 @@ class StringExtractor {
|
||||
$arguments = array();
|
||||
foreach($arguments_matches[0] as $argument) {
|
||||
// Remove surrounding quotes of the same type from argument strings
|
||||
$arguments[] = preg_replace("/^(('|\")+)(.*)\\1$/", "\\3", $argument);
|
||||
$arguments[] = preg_replace("/^(('|\")+)(.*)\\1$/", "\\3", stripslashes($argument));
|
||||
}
|
||||
|
||||
$call = array(
|
||||
|
@ -99,7 +99,7 @@ class APITest extends \MailPoetTest {
|
||||
}
|
||||
}
|
||||
|
||||
function testItSubscriberSubscriberToMultupleLists() {
|
||||
function testItSubscribesSubscriberToMultupleLists() {
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->hydrate(Fixtures::get('subscriber_template'));
|
||||
$subscriber->save();
|
||||
@ -111,7 +111,7 @@ class APITest extends \MailPoetTest {
|
||||
);
|
||||
$result = API::MP(self::VERSION)->subscribeToLists($subscriber->id, array($segment->id));
|
||||
expect($result['id'])->equals($subscriber->id);
|
||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
||||
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||
}
|
||||
|
||||
function testItSubscribesSubscriberToSingleList() {
|
||||
@ -127,7 +127,7 @@ class APITest extends \MailPoetTest {
|
||||
$result = API::MP(self::VERSION)->subscribeToList($subscriber->id, $segment->id);
|
||||
expect($result['id'])->equals($subscriber->id);
|
||||
expect($result['subscriptions'])->notEmpty();
|
||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
||||
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||
}
|
||||
|
||||
function testItSubscribesSubscriberWithEmailIdentifier() {
|
||||
@ -143,7 +143,7 @@ class APITest extends \MailPoetTest {
|
||||
$result = API::MP(self::VERSION)->subscribeToList($subscriber->email, $segment->id);
|
||||
expect($result['id'])->equals($subscriber->id);
|
||||
expect($result['subscriptions'])->notEmpty();
|
||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
||||
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||
}
|
||||
|
||||
function testItGetsSegments() {
|
||||
@ -242,7 +242,7 @@ class APITest extends \MailPoetTest {
|
||||
$result = API::MP(self::VERSION)->addSubscriber($subscriber, array($segment->id));
|
||||
expect($result['id'])->greaterThan(0);
|
||||
expect($result['email'])->equals($subscriber['email']);
|
||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
||||
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||
}
|
||||
|
||||
function testItSchedulesWelcomeNotificationByDefaultAfterAddingSubscriber() {
|
||||
@ -325,4 +325,4 @@ class APITest extends \MailPoetTest {
|
||||
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||
\ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
<?php
|
||||
namespace MailPoet\Test\Config;
|
||||
|
||||
use MailPoet\Config\Hooks;
|
||||
|
||||
class HooksTest extends \MailPoetTest {
|
||||
function testItHooksSchedulerToMultiplePostTypes() {
|
||||
$hooks = new Hooks();
|
||||
$hooks->setupPostNotifications();
|
||||
$post_types = get_post_types();
|
||||
foreach($post_types as $post_type) {
|
||||
expect(has_filter('publish_' . $post_type, '\MailPoet\Newsletter\Scheduler\Scheduler::schedulePostNotification'))->notEmpty();
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace MailPoet\Test\Cron;
|
||||
|
||||
use AspectMock\Test as Mock;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
class CronHelperTest extends \MailPoetTest {
|
||||
function _before() {
|
||||
@ -14,7 +14,7 @@ class CronHelperTest extends \MailPoetTest {
|
||||
function testItDefinesConstants() {
|
||||
expect(CronHelper::DAEMON_EXECUTION_LIMIT)->equals(20);
|
||||
expect(CronHelper::DAEMON_EXECUTION_TIMEOUT)->equals(35);
|
||||
expect(CronHelper::DAEMON_REQUEST_TIMEOUT)->equals(2);
|
||||
expect(CronHelper::DAEMON_REQUEST_TIMEOUT)->equals(5);
|
||||
expect(CronHelper::DAEMON_SETTING)->equals('cron_daemon');
|
||||
}
|
||||
|
||||
@ -74,38 +74,30 @@ class CronHelperTest extends \MailPoetTest {
|
||||
|
||||
function testItCreatesRandomToken() {
|
||||
// random token is a string of 5 characters
|
||||
$token1 = CronHelper::createToken();
|
||||
$token2 = CronHelper::createToken();
|
||||
$token1 = CronHelper::createToken();
|
||||
$token2 = CronHelper::createToken();
|
||||
expect($token1)->notEquals($token2);
|
||||
expect(is_string($token1))->true();
|
||||
expect(strlen($token1))->equals(5);
|
||||
}
|
||||
|
||||
function testItGetsSiteUrl() {
|
||||
// 1. do nothing when the url is manually overridden via a hook
|
||||
$filter = function() {
|
||||
return 'custom_url';
|
||||
};
|
||||
add_filter('mailpoet_cron_request_url', $filter);
|
||||
expect(CronHelper::getSiteUrl())->equals('custom_url');
|
||||
remove_filter('mailpoet_cron_request_url', $filter);
|
||||
|
||||
// 2. do nothing when the url does not contain port
|
||||
// 1. do nothing when the url does not contain port
|
||||
$site_url = 'http://example.com';
|
||||
expect(CronHelper::getSiteUrl($site_url))->equals($site_url);
|
||||
|
||||
if(getenv('WP_TEST_ENABLE_NETWORK_TESTS') !== 'true') return;
|
||||
|
||||
// 3. when url contains valid port, try connecting to it
|
||||
// 2. when url contains valid port, try connecting to it
|
||||
$site_url = 'http://example.com:80';
|
||||
expect(CronHelper::getSiteUrl($site_url))->equals($site_url);
|
||||
|
||||
// 4. when url contains invalid port, try connecting to it. when connection fails,
|
||||
// 3. when url contains invalid port, try connecting to it. when connection fails,
|
||||
// another attempt will be made to connect to the standard port derived from URL schema
|
||||
$site_url = 'http://example.com:8080';
|
||||
expect(CronHelper::getSiteUrl($site_url))->equals('http://example.com');
|
||||
|
||||
// 5. when connection can't be established, exception should be thrown
|
||||
// 4. when connection can't be established, exception should be thrown
|
||||
$site_url = 'https://invalid:80';
|
||||
try {
|
||||
CronHelper::getSiteUrl($site_url);
|
||||
@ -126,12 +118,49 @@ class CronHelperTest extends \MailPoetTest {
|
||||
}
|
||||
}
|
||||
|
||||
function testItAllowsSettingCustomCronUrl() {
|
||||
$filter = function($url) {
|
||||
expect($url)->contains('&endpoint=cron');
|
||||
return 'http://custom_cron_url';
|
||||
};
|
||||
add_filter('mailpoet_cron_request_url', $filter);
|
||||
expect(CronHelper::getCronUrl('sample_action'))->equals('http://custom_cron_url');
|
||||
remove_filter('mailpoet_cron_request_url', $filter);
|
||||
}
|
||||
|
||||
function testItAllowsSettingCustomCronRequestArguments() {
|
||||
$request_args = array(
|
||||
'blocking' => 'custom_blocking',
|
||||
'sslverify' => 'custom_ssl_verify',
|
||||
'timeout' => 'custom_timeout',
|
||||
'user-agent' => 'custom_user_agent'
|
||||
);
|
||||
$filter = function($args) use ($request_args) {
|
||||
expect($args)->notEmpty();
|
||||
return $request_args;
|
||||
};
|
||||
add_filter('mailpoet_cron_request_args', $filter);
|
||||
Mock::func('MailPoet\Cron', 'wp_remote_get', function($url, $args) {
|
||||
return $args;
|
||||
});
|
||||
expect(CronHelper::queryCronUrl('test'))->equals($request_args);
|
||||
remove_filter('mailpoet_cron_request_args', $filter);
|
||||
}
|
||||
|
||||
function testItReturnsErrorMessageAsPingResponseWhenCronUrlCannotBeAccessed() {
|
||||
Mock::double('MailPoet\Cron\CronHelper', array(
|
||||
'getSiteUrl' => false
|
||||
));
|
||||
expect(CronHelper::pingDaemon())->equals('A valid URL was not provided.');
|
||||
}
|
||||
|
||||
function testItPingsDaemon() {
|
||||
if(getenv('WP_TEST_ENABLE_NETWORK_TESTS') !== 'true') return;
|
||||
expect(CronHelper::pingDaemon())->equals('pong');
|
||||
}
|
||||
|
||||
function _after() {
|
||||
Mock::clean();
|
||||
\ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||
}
|
||||
}
|
@ -7,10 +7,6 @@ use MailPoet\Cron\Daemon;
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
class DaemonTest extends \MailPoetTest {
|
||||
function testItDefinesConstants() {
|
||||
expect(Daemon::REQUEST_TIMEOUT)->equals(5);
|
||||
}
|
||||
|
||||
function testItConstructs() {
|
||||
Setting::setValue(
|
||||
CronHelper::DAEMON_SETTING,
|
||||
|
@ -4,6 +4,7 @@ namespace MailPoet\Test\Helpscout;
|
||||
use MailPoet\Helpscout\Beacon;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
class BeaconTest extends \MailPoetTest {
|
||||
function _before() {
|
||||
@ -130,4 +131,10 @@ class BeaconTest extends \MailPoetTest {
|
||||
(defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function testItReturnsPremiumKey() {
|
||||
expect($this->beacon_data['MailPoet Premium/MSS key'])->equals(
|
||||
Setting::getValue(Bridge::PREMIUM_KEY_SETTING_NAME) ?: Setting::getValue(Bridge::API_KEY_SETTING_NAME)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ require_once(ABSPATH . 'wp-admin/includes/user.php');
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Segments\WP;
|
||||
|
||||
class WPTest extends \MailPoetTest {
|
||||
@ -67,6 +68,15 @@ class WPTest extends \MailPoetTest {
|
||||
expect($subscriber->first_name)->equals('First name');
|
||||
}
|
||||
|
||||
function testItSynchronizeFirstNamesFromMetaNotDisplayName() {
|
||||
$id = $this->insertUser();
|
||||
update_user_meta($id, 'first_name', 'First name');
|
||||
$this->updateWPUserDisplayName($id, 'display_name');
|
||||
WP::synchronizeUsers();
|
||||
$subscriber = Subscriber::where('wp_user_id', $id)->findOne();
|
||||
expect($subscriber->first_name)->equals('First name');
|
||||
}
|
||||
|
||||
function testItSynchronizeSegment() {
|
||||
$this->insertUser();
|
||||
$this->insertUser();
|
||||
@ -108,6 +118,54 @@ class WPTest extends \MailPoetTest {
|
||||
expect($subscribers->count())->equals(1);
|
||||
}
|
||||
|
||||
function testItDoesntDeleteNonWPData() {
|
||||
$this->insertUser();
|
||||
// wp_user_id is null
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->hydrate(array(
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'John',
|
||||
'email' => 'user-sync-test' . rand() . '@example.com',
|
||||
));
|
||||
$subscriber->status = Subscriber::STATUS_UNCONFIRMED;
|
||||
$subscriber->save();
|
||||
// wp_user_id is zero
|
||||
$subscriber2 = Subscriber::create();
|
||||
$subscriber2->hydrate(array(
|
||||
'first_name' => 'Mike',
|
||||
'last_name' => 'Mike',
|
||||
'email' => 'user-sync-test2' . rand() . '@example.com',
|
||||
'wp_user_id' => 0,
|
||||
));
|
||||
$subscriber2->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$subscriber2->save();
|
||||
WP::synchronizeUsers();
|
||||
$subscribersCount = $this->getSubscribersCount();
|
||||
expect($subscribersCount)->equals(3);
|
||||
}
|
||||
|
||||
function testItRemovesSubscribersInWPSegmentWithoutWPId() {
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->hydrate(array(
|
||||
'first_name' => 'Mike',
|
||||
'last_name' => 'Mike',
|
||||
'email' => 'user-sync-test' . rand() . '@example.com',
|
||||
'wp_user_id' => null,
|
||||
));
|
||||
$subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$subscriber->save();
|
||||
$wp_segment = Segment::getWPSegment();
|
||||
$association = SubscriberSegment::create();
|
||||
$association->subscriber_id = $subscriber->id;
|
||||
$association->segment_id = $wp_segment->id;
|
||||
$association->save();
|
||||
$subscribersCount = $this->getSubscribersCount();
|
||||
expect($subscribersCount)->equals(1);
|
||||
WP::synchronizeUsers();
|
||||
$subscribersCount = $this->getSubscribersCount(0);
|
||||
expect($subscribersCount)->equals(0);
|
||||
}
|
||||
|
||||
function _before() {
|
||||
$this->cleanData();
|
||||
}
|
||||
@ -118,18 +176,37 @@ class WPTest extends \MailPoetTest {
|
||||
|
||||
private function cleanData() {
|
||||
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||
\ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table);
|
||||
global $wpdb;
|
||||
$db = \ORM::getDb();
|
||||
$db->exec(sprintf('
|
||||
DELETE FROM
|
||||
%susers
|
||||
%s
|
||||
WHERE
|
||||
subscriber_id IN (select id from %s WHERE email LIKE "user-sync-test%%")
|
||||
', SubscriberSegment::$_table, Subscriber::$_table));
|
||||
$db->exec(sprintf('
|
||||
DELETE FROM
|
||||
%s
|
||||
WHERE
|
||||
user_id IN (select id from %s WHERE user_email LIKE "user-sync-test%%")
|
||||
', $wpdb->usermeta, $wpdb->users));
|
||||
$db->exec(sprintf('
|
||||
DELETE FROM
|
||||
%s
|
||||
WHERE
|
||||
user_email LIKE "user-sync-test%%"
|
||||
', $wpdb->prefix));
|
||||
', $wpdb->users));
|
||||
$db->exec(sprintf('
|
||||
DELETE FROM
|
||||
%s
|
||||
WHERE
|
||||
email LIKE "user-sync-test%%"
|
||||
', Subscriber::$_table));
|
||||
}
|
||||
|
||||
private function getSubscribersCount() {
|
||||
return Subscriber::whereIn("wp_user_id", $this->userIds)->count();
|
||||
private function getSubscribersCount($a = null) {
|
||||
return Subscriber::whereLike("email", "user-sync-test%")->count();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,14 +220,14 @@ class WPTest extends \MailPoetTest {
|
||||
global $wpdb;
|
||||
$db = \ORM::getDb();
|
||||
$db->exec(sprintf('
|
||||
INSERT INTO
|
||||
%susers(user_login, user_email, user_registered)
|
||||
VALUES
|
||||
INSERT INTO
|
||||
%s (user_login, user_email, user_registered)
|
||||
VALUES
|
||||
(
|
||||
CONCAT("user-sync-test", rand()),
|
||||
CONCAT("user", rand(), "@example.com"),
|
||||
CONCAT("user-sync-test", rand()),
|
||||
CONCAT("user-sync-test", rand(), "@example.com"),
|
||||
"2017-01-02 12:31:12"
|
||||
)', $wpdb->prefix));
|
||||
)', $wpdb->users));
|
||||
$id = $db->lastInsertId();
|
||||
$this->userIds[] = $id;
|
||||
return $id;
|
||||
@ -161,11 +238,11 @@ class WPTest extends \MailPoetTest {
|
||||
$db = \ORM::getDb();
|
||||
$db->exec(sprintf('
|
||||
UPDATE
|
||||
%susers
|
||||
%s
|
||||
SET user_email = "%s"
|
||||
WHERE
|
||||
id = %s
|
||||
', $wpdb->prefix, $email, $id));
|
||||
', $wpdb->users, $email, $id));
|
||||
}
|
||||
|
||||
private function updateWPUserDisplayName($id, $name) {
|
||||
@ -173,11 +250,11 @@ class WPTest extends \MailPoetTest {
|
||||
$db = \ORM::getDb();
|
||||
$db->exec(sprintf('
|
||||
UPDATE
|
||||
%susers
|
||||
%s
|
||||
SET display_name = "%s"
|
||||
WHERE
|
||||
id = %s
|
||||
', $wpdb->prefix, $name, $id));
|
||||
', $wpdb->users, $name, $id));
|
||||
}
|
||||
|
||||
private function deleteWPUser($id) {
|
||||
@ -185,10 +262,10 @@ class WPTest extends \MailPoetTest {
|
||||
$db = \ORM::getDb();
|
||||
$db->exec(sprintf('
|
||||
DELETE FROM
|
||||
%susers
|
||||
%s
|
||||
WHERE
|
||||
id = %s
|
||||
', $wpdb->prefix, $id));
|
||||
', $wpdb->users, $id));
|
||||
}
|
||||
|
||||
}
|
@ -61,12 +61,7 @@
|
||||
>
|
||||
<div class="mailpoet_sending_method_description">
|
||||
<h3>
|
||||
<img
|
||||
src="<%= assets_url %>/img/mailpoet_logo.png"
|
||||
alt="MailPoet"
|
||||
width="137"
|
||||
height="54"
|
||||
/>
|
||||
<%= __('MailPoet Sending Service') %>
|
||||
</h3>
|
||||
|
||||
<p
|
||||
@ -83,19 +78,26 @@
|
||||
id="mailpoet_sending_method_inactive_text"
|
||||
>
|
||||
<strong><%= __("Solve all of your sending problems!") %></strong>
|
||||
<br />
|
||||
<%= __("Let MailPoet send your emails and get the Premium features for as little as 10 dollars or euros per month.") %>
|
||||
|
||||
<ul class="sending-method-benefits mailpoet_success">
|
||||
<li class="mailpoet_success_item"><%= __('Reach the inbox, not the spam box.') %>
|
||||
<li class="mailpoet_success_item"><%= __('Send emails up to 20 times faster than other sending methods.') %>
|
||||
<li class="mailpoet_success_item"><%= __('SPF & DKIM signatures are already set up! No configuration required.') %>
|
||||
<li class="mailpoet_success_item"><%= __('Super fast: send up to 50,000 emails per hour.') %>
|
||||
<li class="mailpoet_success_item"><%= __('All emails are signed with SPF & DKIM.') %>
|
||||
<li class="mailpoet_success_item"><%= __('Automatically remove invalid and bounced addresses (bounce handling) to keep your lists clean.') %>
|
||||
<li class="mailpoet_success_item"><%= __('Configuration is dead-simple: simply enter a key to activate the sending service.') %>
|
||||
<li class="mailpoet_success_item"><strong><%= __('Coming soon:')%></strong> <%= __('MailPoet will send your WordPress site and account emails, too!') %>
|
||||
<li class="mailpoet_success_item"><strong><%= __('Plus:')%></strong> <%= __('get the Premium features for free.') %>
|
||||
</li>
|
||||
</ul>
|
||||
<a
|
||||
href="<%= admin_url('admin.php?page=mailpoet-premium') %>"
|
||||
class="button button-primary"
|
||||
target="_blank"
|
||||
><%= __('Find out more') %></a>
|
||||
><%= __('Find out more about our monthly plans') %></a>
|
||||
|
||||
<a href="https://www.mailpoet.com/free-plan/" class="button button-primary sending-free-plan-button" target="_blank">
|
||||
<strong><%= __('new!') %></strong> <%= __('Try it for free (for up to 2,000 subscribers)') %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mailpoet_status">
|
||||
@ -118,14 +120,17 @@
|
||||
<div class="mailpoet_sending_method_description">
|
||||
<h3><%= __('Other') %></h3>
|
||||
<div class="mailpoet_description">
|
||||
<strong><%= __('Send with your website or third party') %></strong>
|
||||
<br />
|
||||
<%= __('Choose to send emails through your website (not recommended) or a third party sender.') %>
|
||||
<strong><%= __('Send emails via your host (not recommended!) or via a third-party sender.') %></strong>
|
||||
<ul class="sending-method-benefits mailpoet_error">
|
||||
<li class="mailpoet_error_item"><%= __("You'll probably end up in spam.") %>
|
||||
<li class="mailpoet_error_item"><%= __('Sending speed is limited by your web host.') %>
|
||||
<li class="mailpoet_error_item"><%= __('Manual configuration of SPF and DKIM required.') %>
|
||||
<li class="mailpoet_error_item"><%= __('Bounce handling is available, but only with an extra add-on.') %>
|
||||
<li class="mailpoet_error_item"><%= __("Unless you're a pro, you’ll probably end up in spam.") %>
|
||||
<li class="mailpoet_error_item"><%= __("Sending speed is limited by your host and/or your third-party (with a 2,000 per hour maximum).") %>
|
||||
<li class="mailpoet_error_item"><%= __("Manual configuration of SPF and DKIM required.") %>
|
||||
<li class="mailpoet_error_item"><%=
|
||||
__("Bounce handling is available, but only with an extra [link]add-on[/link].")
|
||||
|replaceLinkTags('https://wordpress.org/plugins/bounce-handler-mailpoet/', {'target' : '_blank'})
|
||||
|raw
|
||||
%>
|
||||
<li class="mailpoet_error_item"><%= __("You’ll need a separate plugin to send your WordPress site emails (optional).") %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<h1><%= __('Greetings, humans.') %></h1>
|
||||
|
||||
<p class="about-text"><%= __('Thanks for using MailPoet! We really appreciate all of your love, affection, [link]and (good) plugin reviews.[/link]')
|
||||
|replaceLinkTags('https://wordpress.org/support/plugin/wysija-newsletters/reviews/', {'target' : '_blank'})
|
||||
|replaceLinkTags('https://wordpress.org/support/plugin/mailpoet/reviews/', {'target' : '_blank'})
|
||||
|raw
|
||||
%>
|
||||
</p>
|
||||
@ -60,8 +60,18 @@
|
||||
<div class="feature-section one-col mailpoet_centered">
|
||||
<h2><%= __('Care to Give Your Opinion?') %></h2>
|
||||
|
||||
<script type="text/javascript" charset="utf-8" src="//secure.polldaddy.com/p/9801036.js"></script>
|
||||
<noscript><a href="//polldaddy.com/poll/9801036/">Should MailPoet include more default templates?</a></noscript>
|
||||
<div class="pd-embed" id="pd_1505214143"></div>
|
||||
<script type="text/javascript">
|
||||
var _polldaddy = [] || _polldaddy;
|
||||
_polldaddy.push( {
|
||||
type: "iframe",
|
||||
auto: "1",
|
||||
domain: "mailpoet.polldaddy.com/s/",
|
||||
id: "what-s-one-feature-that-s-missing-in-mailpoet",
|
||||
placeholder: "pd_1505214143"
|
||||
} );
|
||||
(function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/survey.js':'http://i0.poll.fm/survey.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-embed'));
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<h1><%= __('Greetings, humans.') %></h1>
|
||||
|
||||
<p class="about-text"><%= __('Thanks for using MailPoet! We really appreciate all of your love, affection, [link]and (good) plugin reviews.[/link]')
|
||||
|replaceLinkTags('https://wordpress.org/support/plugin/wysija-newsletters/reviews/', {'target' : '_blank'})
|
||||
|replaceLinkTags('https://wordpress.org/support/plugin/mailpoet/reviews/', {'target' : '_blank'})
|
||||
|raw
|
||||
%>
|
||||
</p>
|
||||
@ -17,9 +17,32 @@
|
||||
<a href="admin.php?page=mailpoet-update" class="nav-tab"><%= __("What's new") %></a>
|
||||
</h2>
|
||||
|
||||
<% set random = random(2) %>
|
||||
|
||||
<div <% if random != 0 %>style="display: none;"<% endif %>>
|
||||
<h2><%= __('Coming this Fall to a WordPress plugin page near you') %></h2>
|
||||
<p class="about-text mailpoet_centered mailpoet-top-text"><%= __('The highly-anticipated sequel to Dead Poets Society, Introduction to MailPoet will keep you on the edge of your seat.
|
||||
“Five out of five stars,” says Rafael Ehlers, MailPoet Support Manager.
|
||||
“A must-watch for aspiring email poets.”') %>
|
||||
</div>
|
||||
<div <% if random != 1 %>style="display: none;"<% endif %>>
|
||||
<h2><%= __('But first, watch this video') %></h2>
|
||||
<p class="about-text mailpoet_centered mailpoet-top-text"><%= __('Wait a second. Don’t click that big blue button just yet.
|
||||
Yeah, we’re talking to you. Before you do anything, you should really watch this video.
|
||||
It won’t change your life, but it will save you (and our support team) a ton of time.
|
||||
And what is life without time? So, maybe it is life-changing, after all…') %>
|
||||
</div>
|
||||
<div <% if random != 2 %>style="display: none;"<% endif %>>
|
||||
<h2><%= __('Explanatory videos are boring, we know') %></h2>
|
||||
<p class="about-text mailpoet_centered mailpoet-top-text"><%= __('But this video is really important!
|
||||
We promise. Over the course of three minutes, you’ll learn how to send your first newsletter,
|
||||
manage your lists, make billions of dollars and live happily ever after.
|
||||
That’s right – it’s that good. So get watching.') %>
|
||||
</div>
|
||||
|
||||
<div class="headline-feature feature-video">
|
||||
<div class="videoWrapper">
|
||||
<iframe width="1050" height="591" src="https://player.vimeo.com/video/184501111?title=0&byline=0&portrait=0" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
|
||||
<iframe width="1050" height="591" src="https://player.vimeo.com/video/229737424" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -28,13 +51,12 @@
|
||||
<div class="feature-section two-col">
|
||||
<h2><%= __('Want to Make MailPoet Even Better?') %></h2>
|
||||
<div class="col">
|
||||
<h3><%= __('We Need Your Feedback!') %></h3>
|
||||
<p><%= __('As a beta tester, you have a very important job: to tell us what you think about this new version. If you love it, tell us! If you hate it, let us know! Any and all feedback is useful.') %></p>
|
||||
<p><%= __('To get in touch with us, simply click on the blue circle in the bottom right corner of your screen. This button is visible on all MailPoet pages on your WordPress dashboard.') %> <img width="30" style="margin:0" src="<%= image_url('welcome_template/beacon.png') %>" alt="Beacon" /></p>
|
||||
<h3><%= __('Documentation Is One Click Away') %></h3>
|
||||
<p><%= __('Simply click on the blue circle in the bottom right corner of any of the MailPoet pages to access our documentation.') %> <em><%= __('Voilà!') %></em>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3><%= __('Sharing is Caring') %></h3>
|
||||
<p><%= __("By sharing your data <i>anonymously</i> with us, you can help us understand <i>how people use MailPoet</i> and <i>what sort of features they like and don't like</i>.") %> <a href="http://beta.docs.mailpoet.com/article/130-sharing-your-data-with-us" target="_blank"><%= __('Find out more') %> →</a>
|
||||
<p><%= __("By sharing your data <i>anonymously</i> with us, you can help us understand how people use MailPoet and what sort of features they like and don't like.") %> <a href="http://beta.docs.mailpoet.com/article/130-sharing-your-data-with-us" target="_blank"><%= __('Find out more') %> →</a>
|
||||
<br><br>
|
||||
<label>
|
||||
<input type="checkbox" id="mailpoet_analytics_enabled" value="1"
|
||||
@ -58,7 +80,7 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3><%= __("Learn the Ropes") %></h3>
|
||||
<p><%= __("New to MailPoet? Check out our brand new email course. Over the span of 3 weeks, we'll teach you how to create and send your first MailPoet email newsletter. Sign up below!") %></p>
|
||||
<p><%= __("New to MailPoet? Check out our brand new email course. Over the course of a week, we'll teach you how to create and send your first MailPoet email newsletter. Sign up below!") %></p>
|
||||
<p>
|
||||
<iframe width="100%" height="100%" scrolling="no" frameborder="0" src="http://newsletters.mailpoet.com?mailpoet_form_iframe=4" class="mailpoet_form_iframe" vspace="0" tabindex="0" onload="if(window['MailPoet']) MailPoet.Iframe.autoSize(this);" marginwidth="0" marginheight="0" hspace="0" allowtransparency="true"></iframe>
|
||||
</p>
|
||||
|
Reference in New Issue
Block a user