Compare commits

...

15 Commits

Author SHA1 Message Date
f7b1016e63 Release 3.0.0-rc.1.0.3 2017-08-15 11:35:44 +02:00
223fedba72 Update vendor dependencies
Bump down codeception version to 2.2.11 for code coverage compatibility
with php 5.6

[MAILPOET-1049]
2017-08-15 10:12:48 +02:00
bf7e7e414f Adds hook to modify rendered form widget 2017-08-15 09:49:38 +02:00
618d0c0c9d Explicitly sets form target to _self as default 2017-08-15 09:49:38 +02:00
70860a676c Merge pull request #1036 from mailpoet/date_shortcode_update
Translates and updates date shortcode to display WP time [MAILPOET-1046]
2017-08-14 13:09:08 +03:00
469e9fd8e1 Update poll to "how would you rate MailPoet's reliability?"
[MAILPOET-1043]
2017-08-14 08:49:44 +02:00
715b48df8d Merge pull request #1040 from mailpoet/preview-popup
Fit newsletter browser preview modal popup to screen [MAILPOET-975]
2017-08-13 11:31:05 -04:00
27ae0a9f16 Merge pull request #1039 from mailpoet/set_time_limit_update
Conditionally uses set_time_limit() when function is not disabled [MAILPOET-1054]
2017-08-11 19:52:15 +02:00
b92329a6b5 Fix popup dimensions to the viewport and show the close button 2017-08-11 17:30:13 +00:00
6fe5b7e0c5 Conditionally uses set_time_limit() when function is not disabled 2017-08-11 12:16:31 -04:00
7e0c500e4f Uses WP's date_i18n() to localize date shortcode 2017-08-10 12:46:27 -04:00
eec35c8ab6 Merge pull request #1037 from mailpoet/build-failures
Break the build when errors happen during build steps [MAILPOET-1052]
2017-08-10 16:35:55 +02:00
4096c4b31b Break the build when errors happen during build steps [MAILPOET-1052] 2017-08-10 14:51:37 +03:00
40cbefd1f4 Uses WP time vs. system time 2017-08-09 18:59:55 -04:00
fb5d43e975 Adds helper method to translate shortcodes
Adds translations to Date shortcode
2017-08-09 18:56:33 -04:00
21 changed files with 1343 additions and 994 deletions

View File

@ -45,7 +45,6 @@ body.mailpoet_modal_opened
position: absolute position: absolute
z-index: 25 z-index: 25
top: 48px top: 48px
padding-bottom: 48px
margin: 0 margin: 0
.mailpoet_popup_wrapper .mailpoet_popup_wrapper
@ -54,6 +53,7 @@ body.mailpoet_modal_opened
position: relative position: relative
width: 100% width: 100%
z-index: 0 z-index: 0
height: 96%
.mailpoet_overlay_hidden .mailpoet_popup_wrapper .mailpoet_overlay_hidden .mailpoet_popup_wrapper
border: 1px solid #333 border: 1px solid #333
@ -75,6 +75,7 @@ body.mailpoet_modal_opened
.mailpoet_popup_body .mailpoet_popup_body
padding: 10px 10px 10px 10px padding: 10px 10px 10px 10px
height: 92%
// modal panel // modal panel
#mailpoet_modal_overlay.mailpoet_panel_overlay #mailpoet_modal_overlay.mailpoet_panel_overlay

View File

@ -127,9 +127,6 @@ body
background-color: $primary-background-color background-color: $primary-background-color
border: 1px solid $content-border-color border: 1px solid $content-border-color
#mailpoet_modal_close
display: none
.wrap > .mailpoet_notice, .wrap > .mailpoet_notice,
.notice .notice
.update-nag .update-nag

View File

