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
|
p.top-space-triple
|
||||||
margin-top: 3em
|
margin-top: 3em
|
||||||
|
|
||||||
|
p.mailpoet-top-text
|
||||||
|
margin-right: 0
|
||||||
|
@ -62,6 +62,15 @@
|
|||||||
margin-bottom: 2em
|
margin-bottom: 2em
|
||||||
margin-top: 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
|
.mailpoet_success_item::before
|
||||||
content '✔ '
|
content '✔ '
|
||||||
|
|
||||||
|
@ -285,6 +285,7 @@ define(
|
|||||||
}
|
}
|
||||||
return newField;
|
return newField;
|
||||||
});
|
});
|
||||||
|
const sendButtonOptions = this.getSendButtonOptions();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>{MailPoet.I18n.t('finalNewsletterStep')}</h1>
|
<h1>{MailPoet.I18n.t('finalNewsletterStep')}</h1>
|
||||||
@ -313,7 +314,7 @@ define(
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={ this.handleSend }
|
onClick={ this.handleSend }
|
||||||
value={MailPoet.I18n.t('send')}
|
value={MailPoet.I18n.t('send')}
|
||||||
{...this.getSendButtonOptions()}
|
{...sendButtonOptions}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,10 +331,12 @@ define(
|
|||||||
{MailPoet.I18n.t('goBackToDesign')}
|
{MailPoet.I18n.t('goBackToDesign')}
|
||||||
</a>.
|
</a>.
|
||||||
</p>
|
</p>
|
||||||
<HelpTooltip
|
{ !isPaused && sendButtonOptions['disabled'] && sendButtonOptions['disabled'] === 'disabled' && (
|
||||||
tooltip={MailPoet.I18n.t('helpTooltipSendEmail')}
|
<HelpTooltip
|
||||||
tooltipId="helpTooltipSendEmail"
|
tooltip={MailPoet.I18n.t('helpTooltipSendEmail')}
|
||||||
/>
|
tooltipId="helpTooltipSendEmail"
|
||||||
|
/>
|
||||||
|
) }
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -13,6 +13,7 @@ class RequirementsChecker {
|
|||||||
const TEST_XML_EXTENSION = 'XmlExtension';
|
const TEST_XML_EXTENSION = 'XmlExtension';
|
||||||
const TEST_ZIP_EXTENSION = 'ZipExtension';
|
const TEST_ZIP_EXTENSION = 'ZipExtension';
|
||||||
const TEST_VENDOR_SOURCE = 'VendorSource';
|
const TEST_VENDOR_SOURCE = 'VendorSource';
|
||||||
|
const TWIG_SUPPORTED_VERSIONS = '1.26.0-1.34.4';
|
||||||
|
|
||||||
public $display_error_notice;
|
public $display_error_notice;
|
||||||
public $vendor_classes = array(
|
public $vendor_classes = array(
|
||||||
@ -22,7 +23,6 @@ class RequirementsChecker {
|
|||||||
'\Twig_Loader_Filesystem',
|
'\Twig_Loader_Filesystem',
|
||||||
'\Twig_Lexer',
|
'\Twig_Lexer',
|
||||||
'\Twig_Extension',
|
'\Twig_Extension',
|
||||||
'\Twig_Extension_GlobalsInterface',
|
|
||||||
'\Twig_SimpleFunction',
|
'\Twig_SimpleFunction',
|
||||||
'\Swift_Mailer',
|
'\Swift_Mailer',
|
||||||
'\Swift_SmtpTransport',
|
'\Swift_SmtpTransport',
|
||||||
@ -141,13 +141,30 @@ class RequirementsChecker {
|
|||||||
$dependency_path
|
$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;
|
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) {
|
private function getDependencyPath($namespaced_class) {
|
||||||
try {
|
try {
|
||||||
$reflector = new \ReflectionClass($namespaced_class);
|
$reflector = new \ReflectionClass($namespaced_class);
|
||||||
@ -163,4 +180,4 @@ class RequirementsChecker {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ if(!defined('ABSPATH')) exit;
|
|||||||
class CronHelper {
|
class CronHelper {
|
||||||
const DAEMON_EXECUTION_LIMIT = 20; // seconds
|
const DAEMON_EXECUTION_LIMIT = 20; // seconds
|
||||||
const DAEMON_EXECUTION_TIMEOUT = 35; // seconds
|
const DAEMON_EXECUTION_TIMEOUT = 35; // seconds
|
||||||
const DAEMON_REQUEST_TIMEOUT = 2; // seconds
|
const DAEMON_REQUEST_TIMEOUT = 5; // seconds
|
||||||
const DAEMON_SETTING = 'cron_daemon';
|
const DAEMON_SETTING = 'cron_daemon';
|
||||||
|
|
||||||
static function createDaemon($token) {
|
static function createDaemon($token) {
|
||||||
@ -49,45 +49,53 @@ class CronHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static function pingDaemon() {
|
static function pingDaemon() {
|
||||||
$url = Router::buildRequest(
|
$url = self::getCronUrl(
|
||||||
CronDaemonEndpoint::ENDPOINT,
|
|
||||||
CronDaemonEndpoint::ACTION_PING_RESPONSE
|
CronDaemonEndpoint::ACTION_PING_RESPONSE
|
||||||
);
|
);
|
||||||
$url = str_replace(home_url(), self::getSiteUrl(), $url);
|
$result = self::queryCronUrl($url);
|
||||||
$args = array(
|
return (is_wp_error($result)) ?
|
||||||
'blocking' => true,
|
$result->get_error_message() :
|
||||||
'sslverify' => false,
|
wp_remote_retrieve_body($result);
|
||||||
'timeout' => self::DAEMON_REQUEST_TIMEOUT,
|
|
||||||
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
|
|
||||||
);
|
|
||||||
$result = wp_remote_get($url, $args);
|
|
||||||
return wp_remote_retrieve_body($result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static function accessDaemon($token, $timeout = self::DAEMON_REQUEST_TIMEOUT) {
|
static function accessDaemon($token) {
|
||||||
$data = array('token' => $token);
|
$data = array('token' => $token);
|
||||||
$url = Router::buildRequest(
|
$url = self::getCronUrl(
|
||||||
CronDaemonEndpoint::ENDPOINT,
|
|
||||||
CronDaemonEndpoint::ACTION_RUN,
|
CronDaemonEndpoint::ACTION_RUN,
|
||||||
$data
|
$data
|
||||||
);
|
);
|
||||||
$url = str_replace(home_url(), self::getSiteUrl(), $url);
|
$result = self::queryCronUrl($url);
|
||||||
$args = array(
|
|
||||||
'blocking' => true,
|
|
||||||
'sslverify' => false,
|
|
||||||
'timeout' => $timeout,
|
|
||||||
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
|
|
||||||
);
|
|
||||||
$result = wp_remote_get($url, $args);
|
|
||||||
return wp_remote_retrieve_body($result);
|
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) {
|
static function getSiteUrl($site_url = false) {
|
||||||
// additional check for some sites running inside a virtual machine or behind
|
// 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)
|
// 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();
|
$site_url = ($site_url) ? $site_url : home_url();
|
||||||
$parsed_url = parse_url($site_url);
|
$parsed_url = parse_url($site_url);
|
||||||
$scheme = '';
|
$scheme = '';
|
||||||
|
@ -13,7 +13,6 @@ class Daemon {
|
|||||||
public $daemon;
|
public $daemon;
|
||||||
public $request_data;
|
public $request_data;
|
||||||
public $timer;
|
public $timer;
|
||||||
const REQUEST_TIMEOUT = 5; // seconds
|
|
||||||
|
|
||||||
function __construct($request_data = false) {
|
function __construct($request_data = false) {
|
||||||
$this->request_data = $request_data;
|
$this->request_data = $request_data;
|
||||||
@ -100,7 +99,7 @@ class Daemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function callSelf() {
|
function callSelf() {
|
||||||
CronHelper::accessDaemon($this->token, self::REQUEST_TIMEOUT);
|
CronHelper::accessDaemon($this->token);
|
||||||
return $this->terminateRequest();
|
return $this->terminateRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ use MailPoet\Models\Subscriber;
|
|||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
use MailPoet\Router\Endpoints\CronDaemon;
|
use MailPoet\Router\Endpoints\CronDaemon;
|
||||||
use MailPoet\Router\Router;
|
use MailPoet\Router\Router;
|
||||||
|
use MailPoet\Services\Bridge;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
@ -20,12 +21,14 @@ class Beacon {
|
|||||||
CronDaemon::ACTION_PING
|
CronDaemon::ACTION_PING
|
||||||
);
|
);
|
||||||
$cron_ping_url = str_replace(home_url(), CronHelper::getSiteUrl(), $cron_ping_url);
|
$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(
|
return array(
|
||||||
'name' => $current_user->display_name,
|
'name' => $current_user->display_name,
|
||||||
'email' => $current_user->user_email,
|
'email' => $current_user->user_email,
|
||||||
'PHP version' => PHP_VERSION,
|
'PHP version' => PHP_VERSION,
|
||||||
'MailPoet Free version' => MAILPOET_VERSION,
|
'MailPoet Free version' => MAILPOET_VERSION,
|
||||||
'MailPoet Premium version' => (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A',
|
'MailPoet Premium version' => (defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A',
|
||||||
|
'MailPoet Premium/MSS key' => $premium_key,
|
||||||
'WordPress version' => get_bloginfo('version'),
|
'WordPress version' => get_bloginfo('version'),
|
||||||
'Database version' => $db_version,
|
'Database version' => $db_version,
|
||||||
'Web server' => (!empty($_SERVER["SERVER_SOFTWARE"])) ? $_SERVER["SERVER_SOFTWARE"] : 'N/A',
|
'Web server' => (!empty($_SERVER["SERVER_SOFTWARE"])) ? $_SERVER["SERVER_SOFTWARE"] : 'N/A',
|
||||||
|
@ -97,10 +97,10 @@ class WP {
|
|||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
UPDATE IGNORE %s
|
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
|
SET email = user_email
|
||||||
WHERE %s.wp_user_id IS NOT NULL
|
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() {
|
private static function insertSubscribers() {
|
||||||
@ -108,10 +108,10 @@ class WP {
|
|||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
INSERT IGNORE INTO %s(wp_user_id, email, status, created_at)
|
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
|
LEFT JOIN %s mps ON wu.id = mps.wp_user_id
|
||||||
WHERE mps.wp_user_id IS NULL
|
WHERE mps.wp_user_id IS NULL
|
||||||
', $subscribers_table, $wpdb->prefix, $subscribers_table));
|
', $subscribers_table, $wpdb->users, $subscribers_table));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function updateFirstNames() {
|
private static function updateFirstNames() {
|
||||||
@ -119,11 +119,11 @@ class WP {
|
|||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
UPDATE %s
|
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
|
SET first_name = meta_value
|
||||||
WHERE %s.first_name = ""
|
WHERE %s.first_name = ""
|
||||||
AND %s.wp_user_id IS NOT NULL
|
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() {
|
private static function updateLastNames() {
|
||||||
@ -131,11 +131,11 @@ class WP {
|
|||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
UPDATE %s
|
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
|
SET last_name = meta_value
|
||||||
WHERE %s.last_name = ""
|
WHERE %s.last_name = ""
|
||||||
AND %s.wp_user_id IS NOT NULL
|
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() {
|
private static function updateFristNameIfMissing() {
|
||||||
@ -143,11 +143,11 @@ class WP {
|
|||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
UPDATE %s
|
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
|
SET first_name = display_name
|
||||||
WHERE %s.first_name = ""
|
WHERE %s.first_name = ""
|
||||||
AND %s.wp_user_id IS NOT NULL
|
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() {
|
private static function insertUsersToSegment() {
|
||||||
@ -157,14 +157,14 @@ class WP {
|
|||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
INSERT IGNORE INTO %s(subscriber_id, segment_id, created_at)
|
INSERT IGNORE INTO %s(subscriber_id, segment_id, created_at)
|
||||||
SELECT mps.id, "%s", CURRENT_TIMESTAMP() FROM %s mps
|
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));
|
', $wp_mailpoet_subscriber_segment_table, $wp_segment->id, $subscribers_table));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function removeFromTrash() {
|
private static function removeFromTrash() {
|
||||||
$subscribers_table = Subscriber::$_table;
|
$subscribers_table = Subscriber::$_table;
|
||||||
Subscriber::raw_execute(sprintf('
|
Subscriber::raw_execute(sprintf('
|
||||||
UPDATE %s
|
UPDATE %s
|
||||||
SET deleted_at = NULL
|
SET deleted_at = NULL
|
||||||
WHERE %s.wp_user_id IS NOT NULL
|
WHERE %s.wp_user_id IS NOT NULL
|
||||||
', $subscribers_table, $subscribers_table));
|
', $subscribers_table, $subscribers_table));
|
||||||
@ -175,13 +175,13 @@ class WP {
|
|||||||
// e.g. if wp users were deleted directly from the database
|
// e.g. if wp users were deleted directly from the database
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
Subscriber::table_alias('wpms')
|
$wp_segment = Segment::getWPSegment();
|
||||||
->leftOuterJoin($wpdb->prefix . 'users', array('wpms.wp_user_id', '=', 'wu.id'), 'wu')
|
|
||||||
|
$wp_segment->subscribers()
|
||||||
|
->leftOuterJoin($wpdb->users, array(MP_SUBSCRIBERS_TABLE . '.wp_user_id', '=', 'wu.id'), 'wu')
|
||||||
->whereNull('wu.id')
|
->whereNull('wu.id')
|
||||||
->findResultSet()
|
->findResultSet()
|
||||||
->set('wp_user_id', null)
|
->set('wp_user_id', null)
|
||||||
->delete();
|
->delete();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Twig;
|
namespace MailPoet\Twig;
|
||||||
|
|
||||||
use MailPoet\Analytics\Reporter;
|
use MailPoet\Analytics\Reporter;
|
||||||
@ -7,11 +8,6 @@ use MailPoet\Analytics\Analytics as AnalyticsGenerator;
|
|||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Analytics extends \Twig_Extension {
|
class Analytics extends \Twig_Extension {
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return 'analytics';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFunctions() {
|
public function getFunctions() {
|
||||||
$analytics = new AnalyticsGenerator(new Reporter());
|
$analytics = new AnalyticsGenerator(new Reporter());
|
||||||
return array(
|
return array(
|
||||||
|
@ -1,25 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Twig;
|
|
||||||
|
|
||||||
use MailPoet\Config\Env;
|
namespace MailPoet\Twig;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Assets extends \Twig_Extension implements \Twig_Extension_GlobalsInterface {
|
class Assets extends \Twig_Extension {
|
||||||
private $_globals;
|
private $_globals;
|
||||||
|
|
||||||
function __construct($globals) {
|
function __construct($globals) {
|
||||||
$this->_globals = $globals;
|
$this->_globals = $globals;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName() {
|
|
||||||
return 'assets';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGlobals() {
|
|
||||||
return $this->_globals;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFunctions() {
|
function getFunctions() {
|
||||||
return array(
|
return array(
|
||||||
new \Twig_SimpleFunction(
|
new \Twig_SimpleFunction(
|
||||||
|
@ -7,11 +7,6 @@ use MailPoet\Config\ServicesChecker;
|
|||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Functions extends \Twig_Extension {
|
class Functions extends \Twig_Extension {
|
||||||
|
|
||||||
function getName() {
|
|
||||||
return 'functions';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFunctions() {
|
function getFunctions() {
|
||||||
return array(
|
return array(
|
||||||
new \Twig_SimpleFunction(
|
new \Twig_SimpleFunction(
|
||||||
@ -173,4 +168,4 @@ class Functions extends \Twig_Extension {
|
|||||||
function isRtl() {
|
function isRtl() {
|
||||||
return is_rtl();
|
return is_rtl();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,23 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Twig;
|
namespace MailPoet\Twig;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Handlebars extends \Twig_Extension {
|
class Handlebars extends \Twig_Extension {
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return 'handlebars';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFunctions() {
|
public function getFunctions() {
|
||||||
return array(
|
return array(
|
||||||
new \Twig_SimpleFunction(
|
new \Twig_SimpleFunction(
|
||||||
'partial',
|
'partial',
|
||||||
array($this, 'generatePartial'),
|
array(
|
||||||
|
$this,
|
||||||
|
'generatePartial'
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'needs_environment' => true,
|
'needs_environment' => true,
|
||||||
'needs_context' => true,
|
'needs_context' => true,
|
||||||
'is_safe' => array('all'))
|
'is_safe' => array('all')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -41,23 +41,28 @@ class Handlebars extends \Twig_Extension {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = array();
|
$rendered_template = twig_include($env, $context, $file);
|
||||||
|
|
||||||
$output[] = '<script id="'.$id.'" type="text/x-handlebars-template">';
|
$output = <<<EOL
|
||||||
$output[] = twig_include($env, $context, $file);
|
<script id="$id" type="text/x-handlebars-template">
|
||||||
$output[] = '</script>';
|
$rendered_template
|
||||||
|
</script>
|
||||||
|
EOL;
|
||||||
|
|
||||||
if($alias !== null) {
|
if($alias !== null) {
|
||||||
$output[] = '<script type="text/javascript">';
|
$output .= <<<EOL
|
||||||
$output[] = 'jQuery(function($) {';
|
<script type="text/javascript">
|
||||||
$output[] = '$(function() {';
|
jQuery(function($) {
|
||||||
$output[] = ' Handlebars.registerPartial(
|
$(function() {
|
||||||
"'.$alias.'",
|
Handlebars.registerPartial(
|
||||||
jQuery("#'.$id.'").html());';
|
'$alias',
|
||||||
$output[] = '});';
|
jQuery('#$id').html()
|
||||||
$output[] = '});';
|
);
|
||||||
$output[] = '</script>';
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
EOL;
|
||||||
}
|
}
|
||||||
return join("\n", $output);
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Twig;
|
namespace MailPoet\Twig;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Helpscout extends \Twig_Extension {
|
class Helpscout extends \Twig_Extension {
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return 'helpscout';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFunctions() {
|
public function getFunctions() {
|
||||||
return array(
|
return array(
|
||||||
new \Twig_SimpleFunction(
|
new \Twig_SimpleFunction(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace MailPoet\Twig;
|
namespace MailPoet\Twig;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
@ -12,10 +13,6 @@ class I18n extends \Twig_Extension {
|
|||||||
$this->_text_domain = $text_domain;
|
$this->_text_domain = $text_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName() {
|
|
||||||
return 'i18n';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFunctions() {
|
function getFunctions() {
|
||||||
// twig custom functions
|
// twig custom functions
|
||||||
$twig_functions = array();
|
$twig_functions = array();
|
||||||
|
@ -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.3
|
* Version: 3.0.0
|
||||||
* 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.3',
|
'version' => '3.0.0',
|
||||||
'filename' => __FILE__,
|
'filename' => __FILE__,
|
||||||
'path' => dirname(__FILE__),
|
'path' => dirname(__FILE__),
|
||||||
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
'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
|
Contributors: mailpoet, wysija
|
||||||
Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
|
Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
|
||||||
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.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.
|
Create and send beautiful emails and newsletters from WordPress.
|
||||||
|
|
||||||
== Description ==
|
== 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
|
* New designer with responsive templates
|
||||||
* Responsive templates
|
* Send your emails with MailPoet’s Sending Service (optional)
|
||||||
* Send with MailPoet (optional)
|
|
||||||
* Improved user experience
|
* Improved user experience
|
||||||
* Easier configuration
|
* Easy configuration
|
||||||
* Solid reliability
|
* Solid reliability
|
||||||
* Import subscribers, lists, forms and settings from old MailPoet
|
* Weekly releases
|
||||||
|
|
||||||
= See it in action. =
|
= See it in action. =
|
||||||
[Test the demo](http://demo3.mailpoet.com/launch/) or [see the 2 min. video](https://vimeo.com/223581490)
|
[Test the demo](http://demo3.mailpoet.com/launch/) or [see the 2 min. video](https://vimeo.com/223581490)
|
||||||
[vimeo 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
|
= What about the Premium? =
|
||||||
* 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
|
|
||||||
|
|
||||||
= 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 =
|
= Translations =
|
||||||
|
|
||||||
@ -50,8 +61,15 @@ MailPoet version 3 is considered production ready and will soon replace version
|
|||||||
* Russian
|
* Russian
|
||||||
* Japanese
|
* Japanese
|
||||||
* Persian (IR)
|
* 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 ==
|
== Installation ==
|
||||||
|
|
||||||
@ -60,7 +78,7 @@ There are 3 ways to install this plugin:
|
|||||||
= 1. The super easy way =
|
= 1. The super easy way =
|
||||||
1. In your WordPress dashboard, navigate to Plugins > Add New
|
1. In your WordPress dashboard, navigate to Plugins > Add New
|
||||||
1. Search for `MailPoet`
|
1. Search for `MailPoet`
|
||||||
1. Click on "install now" under "MailPoet 3 – Beta Version"
|
1. Click on "install now"
|
||||||
1. Activate the plugin
|
1. Activate the plugin
|
||||||
1. A new `MailPoet` menu will appear in your WordPress dashboard
|
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? =
|
= 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 ==
|
== Screenshots ==
|
||||||
|
|
||||||
@ -94,6 +112,11 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
|
|||||||
|
|
||||||
== Changelog ==
|
== 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 =
|
= 3.0.0-rc.2.0.3 - 2017-09-12 =
|
||||||
* Added: hook to override default cron URL. Thanks Fred;
|
* Added: hook to override default cron URL. Thanks Fred;
|
||||||
* Improved: WordPress user sync optimized for large membership sites; Thanks Nagui and @deltafactory!
|
* 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();
|
$arguments = array();
|
||||||
foreach($arguments_matches[0] as $argument) {
|
foreach($arguments_matches[0] as $argument) {
|
||||||
// Remove surrounding quotes of the same type from argument strings
|
// 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(
|
$call = array(
|
||||||
|
@ -99,7 +99,7 @@ class APITest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItSubscriberSubscriberToMultupleLists() {
|
function testItSubscribesSubscriberToMultupleLists() {
|
||||||
$subscriber = Subscriber::create();
|
$subscriber = Subscriber::create();
|
||||||
$subscriber->hydrate(Fixtures::get('subscriber_template'));
|
$subscriber->hydrate(Fixtures::get('subscriber_template'));
|
||||||
$subscriber->save();
|
$subscriber->save();
|
||||||
@ -111,7 +111,7 @@ class APITest extends \MailPoetTest {
|
|||||||
);
|
);
|
||||||
$result = API::MP(self::VERSION)->subscribeToLists($subscriber->id, array($segment->id));
|
$result = API::MP(self::VERSION)->subscribeToLists($subscriber->id, array($segment->id));
|
||||||
expect($result['id'])->equals($subscriber->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() {
|
function testItSubscribesSubscriberToSingleList() {
|
||||||
@ -127,7 +127,7 @@ class APITest extends \MailPoetTest {
|
|||||||
$result = API::MP(self::VERSION)->subscribeToList($subscriber->id, $segment->id);
|
$result = API::MP(self::VERSION)->subscribeToList($subscriber->id, $segment->id);
|
||||||
expect($result['id'])->equals($subscriber->id);
|
expect($result['id'])->equals($subscriber->id);
|
||||||
expect($result['subscriptions'])->notEmpty();
|
expect($result['subscriptions'])->notEmpty();
|
||||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItSubscribesSubscriberWithEmailIdentifier() {
|
function testItSubscribesSubscriberWithEmailIdentifier() {
|
||||||
@ -143,7 +143,7 @@ class APITest extends \MailPoetTest {
|
|||||||
$result = API::MP(self::VERSION)->subscribeToList($subscriber->email, $segment->id);
|
$result = API::MP(self::VERSION)->subscribeToList($subscriber->email, $segment->id);
|
||||||
expect($result['id'])->equals($subscriber->id);
|
expect($result['id'])->equals($subscriber->id);
|
||||||
expect($result['subscriptions'])->notEmpty();
|
expect($result['subscriptions'])->notEmpty();
|
||||||
expect($result['subscriptions'][0]['id'])->equals($segment->id);
|
expect($result['subscriptions'][0]['segment_id'])->equals($segment->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItGetsSegments() {
|
function testItGetsSegments() {
|
||||||
@ -242,7 +242,7 @@ class APITest extends \MailPoetTest {
|
|||||||
$result = API::MP(self::VERSION)->addSubscriber($subscriber, array($segment->id));
|
$result = API::MP(self::VERSION)->addSubscriber($subscriber, array($segment->id));
|
||||||
expect($result['id'])->greaterThan(0);
|
expect($result['id'])->greaterThan(0);
|
||||||
expect($result['email'])->equals($subscriber['email']);
|
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() {
|
function testItSchedulesWelcomeNotificationByDefaultAfterAddingSubscriber() {
|
||||||
@ -325,4 +325,4 @@ class APITest extends \MailPoetTest {
|
|||||||
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||||
\ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
\ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Test\Config;
|
namespace MailPoet\Test\Config;
|
||||||
|
|
||||||
|
use MailPoet\Config\Hooks;
|
||||||
|
|
||||||
class HooksTest extends \MailPoetTest {
|
class HooksTest extends \MailPoetTest {
|
||||||
function testItHooksSchedulerToMultiplePostTypes() {
|
function testItHooksSchedulerToMultiplePostTypes() {
|
||||||
|
$hooks = new Hooks();
|
||||||
|
$hooks->setupPostNotifications();
|
||||||
$post_types = get_post_types();
|
$post_types = get_post_types();
|
||||||
foreach($post_types as $post_type) {
|
foreach($post_types as $post_type) {
|
||||||
expect(has_filter('publish_' . $post_type, '\MailPoet\Newsletter\Scheduler\Scheduler::schedulePostNotification'))->notEmpty();
|
expect(has_filter('publish_' . $post_type, '\MailPoet\Newsletter\Scheduler\Scheduler::schedulePostNotification'))->notEmpty();
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace MailPoet\Test\Cron;
|
namespace MailPoet\Test\Cron;
|
||||||
|
|
||||||
|
use AspectMock\Test as Mock;
|
||||||
use MailPoet\Cron\CronHelper;
|
use MailPoet\Cron\CronHelper;
|
||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
use MailPoet\WP\Hooks;
|
|
||||||
|
|
||||||
class CronHelperTest extends \MailPoetTest {
|
class CronHelperTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
@ -14,7 +14,7 @@ class CronHelperTest extends \MailPoetTest {
|
|||||||
function testItDefinesConstants() {
|
function testItDefinesConstants() {
|
||||||
expect(CronHelper::DAEMON_EXECUTION_LIMIT)->equals(20);
|
expect(CronHelper::DAEMON_EXECUTION_LIMIT)->equals(20);
|
||||||
expect(CronHelper::DAEMON_EXECUTION_TIMEOUT)->equals(35);
|
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');
|
expect(CronHelper::DAEMON_SETTING)->equals('cron_daemon');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,38 +74,30 @@ class CronHelperTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItCreatesRandomToken() {
|
function testItCreatesRandomToken() {
|
||||||
// random token is a string of 5 characters
|
// random token is a string of 5 characters
|
||||||
$token1 = CronHelper::createToken();
|
$token1 = CronHelper::createToken();
|
||||||
$token2 = CronHelper::createToken();
|
$token2 = CronHelper::createToken();
|
||||||
expect($token1)->notEquals($token2);
|
expect($token1)->notEquals($token2);
|
||||||
expect(is_string($token1))->true();
|
expect(is_string($token1))->true();
|
||||||
expect(strlen($token1))->equals(5);
|
expect(strlen($token1))->equals(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItGetsSiteUrl() {
|
function testItGetsSiteUrl() {
|
||||||
// 1. do nothing when the url is manually overridden via a hook
|
// 1. do nothing when the url does not contain port
|
||||||
$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
|
|
||||||
$site_url = 'http://example.com';
|
$site_url = 'http://example.com';
|
||||||
expect(CronHelper::getSiteUrl($site_url))->equals($site_url);
|
expect(CronHelper::getSiteUrl($site_url))->equals($site_url);
|
||||||
|
|
||||||
if(getenv('WP_TEST_ENABLE_NETWORK_TESTS') !== 'true') return;
|
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';
|
$site_url = 'http://example.com:80';
|
||||||
expect(CronHelper::getSiteUrl($site_url))->equals($site_url);
|
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
|
// another attempt will be made to connect to the standard port derived from URL schema
|
||||||
$site_url = 'http://example.com:8080';
|
$site_url = 'http://example.com:8080';
|
||||||
expect(CronHelper::getSiteUrl($site_url))->equals('http://example.com');
|
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';
|
$site_url = 'https://invalid:80';
|
||||||
try {
|
try {
|
||||||
CronHelper::getSiteUrl($site_url);
|
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() {
|
function testItPingsDaemon() {
|
||||||
if(getenv('WP_TEST_ENABLE_NETWORK_TESTS') !== 'true') return;
|
if(getenv('WP_TEST_ENABLE_NETWORK_TESTS') !== 'true') return;
|
||||||
expect(CronHelper::pingDaemon())->equals('pong');
|
expect(CronHelper::pingDaemon())->equals('pong');
|
||||||
}
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
|
Mock::clean();
|
||||||
\ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
\ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,10 +7,6 @@ use MailPoet\Cron\Daemon;
|
|||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
|
|
||||||
class DaemonTest extends \MailPoetTest {
|
class DaemonTest extends \MailPoetTest {
|
||||||
function testItDefinesConstants() {
|
|
||||||
expect(Daemon::REQUEST_TIMEOUT)->equals(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItConstructs() {
|
function testItConstructs() {
|
||||||
Setting::setValue(
|
Setting::setValue(
|
||||||
CronHelper::DAEMON_SETTING,
|
CronHelper::DAEMON_SETTING,
|
||||||
|
@ -4,6 +4,7 @@ namespace MailPoet\Test\Helpscout;
|
|||||||
use MailPoet\Helpscout\Beacon;
|
use MailPoet\Helpscout\Beacon;
|
||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Services\Bridge;
|
||||||
|
|
||||||
class BeaconTest extends \MailPoetTest {
|
class BeaconTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
@ -130,4 +131,10 @@ class BeaconTest extends \MailPoetTest {
|
|||||||
(defined('MAILPOET_PREMIUM_VERSION')) ? MAILPOET_PREMIUM_VERSION : 'N/A'
|
(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 Carbon\Carbon;
|
||||||
use MailPoet\Models\Segment;
|
use MailPoet\Models\Segment;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Models\SubscriberSegment;
|
||||||
use MailPoet\Segments\WP;
|
use MailPoet\Segments\WP;
|
||||||
|
|
||||||
class WPTest extends \MailPoetTest {
|
class WPTest extends \MailPoetTest {
|
||||||
@ -67,6 +68,15 @@ class WPTest extends \MailPoetTest {
|
|||||||
expect($subscriber->first_name)->equals('First name');
|
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() {
|
function testItSynchronizeSegment() {
|
||||||
$this->insertUser();
|
$this->insertUser();
|
||||||
$this->insertUser();
|
$this->insertUser();
|
||||||
@ -108,6 +118,54 @@ class WPTest extends \MailPoetTest {
|
|||||||
expect($subscribers->count())->equals(1);
|
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() {
|
function _before() {
|
||||||
$this->cleanData();
|
$this->cleanData();
|
||||||
}
|
}
|
||||||
@ -118,18 +176,37 @@ class WPTest extends \MailPoetTest {
|
|||||||
|
|
||||||
private function cleanData() {
|
private function cleanData() {
|
||||||
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||||
|
\ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table);
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
$db = \ORM::getDb();
|
$db = \ORM::getDb();
|
||||||
$db->exec(sprintf('
|
$db->exec(sprintf('
|
||||||
DELETE FROM
|
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
|
WHERE
|
||||||
user_email LIKE "user-sync-test%%"
|
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() {
|
private function getSubscribersCount($a = null) {
|
||||||
return Subscriber::whereIn("wp_user_id", $this->userIds)->count();
|
return Subscriber::whereLike("email", "user-sync-test%")->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,14 +220,14 @@ class WPTest extends \MailPoetTest {
|
|||||||
global $wpdb;
|
global $wpdb;
|
||||||
$db = \ORM::getDb();
|
$db = \ORM::getDb();
|
||||||
$db->exec(sprintf('
|
$db->exec(sprintf('
|
||||||
INSERT INTO
|
INSERT INTO
|
||||||
%susers(user_login, user_email, user_registered)
|
%s (user_login, user_email, user_registered)
|
||||||
VALUES
|
VALUES
|
||||||
(
|
(
|
||||||
CONCAT("user-sync-test", rand()),
|
CONCAT("user-sync-test", rand()),
|
||||||
CONCAT("user", rand(), "@example.com"),
|
CONCAT("user-sync-test", rand(), "@example.com"),
|
||||||
"2017-01-02 12:31:12"
|
"2017-01-02 12:31:12"
|
||||||
)', $wpdb->prefix));
|
)', $wpdb->users));
|
||||||
$id = $db->lastInsertId();
|
$id = $db->lastInsertId();
|
||||||
$this->userIds[] = $id;
|
$this->userIds[] = $id;
|
||||||
return $id;
|
return $id;
|
||||||
@ -161,11 +238,11 @@ class WPTest extends \MailPoetTest {
|
|||||||
$db = \ORM::getDb();
|
$db = \ORM::getDb();
|
||||||
$db->exec(sprintf('
|
$db->exec(sprintf('
|
||||||
UPDATE
|
UPDATE
|
||||||
%susers
|
%s
|
||||||
SET user_email = "%s"
|
SET user_email = "%s"
|
||||||
WHERE
|
WHERE
|
||||||
id = %s
|
id = %s
|
||||||
', $wpdb->prefix, $email, $id));
|
', $wpdb->users, $email, $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateWPUserDisplayName($id, $name) {
|
private function updateWPUserDisplayName($id, $name) {
|
||||||
@ -173,11 +250,11 @@ class WPTest extends \MailPoetTest {
|
|||||||
$db = \ORM::getDb();
|
$db = \ORM::getDb();
|
||||||
$db->exec(sprintf('
|
$db->exec(sprintf('
|
||||||
UPDATE
|
UPDATE
|
||||||
%susers
|
%s
|
||||||
SET display_name = "%s"
|
SET display_name = "%s"
|
||||||
WHERE
|
WHERE
|
||||||
id = %s
|
id = %s
|
||||||
', $wpdb->prefix, $name, $id));
|
', $wpdb->users, $name, $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deleteWPUser($id) {
|
private function deleteWPUser($id) {
|
||||||
@ -185,10 +262,10 @@ class WPTest extends \MailPoetTest {
|
|||||||
$db = \ORM::getDb();
|
$db = \ORM::getDb();
|
||||||
$db->exec(sprintf('
|
$db->exec(sprintf('
|
||||||
DELETE FROM
|
DELETE FROM
|
||||||
%susers
|
%s
|
||||||
WHERE
|
WHERE
|
||||||
id = %s
|
id = %s
|
||||||
', $wpdb->prefix, $id));
|
', $wpdb->users, $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -61,12 +61,7 @@
|
|||||||
>
|
>
|
||||||
<div class="mailpoet_sending_method_description">
|
<div class="mailpoet_sending_method_description">
|
||||||
<h3>
|
<h3>
|
||||||
<img
|
<%= __('MailPoet Sending Service') %>
|
||||||
src="<%= assets_url %>/img/mailpoet_logo.png"
|
|
||||||
alt="MailPoet"
|
|
||||||
width="137"
|
|
||||||
height="54"
|
|
||||||
/>
|
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
@ -83,19 +78,26 @@
|
|||||||
id="mailpoet_sending_method_inactive_text"
|
id="mailpoet_sending_method_inactive_text"
|
||||||
>
|
>
|
||||||
<strong><%= __("Solve all of your sending problems!") %></strong>
|
<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">
|
<ul class="sending-method-benefits mailpoet_success">
|
||||||
<li class="mailpoet_success_item"><%= __('Reach the inbox, not the spam box.') %>
|
<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"><%= __('Super fast: send up to 50,000 emails per hour.') %>
|
||||||
<li class="mailpoet_success_item"><%= __('SPF & DKIM signatures are already set up! No configuration required.') %>
|
<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"><%= __('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>
|
</ul>
|
||||||
<a
|
<a
|
||||||
href="<%= admin_url('admin.php?page=mailpoet-premium') %>"
|
href="<%= admin_url('admin.php?page=mailpoet-premium') %>"
|
||||||
class="button button-primary"
|
class="button button-primary"
|
||||||
target="_blank"
|
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>
|
</div>
|
||||||
<div class="mailpoet_status">
|
<div class="mailpoet_status">
|
||||||
@ -118,14 +120,17 @@
|
|||||||
<div class="mailpoet_sending_method_description">
|
<div class="mailpoet_sending_method_description">
|
||||||
<h3><%= __('Other') %></h3>
|
<h3><%= __('Other') %></h3>
|
||||||
<div class="mailpoet_description">
|
<div class="mailpoet_description">
|
||||||
<strong><%= __('Send with your website or third party') %></strong>
|
<strong><%= __('Send emails via your host (not recommended!) or via a third-party sender.') %></strong>
|
||||||
<br />
|
|
||||||
<%= __('Choose to send emails through your website (not recommended) or a third party sender.') %>
|
|
||||||
<ul class="sending-method-benefits mailpoet_error">
|
<ul class="sending-method-benefits mailpoet_error">
|
||||||
<li class="mailpoet_error_item"><%= __("You'll probably end up in spam.") %>
|
<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 web host.') %>
|
<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"><%= __("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"><%=
|
||||||
|
__("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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<h1><%= __('Greetings, humans.') %></h1>
|
<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]')
|
<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
|
|raw
|
||||||
%>
|
%>
|
||||||
</p>
|
</p>
|
||||||
@ -60,8 +60,18 @@
|
|||||||
<div class="feature-section one-col mailpoet_centered">
|
<div class="feature-section one-col mailpoet_centered">
|
||||||
<h2><%= __('Care to Give Your Opinion?') %></h2>
|
<h2><%= __('Care to Give Your Opinion?') %></h2>
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="//secure.polldaddy.com/p/9801036.js"></script>
|
<div class="pd-embed" id="pd_1505214143"></div>
|
||||||
<noscript><a href="//polldaddy.com/poll/9801036/">Should MailPoet include more default templates?</a></noscript>
|
<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>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<h1><%= __('Greetings, humans.') %></h1>
|
<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]')
|
<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
|
|raw
|
||||||
%>
|
%>
|
||||||
</p>
|
</p>
|
||||||
@ -17,9 +17,32 @@
|
|||||||
<a href="admin.php?page=mailpoet-update" class="nav-tab"><%= __("What's new") %></a>
|
<a href="admin.php?page=mailpoet-update" class="nav-tab"><%= __("What's new") %></a>
|
||||||
</h2>
|
</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="headline-feature feature-video">
|
||||||
<div class="videoWrapper">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -28,13 +51,12 @@
|
|||||||
<div class="feature-section two-col">
|
<div class="feature-section two-col">
|
||||||
<h2><%= __('Want to Make MailPoet Even Better?') %></h2>
|
<h2><%= __('Want to Make MailPoet Even Better?') %></h2>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3><%= __('We Need Your Feedback!') %></h3>
|
<h3><%= __('Documentation Is One Click Away') %></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><%= __('Simply click on the blue circle in the bottom right corner of any of the MailPoet pages to access our documentation.') %> <em><%= __('Voilà!') %></em>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3><%= __('Sharing is Caring') %></h3>
|
<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>
|
<br><br>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="mailpoet_analytics_enabled" value="1"
|
<input type="checkbox" id="mailpoet_analytics_enabled" value="1"
|
||||||
@ -58,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3><%= __("Learn the Ropes") %></h3>
|
<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>
|
<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>
|
<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>
|
</p>
|
||||||
|
Reference in New Issue
Block a user