@ -308,10 +308,11 @@ define('modal', ['mailpoet', 'jquery'],
setDimensions: function() { setDimensions: function() {
switch(this.options.type) { switch(this.options.type) {
case 'popup': case 'popup':
console.log(this.options)
// set popup dimensions // set popup dimensions
jQuery('#mailpoet_popup').css({ jQuery('#mailpoet_popup').css({
width: this.options.width, width: this.options.width,
minHeight: this.options.height height: this.options.height
}); });
// set popup wrapper height // set popup wrapper height
jQuery('#mailpoet_popup_wrapper').css({ jQuery('#mailpoet_popup_wrapper').css({

View File

@ -272,10 +272,13 @@ define([
}); });
var view = this.previewView.render(); var view = this.previewView.render();
this.previewView.$el.css('height', '100%');
MailPoet.Modal.popup({ MailPoet.Modal.popup({
template: '', template: '',
element: this.previewView.$el, element: this.previewView.$el,
width: '95%',
height: '94%',
title: MailPoet.I18n.t('newsletterPreview'), title: MailPoet.I18n.t('newsletterPreview'),
onCancel: function() { onCancel: function() {
this.previewView.destroy(); this.previewView.destroy();
@ -340,8 +343,10 @@ define([
getTemplate: function() { return templates.newsletterPreview; }, getTemplate: function() { return templates.newsletterPreview; },
initialize: function(options) { initialize: function(options) {
this.previewUrl = options.previewUrl; this.previewUrl = options.previewUrl;
this.width = App.getConfig().get('newsletterPreview.width'); this.width = '100%';
this.height = App.getConfig().get('newsletterPreview.height') this.height = '100%';
// this.width = App.getConfig().get('newsletterPreview.width');
// this.height = App.getConfig().get('newsletterPreview.height')
}, },
templateContext: function() { templateContext: function() {
return { return {

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/sh -e
# Translations (npm install & composer install need to be run before) # Translations (npm install & composer install need to be run before)
echo '[BUILD] Generating translations' echo '[BUILD] Generating translations'
@ -9,21 +9,22 @@ plugin_name='mailpoet'
# Remove previous build. # Remove previous build.
echo '[BUILD] Removing previous build' echo '[BUILD] Removing previous build'
rm $plugin_name.zip test -e $plugin_name.zip && rm $plugin_name.zip
# Create temp dir. # Create temp dir.
echo '[BUILD] Creating temporary directory' echo '[BUILD] Creating temporary directory'
test -d $plugin_name && rm -rf $plugin_name
mkdir $plugin_name mkdir $plugin_name
# Production assets. # Production assets.
echo '[BUILD] Generating production CSS and JS assets' echo '[BUILD] Generating production CSS and JS assets'
rm -rf node_modules test -d node_modules && rm -rf node_modules
npm install npm install
./do compile:all --env production ./do compile:all --env production
# Production libraries. # Production libraries.
echo '[BUILD] Fetching production libraries' echo '[BUILD] Fetching production libraries'
rm -rf vendor test -d vendor && rm -rf vendor
./composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-scripts ./composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-scripts
# Copy release folders. # Copy release folders.

View File

@ -20,7 +20,7 @@
}, },
"require-dev": { "require-dev": {
"codeception/aspect-mock": "^2.0", "codeception/aspect-mock": "^2.0",
"codeception/codeception": "^2.2.9", "codeception/codeception": "2.2.11",
"codeception/verify": "^0.3.3", "codeception/verify": "^0.3.3",
"consolidation/robo": "^1.0.5", "consolidation/robo": "^1.0.5",
"henrikbjorn/lurker": "^1.2", "henrikbjorn/lurker": "^1.2",

838
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,21 +2,19 @@
namespace MailPoet\Config; namespace MailPoet\Config;
use MailPoet\Util\ProgressBar;
use MailPoet\Models\Form;
use MailPoet\Models\Setting;
use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
use MailPoet\Models\CustomField; use MailPoet\Models\CustomField;
use MailPoet\Models\SubscriberSegment; use MailPoet\Models\Form;
use MailPoet\Models\SubscriberCustomField;
use MailPoet\Models\MappingToExternalEntities; use MailPoet\Models\MappingToExternalEntities;
use MailPoet\Config\Activator; use MailPoet\Models\Segment;
use MailPoet\Models\Setting;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Util\ProgressBar;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class MP2Migrator { class MP2Migrator {
const IMPORT_TIMEOUT_IN_SECONDS = 7200; // Timeout = 2 hours const IMPORT_TIMEOUT_IN_SECONDS = 7200; // Timeout = 2 hours
const CHUNK_SIZE = 10; // To import the data by batch const CHUNK_SIZE = 10; // To import the data by batch
@ -145,7 +143,9 @@ class MP2Migrator {
* @return string Result * @return string Result
*/ */
public function import() { public function import() {
set_time_limit(self::IMPORT_TIMEOUT_IN_SECONDS); if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
@set_time_limit(3600);
}
ob_start(); ob_start();
$datetime = new \MailPoet\WP\DateTime(); $datetime = new \MailPoet\WP\DateTime();
$this->log(sprintf('=== ' . __('START IMPORT', 'mailpoet') . ' %s ===', $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT))); $this->log(sprintf('=== ' . __('START IMPORT', 'mailpoet') . ' %s ===', $datetime->formatTime(time(), \MailPoet\WP\DateTime::DEFAULT_DATE_TIME_FORMAT)));
@ -1139,5 +1139,4 @@ class MP2Migrator {
} }
return $emails_number; return $emails_number;
} }
} }

View File

@ -1,10 +1,13 @@
<?php <?php
namespace MailPoet\Form; namespace MailPoet\Form;
use MailPoet\API\JSON\API; use MailPoet\API\JSON\API;
use MailPoet\Config\Renderer; use MailPoet\Config\Renderer;
use MailPoet\Models\Form;
use MailPoet\Form\Renderer as FormRenderer; use MailPoet\Form\Renderer as FormRenderer;
use MailPoet\Models\Form;
use MailPoet\Util\Security; use MailPoet\Util\Security;
use MailPoet\WP\Hooks;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@ -37,7 +40,7 @@ class Widget extends \WP_Widget {
$instance = wp_parse_args( $instance = wp_parse_args(
(array)$instance, (array)$instance,
array( array(
'title' => __("Subscribe to Our Newsletter", 'mailpoet') 'title' => __('Subscribe to Our Newsletter', 'mailpoet')
) )
); );
@ -109,7 +112,7 @@ class Widget extends \WP_Widget {
$instance = $args; $instance = $args;
} }
$title = apply_filters( $title = Hooks::applyFilters(
'widget_title', 'widget_title',
!empty($instance['title']) ? $instance['title'] : '', !empty($instance['title']) ? $instance['title'] : '',
$instance, $instance,
@ -119,7 +122,7 @@ class Widget extends \WP_Widget {
// get form // get form
$form = Form::getPublished()->findOne($instance['form']); $form = Form::getPublished()->findOne($instance['form']);
// if the form was not found, return nothing. // if the form was not found, return nothing
if($form === false) { if($form === false) {
return ''; return '';
} else { } else {
@ -175,6 +178,7 @@ class Widget extends \WP_Widget {
try { try {
$output = $renderer->render('form/widget.html', $data); $output = $renderer->render('form/widget.html', $data);
$output = do_shortcode($output); $output = do_shortcode($output);
$output = Hooks::applyFilters('mailpoet_form_widget_post_process', $output);
} catch(\Exception $e) { } catch(\Exception $e) {
$output = $e->getMessage(); $output = $e->getMessage();
} }

View File

@ -1,4 +1,5 @@
<?php <?php
namespace MailPoet\Newsletter\Shortcodes\Categories; namespace MailPoet\Newsletter\Shortcodes\Categories;
class Date { class Date {
@ -7,20 +8,19 @@ class Date {
$action_argument = false, $action_argument = false,
$action_argument_value = false $action_argument_value = false
) { ) {
$date = new \DateTime('now'); $action_mapping = array(
$action_formats = array( 'd' => 'd',
'd' => $date->format('d'), 'dordinal' => 'dS',
'dordinal' => $date->format('dS'), 'dtext' => 'l',
'dtext' => $date->format('l'), 'm' => 'm',
'm' => $date->format('m'), 'mtext' => 'F',
'mtext' => $date->format('F'), 'y' => 'Y'
'y' => $date->format('Y')
); );
if(!empty($action_formats[$action])) { if(!empty($action_mapping[$action])) {
return $action_formats[$action]; return date_i18n($action_mapping[$action], current_time('timestamp'));
} }
return ($action === 'custom' && $action_argument === 'format') ? return ($action === 'custom' && $action_argument === 'format') ?
$date->format($action_argument_value) : date_i18n($action_argument_value, current_time('timestamp')) :
false; false;
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
namespace MailPoet\Newsletter\Shortcodes; namespace MailPoet\Newsletter\Shortcodes;
use MailPoet\Models\CustomField; use MailPoet\Models\CustomField;

View File

@ -1,4 +1,5 @@
<?php <?php
namespace MailPoet\Subscribers\ImportExport\Export; namespace MailPoet\Subscribers\ImportExport\Export;
use MailPoet\Config\Env; use MailPoet\Config\Env;
@ -26,7 +27,9 @@ class Export {
public $subscriber_batch_size; public $subscriber_batch_size;
public function __construct($data) { public function __construct($data) {
if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
set_time_limit(0); set_time_limit(0);
}
$this->export_confirmed_option = $data['export_confirmed_option']; $this->export_confirmed_option = $data['export_confirmed_option'];
$this->export_format_option = $data['export_format_option']; $this->export_format_option = $data['export_format_option'];
$this->group_by_segment_option = $data['group_by_segment_option']; $this->group_by_segment_option = $data['group_by_segment_option'];
@ -47,7 +50,7 @@ class Export {
function process() { function process() {
try { try {
if(is_writable($this->export_path) === false) { if(is_writable($this->export_path) === false) {
throw new \Exception(__("The export file could not be saved on the server.", 'mailpoet')); throw new \Exception(__('The export file could not be saved on the server.', 'mailpoet'));
} }
if(!extension_loaded('zip')) { if(!extension_loaded('zip')) {
throw new \Exception(__('Export requires a ZIP extension to be installed on the host.', 'mailpoet')); throw new \Exception(__('Export requires a ZIP extension to be installed on the host.', 'mailpoet'));

View File

@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
/* /*
* Plugin Name: MailPoet 3 (new) * Plugin Name: MailPoet 3 (new)
* Version: 3.0.0-rc.1.0.2 * Version: 3.0.0-rc.1.0.3
* 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.1.0.2', 'version' => '3.0.0-rc.1.0.3',
'filename' => __FILE__, 'filename' => __FILE__,
'path' => dirname(__FILE__), 'path' => dirname(__FILE__),
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php', 'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',

View File

@ -3,7 +3,7 @@ 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
Stable tag: 3.0.0-rc.1.0.2 Stable tag: 3.0.0-rc.1.0.3
Create and send beautiful emails and newsletters from WordPress. Create and send beautiful emails and newsletters from WordPress.
== Description == == Description ==
@ -93,6 +93,12 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
== Changelog == == Changelog ==
= 3.0.0-rc.1.0.3 - 2017-08-15 =
* Improved: newsletter browser preview window in newsletter editor now fits correctly in any screen height;
* Improved: date shortcode displays WP time and is available to be translated into other laguages. Thanks Rik and Yves!
* Improved: rendered form body can be modified via a hook. Thanks, Vrodo;
* Fixed: subscriber export will not fail on hosts with PHP's set_time_limit() disabled. Thanks, @miguelarroyo;
= 3.0.0-rc.1.0.2 - 2017-08-08 = = 3.0.0-rc.1.0.2 - 2017-08-08 =
* Fixed: correct error notice is displayed when using IIS server. Thanks @flauer! * Fixed: correct error notice is displayed when using IIS server. Thanks @flauer!

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash -e
echo "Getting translations from Transifex..." echo "Getting translations from Transifex..."
tx pull -a -f tx pull -a -f

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash -e
# Write ~/.transifexrc file if not exists # Write ~/.transifexrc file if not exists
if [ ! -f ~/.transifexrc ]; then if [ ! -f ~/.transifexrc ]; then

View File

@ -0,0 +1,54 @@
<?php
namespace MailPoet\Test\Form;
use MailPoet\Form\Widget;
use MailPoet\Models\Form;
use MailPoet\Util\pQuery\pQuery;
use MailPoet\WP\Hooks;
class WidgetTest extends \MailPoetTest {
function testItAllowsModifyingRenderedFormWidgetViaHook() {
$form = Form::createOrUpdate(
array(
'name' => 'Test Form',
'body' => array(
array(
'type' => 'text',
'id' => 'email',
)
)
)
);
$form_widget = new Widget();
// form target is set to _self by default
$rendered_form_widget = $form_widget->widget(
array(),
array(
'form' => $form->id,
'form_type' => 'html'
)
);
$DOM = pQuery::parseStr($rendered_form_widget);
expect($DOM->query('form')->attr('target'))->equals('_self');
// form target is modified to _top via hook
Hooks::addFilter(
'mailpoet_form_widget_post_process',
function($form) {
$form = str_replace('target="_self"', 'target="_top"', $form);
return $form;
}
);
$rendered_form_widget = $form_widget->widget(
array(),
array(
'form' => $form->id,
'form_type' => 'html'
)
);
$DOM = pQuery::parseStr($rendered_form_widget);
expect($DOM->query('form')->attr('target'))->equals('_top');
}
}

View File

@ -5,7 +5,7 @@ use MailPoet\Models\CustomField;
use MailPoet\Newsletter\Shortcodes\ShortcodesHelper; use MailPoet\Newsletter\Shortcodes\ShortcodesHelper;
class ShortcodesHelperTest extends \MailPoetTest { class ShortcodesHelperTest extends \MailPoetTest {
function testItCanGetShortcodes() { function testGetsShortcodes() {
$shortcodes = ShortcodesHelper::getShortcodes(); $shortcodes = ShortcodesHelper::getShortcodes();
expect(array_keys($shortcodes))->equals( expect(array_keys($shortcodes))->equals(
array( array(
@ -18,7 +18,7 @@ class ShortcodesHelperTest extends \MailPoetTest {
); );
} }
function testItCanGetCustomShortShortcodes() { function testItGetsCustomShortShortcodes() {
$shortcodes = ShortcodesHelper::getShortcodes(); $shortcodes = ShortcodesHelper::getShortcodes();
expect(count($shortcodes['Subscriber']))->equals(5); expect(count($shortcodes['Subscriber']))->equals(5);
$custom_field = CustomField::create(); $custom_field = CustomField::create();

View File

@ -80,15 +80,15 @@ class ShortcodesTest extends \MailPoetTest {
} }
function testItCanProcessDateShortcodes() { function testItCanProcessDateShortcodes() {
$date = new \DateTime('now'); $date = new \DateTime(current_time('mysql'));
expect(Date::process('d'))->equals($date->format('d')); expect(Date::process('d'))->equals(date_i18n('d', current_time('timestamp')));
expect(Date::process('dordinal'))->equals($date->format('dS')); expect(Date::process('dordinal'))->equals(date_i18n('dS', current_time('timestamp')));
expect(Date::process('dtext'))->equals($date->format('l')); expect(Date::process('dtext'))->equals(date_i18n('l', current_time('timestamp')));
expect(Date::process('m'))->equals($date->format('m')); expect(Date::process('m'))->equals(date_i18n('m', current_time('timestamp')));
expect(Date::process('mtext'))->equals($date->format('F')); expect(Date::process('mtext'))->equals(date_i18n('F', current_time('timestamp')));
expect(Date::process('y'))->equals($date->format('Y')); expect(Date::process('y'))->equals(date_i18n('Y', current_time('timestamp')));
// allow custom date formats (http://php.net/manual/en/function.date.php) // allow custom date formats (http://php.net/manual/en/function.date.php)
expect(Date::process('custom', 'format', 'U'))->equals($date->format('U')); expect(Date::process('custom', 'format', 'U F'))->equals(date_i18n('U F', current_time('timestamp')));
} }
function testItCanProcessNewsletterShortcodes() { function testItCanProcessNewsletterShortcodes() {
@ -109,7 +109,6 @@ class ShortcodesTest extends \MailPoetTest {
expect($result['0'])->equals($wp_post->post_title); expect($result['0'])->equals($wp_post->post_title);
} }
function itCanProcessPostNotificationNewsletterNumberShortcode() { function itCanProcessPostNotificationNewsletterNumberShortcode() {
// create first post notification // create first post notification
$post_notification_history = $this->_createNewsletter( $post_notification_history = $this->_createNewsletter(
@ -365,4 +364,5 @@ class ShortcodesTest extends \MailPoetTest {
wp_delete_post($this->WP_post, true); wp_delete_post($this->WP_post, true);
wp_delete_user($this->WP_user->ID); wp_delete_user($this->WP_user->ID);
} }
} }

View File

@ -8,6 +8,7 @@
<div id="<%= form_id %>" class="mailpoet_form mailpoet_form_<%= form_type %>"> <div id="<%= form_id %>" class="mailpoet_form mailpoet_form_<%= form_type %>">
<%= styles | raw %> <%= styles | raw %>
<form <form
target="_self"
method="post" method="post"
action="<%= admin_url('admin-post.php?action=mailpoet_subscription_form') | raw %>" action="<%= admin_url('admin-post.php?action=mailpoet_subscription_form') | raw %>"
class="mailpoet_form mailpoet_form_<%= form_type %>" class="mailpoet_form mailpoet_form_<%= form_type %>"

View File

@ -60,8 +60,8 @@
<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="https://secure.polldaddy.com/p/9792513.js"></script> <script type="text/javascript" charset="utf-8" src="//secure.polldaddy.com/p/9801039.js"></script>
<noscript><a href="//polldaddy.com/poll/9792513/">How many people on this website use MailPoet to send emails?</a></noscript> <noscript><a href="//polldaddy.com/poll/9801039/">How would you rate the reliability of MailPoet?</a></noscript>
</div> </div>
<hr> <hr>