Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
ffc1d0a61c | |||
d1b160def7 | |||
493fd01754 | |||
9ced4b1757 | |||
17010e5ba9 | |||
42ad7584d4 | |||
dbc0f9b238 | |||
e62e9a5892 | |||
bc25fa61b4 | |||
2590967183 | |||
86eafd3c17 | |||
90a6f160c2 | |||
c774aec6a2 | |||
8f2fd1d76e | |||
4df11163a1 | |||
82a736ffbb | |||
87052986e8 | |||
0c73c0fadc | |||
5c7e11076d | |||
d1df94c759 | |||
53cc39c6f5 | |||
4955c72ee1 | |||
16661af8c3 | |||
bc80f69e41 | |||
0192934e65 | |||
2793e74858 | |||
5996696cc9 | |||
7f6cf5bbf3 | |||
c0ef2254cd | |||
0dbe04c3f8 | |||
ef1805d9b5 | |||
514f539e83 | |||
50f072705e | |||
f8f7bc3d3d | |||
f1bf2bb097 | |||
bbe2f69a7f | |||
c844488b0b | |||
112fe0cd6e | |||
c9e6dce785 | |||
d1c09c015a |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,7 @@
|
||||
.DS_Store
|
||||
TODO
|
||||
composer.phar
|
||||
vendor
|
||||
/vendor
|
||||
tests/_output/*
|
||||
tests/acceptance.suite.yml
|
||||
tests/_support/_generated/*
|
||||
|
@ -43,7 +43,7 @@
|
||||
bottom: 0
|
||||
background-color: rgba(255, 255, 255, 0.0)
|
||||
opacity: 0
|
||||
transition: all 200ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
|
||||
&:hover
|
||||
background-color: rgba(255, 255, 255, 0.7)
|
||||
|
@ -90,7 +90,7 @@ body.mailpoet_modal_opened
|
||||
padding: 0
|
||||
margin: 0
|
||||
width: 100%
|
||||
transition: margin 0.3s ease-out
|
||||
transition: margin 250ms ease-out
|
||||
|
||||
.mailpoet_panel_wrapper
|
||||
background-color: #f1f1f1
|
||||
@ -200,4 +200,4 @@ body.mailpoet_modal_opened
|
||||
0%
|
||||
50%
|
||||
background-color: #064E6D
|
||||
100%
|
||||
100%
|
||||
|
@ -85,7 +85,6 @@ $layer-selector-width = 30px
|
||||
max-width: 100%
|
||||
display: inline-block
|
||||
opacity: 1
|
||||
animation-fade-in-and-scale-horizontally()
|
||||
|
||||
.mailpoet_delete_block_confirm,
|
||||
.mailpoet_delete_block_cancel
|
||||
@ -113,6 +112,9 @@ $layer-selector-width = 30px
|
||||
max-width: 100%
|
||||
opacity: 1
|
||||
|
||||
.mailpoet_delete_block_cancel
|
||||
margin-left: 3px
|
||||
|
||||
.mailpoet_delete_block_confirm
|
||||
color: $warning-text-color
|
||||
|
||||
|
@ -52,7 +52,7 @@ $draggable-widget-z-index = 2
|
||||
padding: 0
|
||||
margin: 0
|
||||
z-index: $draggable-widget-z-index
|
||||
animation-fade-in-and-scale-up()
|
||||
animation-fade-in()
|
||||
|
||||
.mailpoet_widget_icon
|
||||
padding: 0
|
||||
|
@ -26,13 +26,9 @@ $widget-icon-width = 30px
|
||||
border-right: 0
|
||||
|
||||
&.closed .mailpoet_region_content
|
||||
max-height: 0px
|
||||
overflow: hidden
|
||||
margin-top: 0
|
||||
display: none
|
||||
|
||||
.mailpoet_region_content
|
||||
max-height: 2000px
|
||||
transition: max-height 300ms ease
|
||||
padding: 0 20px
|
||||
margin-top: 12px
|
||||
|
||||
|
@ -30,8 +30,3 @@ $block-hover-highlight-color = $primary-active-color
|
||||
|
||||
.mailpoet_content
|
||||
position: relative
|
||||
|
||||
.mailpoet_block_transition_in
|
||||
animation-fade-in-and-scale-up()
|
||||
.mailpoet_block_transition_out
|
||||
animation-fade-out-and-scale-down()
|
||||
|
@ -1,5 +1,5 @@
|
||||
animation-slide-open-downwards()
|
||||
transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
max-height: 2000px
|
||||
opacity: 1
|
||||
|
||||
@ -9,45 +9,22 @@ animation-slide-open-downwards()
|
||||
overflow-y: hidden
|
||||
|
||||
animation-background-color()
|
||||
transition: background 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
transition: background 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
|
||||
animation-fade-in-and-scale-up()
|
||||
animation-name: fadeInAndScaleUp
|
||||
animation-duration: 500ms
|
||||
animation-fill-mode: forwards
|
||||
|
||||
animation-fade-out-and-scale-down()
|
||||
animation-name: fadeOutAndScaleDown
|
||||
animation-duration: 500ms
|
||||
animation-fade-in()
|
||||
animation-name: fadeIn
|
||||
animation-duration: 250ms
|
||||
animation-fill-mode: forwards
|
||||
|
||||
animation-fade-in-and-scale-horizontally()
|
||||
transition: all 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
|
||||
@keyframes fadeInAndScaleUp {
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0.3
|
||||
max-height: 0
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1
|
||||
max-height: 5000px
|
||||
overflow: hidden
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOutAndScaleDown {
|
||||
0% {
|
||||
opacity: 1
|
||||
max-height: 5000px
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.3
|
||||
max-height: 0
|
||||
overflow: hidden
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ define(
|
||||
status: 'loading'
|
||||
};
|
||||
},
|
||||
getDaemonData: function() {
|
||||
getCronData: function() {
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'cron',
|
||||
action: 'getDaemonStatus'
|
||||
action: 'getStatus'
|
||||
})
|
||||
.done(function(response) {
|
||||
jQuery('.button-primary')
|
||||
@ -32,25 +32,23 @@ define(
|
||||
},
|
||||
componentDidMount: function() {
|
||||
if(this.isMounted()) {
|
||||
this.getDaemonData();
|
||||
setInterval(this.getDaemonData, 5000);
|
||||
this.getCronData();
|
||||
setInterval(this.getCronData, 5000);
|
||||
}
|
||||
},
|
||||
controlDaemon: function(action) {
|
||||
controlCron: function(action) {
|
||||
if(jQuery('.button-primary').hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
jQuery('.button-primary')
|
||||
.addClass('disabled');
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'cron',
|
||||
action: 'controlDaemon',
|
||||
data: {
|
||||
'action': action
|
||||
}
|
||||
action: action,
|
||||
})
|
||||
.done(function(response) {
|
||||
if(!response.result) {
|
||||
//this.replaceState();
|
||||
} else {
|
||||
//this.setState(response);
|
||||
MailPoet.Notice.error(MailPoetI18n.daemonControlError);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
@ -71,19 +69,25 @@ define(
|
||||
<strong> {this.state.counter} </strong> times (once every 30 seconds, unless it was interrupted and restarted).
|
||||
<br />
|
||||
<br />
|
||||
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'stop')}>Stop</a>
|
||||
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'pause')}>Pause</a>
|
||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'stop')}>Stop</a>
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
case 'starting':
|
||||
case 'stopping':
|
||||
return(
|
||||
<div>
|
||||
Daemon is {this.state.status}
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
case 'paused':
|
||||
case 'stopped':
|
||||
return(
|
||||
<div>
|
||||
Daemon is {this.state.status}
|
||||
<br />
|
||||
<br />
|
||||
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'start')}>Start</a>
|
||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'start')}>Start</a>
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
|
@ -70,8 +70,8 @@ define([
|
||||
fetchPosts: function() {
|
||||
var that = this;
|
||||
CommunicationComponent.getTransformedPosts(this.toJSON()).done(function(content) {
|
||||
console.log('ALC fetched', arguments);
|
||||
that.get('_container').get('blocks').reset(content, {parse: true});
|
||||
that.trigger('postsChanged');
|
||||
}).fail(function(error) {
|
||||
console.log('ALC fetchPosts error', arguments);
|
||||
});
|
||||
@ -100,6 +100,11 @@ define([
|
||||
toolsRegion: '.mailpoet_tools',
|
||||
postsRegion: '.mailpoet_automated_latest_content_block_posts',
|
||||
},
|
||||
modelEvents: _.extend(
|
||||
_.omit(base.BlockView.prototype.modelEvents, 'change'),
|
||||
{
|
||||
'postsChanged': 'render',
|
||||
}),
|
||||
events: _.extend(base.BlockView.prototype.events, {
|
||||
'click .mailpoet_automated_latest_content_block_overlay': 'showSettings',
|
||||
}),
|
||||
|
@ -128,24 +128,37 @@ define([
|
||||
}
|
||||
},
|
||||
deleteBlock: function() {
|
||||
this.transitionOut().done(function() {
|
||||
this.transitionOut().then(function() {
|
||||
this.model.destroy();
|
||||
}.bind(this));
|
||||
},
|
||||
transitionIn: function() {
|
||||
return this._transition('mailpoet_block_transition_in');
|
||||
return this._transition('slideDown', 'fadeIn', 'easeIn');
|
||||
},
|
||||
transitionOut: function() {
|
||||
return this._transition('mailpoet_block_transition_out');
|
||||
return this._transition('slideUp', 'fadeOut', 'easeOut');
|
||||
},
|
||||
_transition: function(className) {
|
||||
_transition: function(slideDirection, fadeDirection, easing) {
|
||||
var promise = jQuery.Deferred();
|
||||
|
||||
this.$el.addClass(className);
|
||||
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
|
||||
this.$el.removeClass(className);
|
||||
promise.resolve();
|
||||
}.bind(this));
|
||||
this.$el.velocity(
|
||||
slideDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
complete: function() {
|
||||
promise.resolve();
|
||||
}.bind(this),
|
||||
}
|
||||
).velocity(
|
||||
fadeDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
queue: false, // Do not enqueue, trigger animation in parallel
|
||||
}
|
||||
);
|
||||
|
||||
return promise;
|
||||
},
|
||||
});
|
||||
|
@ -248,20 +248,32 @@ define([
|
||||
}.bind(this));
|
||||
},
|
||||
transitionIn: function() {
|
||||
return this._transition('mailpoet_block_transition_in');
|
||||
return this._transition('slideDown', 'fadeIn', 'easeIn');
|
||||
},
|
||||
transitionOut: function() {
|
||||
return this._transition('mailpoet_block_transition_out');
|
||||
return this._transition('slideUp', 'fadeOut', 'easeOut');
|
||||
},
|
||||
_transition: function(className) {
|
||||
var that = this,
|
||||
promise = jQuery.Deferred();
|
||||
_transition: function(slideDirection, fadeDirection, easing) {
|
||||
var promise = jQuery.Deferred();
|
||||
|
||||
this.$el.velocity(
|
||||
slideDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
complete: function() {
|
||||
promise.resolve();
|
||||
}.bind(this),
|
||||
}
|
||||
).velocity(
|
||||
fadeDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
queue: false, // Do not enqueue, trigger animation in parallel
|
||||
}
|
||||
);
|
||||
|
||||
this.$el.addClass(className);
|
||||
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
|
||||
that.$el.removeClass(className);
|
||||
promise.resolve();
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
});
|
||||
|
@ -97,7 +97,6 @@ define([
|
||||
fetchAvailablePosts: function() {
|
||||
var that = this;
|
||||
CommunicationComponent.getPosts(this.toJSON()).done(function(posts) {
|
||||
console.log('Posts fetched', arguments);
|
||||
that.get('_availablePosts').reset(posts);
|
||||
that.get('_selectedPosts').reset(); // Empty out the collection
|
||||
that.trigger('change:_availablePosts');
|
||||
@ -117,7 +116,6 @@ define([
|
||||
}
|
||||
|
||||
CommunicationComponent.getTransformedPosts(data).done(function(posts) {
|
||||
console.log('Transformed posts fetched', arguments);
|
||||
that.get('_transformedPosts').get('blocks').reset(posts, {parse: true});
|
||||
}).fail(function() {
|
||||
console.log('Posts _refreshTransformedPosts error', arguments);
|
||||
@ -134,7 +132,6 @@ define([
|
||||
if (data.posts.length === 0) return;
|
||||
|
||||
CommunicationComponent.getTransformedPosts(data).done(function(posts) {
|
||||
console.log('Available posts fetched', arguments);
|
||||
collection.add(posts, { at: index });
|
||||
}).fail(function() {
|
||||
console.log('Posts fetchPosts error', arguments);
|
||||
|
@ -208,20 +208,32 @@ define([
|
||||
}.bind(this));
|
||||
},
|
||||
transitionIn: function() {
|
||||
return this._transition('mailpoet_block_transition_in');
|
||||
return this._transition('slideDown', 'fadeIn', 'easeIn');
|
||||
},
|
||||
transitionOut: function() {
|
||||
return this._transition('mailpoet_block_transition_out');
|
||||
return this._transition('slideUp', 'fadeOut', 'easeOut');
|
||||
},
|
||||
_transition: function(className) {
|
||||
var that = this,
|
||||
promise = jQuery.Deferred();
|
||||
_transition: function(slideDirection, fadeDirection, easing) {
|
||||
var promise = jQuery.Deferred();
|
||||
|
||||
this.$el.velocity(
|
||||
slideDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
complete: function() {
|
||||
promise.resolve();
|
||||
}.bind(this),
|
||||
}
|
||||
).velocity(
|
||||
fadeDirection,
|
||||
{
|
||||
duration: 250,
|
||||
easing: easing,
|
||||
queue: false, // Do not enqueue, trigger animation in parallel
|
||||
}
|
||||
);
|
||||
|
||||
this.$el.addClass(className);
|
||||
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
|
||||
that.$el.removeClass(className);
|
||||
promise.resolve();
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
});
|
||||
|
@ -51,8 +51,33 @@ define([
|
||||
},
|
||||
events: {
|
||||
'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function(event) {
|
||||
this.$el.find('.mailpoet_sidebar_region').addClass('closed');
|
||||
this.$el.find(event.target).parent().parent().removeClass('closed');
|
||||
var $openRegion = this.$el.find('.mailpoet_sidebar_region:not(.closed)'),
|
||||
$targetRegion = this.$el.find(event.target).closest('.mailpoet_sidebar_region');
|
||||
|
||||
if ($openRegion.get(0) === $targetRegion.get(0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$openRegion.find('.mailpoet_region_content').velocity(
|
||||
'slideUp',
|
||||
{
|
||||
duration: 250,
|
||||
easing: "easeOut",
|
||||
complete: function() {
|
||||
$openRegion.addClass('closed');
|
||||
}.bind(this)
|
||||
}
|
||||
);
|
||||
$targetRegion.find('.mailpoet_region_content').velocity(
|
||||
'slideDown',
|
||||
{
|
||||
duration: 250,
|
||||
easing: "easeIn",
|
||||
complete: function() {
|
||||
$targetRegion.removeClass('closed');
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
initialize: function(options) {
|
||||
|
@ -17,7 +17,7 @@ define([
|
||||
},
|
||||
h1: {
|
||||
fontColor: '#111111',
|
||||
fontFamily: 'Arial Black',
|
||||
fontFamily: 'Arial',
|
||||
fontSize: '40px'
|
||||
},
|
||||
h2: {
|
||||
|
@ -16,7 +16,7 @@ define(
|
||||
Breadcrumb
|
||||
) {
|
||||
|
||||
var settings = window.mailpoet_settings || {};
|
||||
var settings = window.mailpoet_settings || {};
|
||||
|
||||
var fields = [
|
||||
{
|
||||
@ -24,14 +24,17 @@ define(
|
||||
label: 'Subject line',
|
||||
tip: "Be creative! It's the first thing your subscribers see."+
|
||||
"Tempt them to open your email.",
|
||||
type: 'text'
|
||||
type: 'text',
|
||||
validation: {
|
||||
'data-parsley-required': true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'segments',
|
||||
label: 'Lists',
|
||||
tip: "The subscriber list that will be used for this campaign.",
|
||||
label: 'Segments',
|
||||
tip: "The subscriber segment that will be used for this campaign.",
|
||||
type: 'selection',
|
||||
placeholder: "Select a list",
|
||||
placeholder: "Select a segment",
|
||||
id: "mailpoet_segments",
|
||||
endpoint: "segments",
|
||||
multiple: true,
|
||||
@ -111,12 +114,19 @@ define(
|
||||
action: 'add',
|
||||
data: {
|
||||
newsletter_id: this.props.params.id,
|
||||
segments: jQuery('#mailpoet_segments').val()
|
||||
segments: jQuery('#mailpoet_segments').val(),
|
||||
sender: {
|
||||
'name': jQuery('#mailpoet_newsletter [name="sender_name"]').val(),
|
||||
'address': jQuery('#mailpoet_newsletter [name="sender_address"]').val()
|
||||
},
|
||||
reply_to: {
|
||||
'name': jQuery('#mailpoet_newsletter [name="reply_to_name"]').val(),
|
||||
'address': jQuery('#mailpoet_newsletter [name="reply_to_address"]').val()
|
||||
}
|
||||
}
|
||||
}).done(function(response) {
|
||||
if(response.result === true) {
|
||||
this.history.pushState(null, '/');
|
||||
|
||||
MailPoet.Notice.success(
|
||||
'The newsletter is being sent...'
|
||||
);
|
||||
|
@ -1,75 +1,75 @@
|
||||
define('notice', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
||||
"use strict";
|
||||
/*==================================================================================================
|
||||
|
||||
MailPoet Notice:
|
||||
|
||||
description: Handles notices
|
||||
version: 0.2
|
||||
author: Jonathan Labreuille
|
||||
company: Wysija
|
||||
dependencies: jQuery
|
||||
|
||||
Usage:
|
||||
|
||||
// success message (static: false)
|
||||
MailPoet.Notice.success('Yatta!');
|
||||
|
||||
// error message (static: false)
|
||||
MailPoet.Notice.error('Boo!');
|
||||
|
||||
// system message (static: true)
|
||||
MailPoet.Notice.system('You need to updated ASAP!');
|
||||
|
||||
Examples:
|
||||
|
||||
MailPoet.Notice.success('- success #1 -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.success('- success #2 -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.error('- error -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.system('- system -');
|
||||
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.hide();
|
||||
}, 2500);
|
||||
}, 300);
|
||||
}, 400);
|
||||
}, 500);
|
||||
|
||||
==================================================================================================*/
|
||||
|
||||
MailPoet.Notice = {
|
||||
version: 0.2,
|
||||
// default options
|
||||
defaults: {
|
||||
type: 'success',
|
||||
message: '',
|
||||
static: false,
|
||||
hideClose: false,
|
||||
id: null,
|
||||
define('notice', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
||||
"use strict";
|
||||
/*==================================================================================================
|
||||
|
||||
MailPoet Notice:
|
||||
|
||||
description: Handles notices
|
||||
version: 0.2
|
||||
author: Jonathan Labreuille
|
||||
company: Wysija
|
||||
dependencies: jQuery
|
||||
|
||||
Usage:
|
||||
|
||||
// success message (static: false)
|
||||
MailPoet.Notice.success('Yatta!');
|
||||
|
||||
// error message (static: false)
|
||||
MailPoet.Notice.error('Boo!');
|
||||
|
||||
// system message (static: true)
|
||||
MailPoet.Notice.system('You need to updated ASAP!');
|
||||
|
||||
Examples:
|
||||
|
||||
MailPoet.Notice.success('- success #1 -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.success('- success #2 -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.error('- error -');
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.system('- system -');
|
||||
|
||||
setTimeout(function() {
|
||||
MailPoet.Notice.hide();
|
||||
}, 2500);
|
||||
}, 300);
|
||||
}, 400);
|
||||
}, 500);
|
||||
|
||||
==================================================================================================*/
|
||||
|
||||
MailPoet.Notice = {
|
||||
version: 0.2,
|
||||
// default options
|
||||
defaults: {
|
||||
type: 'success',
|
||||
message: '',
|
||||
static: false,
|
||||
hideClose: false,
|
||||
id: null,
|
||||
positionAfter: false,
|
||||
scroll: false,
|
||||
timeout: 2000,
|
||||
onOpen: null,
|
||||
onClose: null
|
||||
},
|
||||
options: {},
|
||||
init: function(options) {
|
||||
// set options
|
||||
this.options = jQuery.extend({}, this.defaults, options);
|
||||
|
||||
// clone element
|
||||
this.element = jQuery('#mailpoet_notice_'+this.options.type).clone();
|
||||
|
||||
// add data-id to the element
|
||||
if (this.options.id) this.element.attr('data-id', 'notice_' + this.options.id);
|
||||
|
||||
// remove id from clone
|
||||
this.element.removeAttr('id');
|
||||
|
||||
// insert notice after its parent
|
||||
scroll: false,
|
||||
timeout: 2000,
|
||||
onOpen: null,
|
||||
onClose: null
|
||||
},
|
||||
options: {},
|
||||
init: function(options) {
|
||||
// set options
|
||||
this.options = jQuery.extend({}, this.defaults, options);
|
||||
|
||||
// clone element
|
||||
this.element = jQuery('#mailpoet_notice_'+this.options.type).clone();
|
||||
|
||||
// add data-id to the element
|
||||
if (this.options.id) this.element.attr('data-id', 'notice_' + this.options.id);
|
||||
|
||||
// remove id from clone
|
||||
this.element.removeAttr('id');
|
||||
|
||||
// insert notice after its parent
|
||||
var positionAfter;
|
||||
if (typeof this.options.positionAfter === 'object') {
|
||||
positionAfter = this.options.positionAfter;
|
||||
@ -78,136 +78,135 @@ define('notice', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
||||
} else {
|
||||
positionAfter = jQuery('#mailpoet_notice_'+this.options.type);
|
||||
}
|
||||
console.log('positionAfter', typeof this.options.positionAfter);
|
||||
positionAfter.after(this.element);
|
||||
|
||||
// setup onClose callback
|
||||
var onClose = null;
|
||||
if(this.options.onClose !== null) {
|
||||
onClose = this.options.onClose;
|
||||
}
|
||||
|
||||
// listen to remove event
|
||||
jQuery(this.element).on('close', function() {
|
||||
jQuery(this).fadeOut(200, function() {
|
||||
// on close callback
|
||||
if(onClose !== null) {
|
||||
onClose();
|
||||
}
|
||||
// remove notice
|
||||
jQuery(this).remove();
|
||||
});
|
||||
}.bind(this.element));
|
||||
|
||||
// listen to message event
|
||||
jQuery(this.element).on('message', function(e, message) {
|
||||
MailPoet.Notice.setMessage(message);
|
||||
}.bind(this.element));
|
||||
|
||||
return this;
|
||||
},
|
||||
isHTML: function(str) {
|
||||
var a = document.createElement('div');
|
||||
a.innerHTML = str;
|
||||
for(var c = a.childNodes, i = c.length; i--;) {
|
||||
if(c[i].nodeType == 1) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
setMessage: function(message) {
|
||||
// if it's not an html message, let's sugar coat the message with a fancy <p>
|
||||
if(this.isHTML(message) === false) {
|
||||
message = '<p>'+message+'</p>';
|
||||
}
|
||||
// set message
|
||||
return this.element.html(message);
|
||||
},
|
||||
show: function(options) {
|
||||
// initialize
|
||||
this.init(options);
|
||||
|
||||
// show notice
|
||||
this.showNotice();
|
||||
|
||||
// return this;
|
||||
},
|
||||
showNotice: function() {
|
||||
// set message
|
||||
this.setMessage(this.options.message);
|
||||
|
||||
// position notice
|
||||
this.element.insertAfter(jQuery('h2.title'));
|
||||
|
||||
// set class name
|
||||
switch(this.options.type) {
|
||||
case 'success':
|
||||
this.element.addClass('updated');
|
||||
break;
|
||||
case 'system':
|
||||
this.element.addClass('update-nag');
|
||||
break;
|
||||
case 'error':
|
||||
this.element.addClass('error');
|
||||
break;
|
||||
}
|
||||
|
||||
// make the notice appear
|
||||
this.element.fadeIn(200);
|
||||
|
||||
// if scroll option is enabled, scroll to the notice
|
||||
if(this.options.scroll === true) {
|
||||
this.element.get(0).scrollIntoView(false);
|
||||
}
|
||||
|
||||
// if the notice is not static, it has to disappear after a timeout
|
||||
if(this.options.static === false) {
|
||||
this.element.delay(this.options.timeout).trigger('close');
|
||||
} else if (this.options.hideClose === false) {
|
||||
this.element.append('<a href="javascript:;" class="mailpoet_notice_close"><span class="dashicons dashicons-dismiss"></span></a>');
|
||||
this.element.find('.mailpoet_notice_close').on('click', function() {
|
||||
jQuery(this).trigger('close');
|
||||
});
|
||||
}
|
||||
|
||||
// call onOpen callback
|
||||
if(this.options.onOpen !== null) {
|
||||
this.options.onOpen(this.element);
|
||||
}
|
||||
},
|
||||
hide: function(all) {
|
||||
if(all !== undefined && all === true) {
|
||||
jQuery('.mailpoet_notice:not([id])').trigger('close');
|
||||
} else if (all !== undefined && jQuery.isArray(all)) {
|
||||
for (var id in all) {
|
||||
jQuery('[data-id="notice_' + all[id] + '"]')
|
||||
.trigger('close');
|
||||
}
|
||||
} if (all !== undefined) {
|
||||
jQuery('[data-id="notice_' + all + '"]')
|
||||
.trigger('close');
|
||||
} else {
|
||||
jQuery('.mailpoet_notice.updated:not([id]), .mailpoet_notice.error:not([id])')
|
||||
.trigger('close');
|
||||
}
|
||||
},
|
||||
error: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'error',
|
||||
message: '<p>'+message+'</p>'
|
||||
}, options));
|
||||
},
|
||||
success: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'success',
|
||||
message: '<p>'+message+'</p>'
|
||||
}, options));
|
||||
},
|
||||
system: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'system',
|
||||
static: true,
|
||||
message: message
|
||||
}, options));
|
||||
}
|
||||
};
|
||||
positionAfter.after(this.element);
|
||||
|
||||
// setup onClose callback
|
||||
var onClose = null;
|
||||
if(this.options.onClose !== null) {
|
||||
onClose = this.options.onClose;
|
||||
}
|
||||
|
||||
// listen to remove event
|
||||
jQuery(this.element).on('close', function() {
|
||||
jQuery(this).fadeOut(200, function() {
|
||||
// on close callback
|
||||
if(onClose !== null) {
|
||||
onClose();
|
||||
}
|
||||
// remove notice
|
||||
jQuery(this).remove();
|
||||
});
|
||||
}.bind(this.element));
|
||||
|
||||
// listen to message event
|
||||
jQuery(this.element).on('message', function(e, message) {
|
||||
MailPoet.Notice.setMessage(message);
|
||||
}.bind(this.element));
|
||||
|
||||
return this;
|
||||
},
|
||||
isHTML: function(str) {
|
||||
var a = document.createElement('div');
|
||||
a.innerHTML = str;
|
||||
for(var c = a.childNodes, i = c.length; i--;) {
|
||||
if(c[i].nodeType == 1) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
setMessage: function(message) {
|
||||
// if it's not an html message, let's sugar coat the message with a fancy <p>
|
||||
if(this.isHTML(message) === false) {
|
||||
message = '<p>'+message+'</p>';
|
||||
}
|
||||
// set message
|
||||
return this.element.html(message);
|
||||
},
|
||||
show: function(options) {
|
||||
// initialize
|
||||
this.init(options);
|
||||
|
||||
// show notice
|
||||
this.showNotice();
|
||||
|
||||
// return this;
|
||||
},
|
||||
showNotice: function() {
|
||||
// set message
|
||||
this.setMessage(this.options.message);
|
||||
|
||||
// position notice
|
||||
this.element.insertAfter(jQuery('h2.title'));
|
||||
|
||||
// set class name
|
||||
switch(this.options.type) {
|
||||
case 'success':
|
||||
this.element.addClass('updated');
|
||||
break;
|
||||
case 'system':
|
||||
this.element.addClass('update-nag');
|
||||
break;
|
||||
case 'error':
|
||||
this.element.addClass('error');
|
||||
break;
|
||||
}
|
||||
|
||||
// make the notice appear
|
||||
this.element.fadeIn(200);
|
||||
|
||||
// if scroll option is enabled, scroll to the notice
|
||||
if(this.options.scroll === true) {
|
||||
this.element.get(0).scrollIntoView(false);
|
||||
}
|
||||
|
||||
// if the notice is not static, it has to disappear after a timeout
|
||||
if(this.options.static === false) {
|
||||
this.element.delay(this.options.timeout).trigger('close');
|
||||
} else if (this.options.hideClose === false) {
|
||||
this.element.append('<a href="javascript:;" class="mailpoet_notice_close"><span class="dashicons dashicons-dismiss"></span></a>');
|
||||
this.element.find('.mailpoet_notice_close').on('click', function() {
|
||||
jQuery(this).trigger('close');
|
||||
});
|
||||
}
|
||||
|
||||
// call onOpen callback
|
||||
if(this.options.onOpen !== null) {
|
||||
this.options.onOpen(this.element);
|
||||
}
|
||||
},
|
||||
hide: function(all) {
|
||||
if(all !== undefined && all === true) {
|
||||
jQuery('.mailpoet_notice:not([id])').trigger('close');
|
||||
} else if (all !== undefined && jQuery.isArray(all)) {
|
||||
for (var id in all) {
|
||||
jQuery('[data-id="notice_' + all[id] + '"]')
|
||||
.trigger('close');
|
||||
}
|
||||
} if (all !== undefined) {
|
||||
jQuery('[data-id="notice_' + all + '"]')
|
||||
.trigger('close');
|
||||
} else {
|
||||
jQuery('.mailpoet_notice.updated:not([id]), .mailpoet_notice.error:not([id])')
|
||||
.trigger('close');
|
||||
}
|
||||
},
|
||||
error: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'error',
|
||||
message: '<p>'+message+'</p>'
|
||||
}, options));
|
||||
},
|
||||
success: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'success',
|
||||
message: '<p>'+message+'</p>'
|
||||
}, options));
|
||||
},
|
||||
system: function(message, options) {
|
||||
this.show(jQuery.extend({}, {
|
||||
type: 'system',
|
||||
static: true,
|
||||
message: message
|
||||
}, options));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -62,7 +62,7 @@ define(
|
||||
if (_.contains(fieldsToExclude, selectedOptionId)) {
|
||||
selectEvent.preventDefault();
|
||||
if (selectedOptionId === 'deselect') {
|
||||
jQuery(selectElement).select2('val', '');
|
||||
jQuery(selectElement).val('').trigger('change');
|
||||
} else {
|
||||
var allOptions = [];
|
||||
_.each(container.find('option'), function (field) {
|
||||
@ -70,7 +70,7 @@ define(
|
||||
allOptions.push(field.value);
|
||||
}
|
||||
});
|
||||
jQuery(selectElement).select2('val', allOptions);
|
||||
jQuery(selectElement).val(allOptions).trigger('change');
|
||||
}
|
||||
jQuery(selectElement).select2('close');
|
||||
}
|
||||
@ -138,11 +138,11 @@ define(
|
||||
endpoint: 'ImportExport',
|
||||
action: 'processExport',
|
||||
data: JSON.stringify({
|
||||
'exportConfirmedOption': exportData.exportConfirmedOption,
|
||||
'exportFormatOption': jQuery(':radio[name="option_format"]:checked').val(),
|
||||
'groupBySegmentOption': (groupBySegmentOptionElement.is(":visible")) ? groupBySegmentOptionElement.prop('checked') : false,
|
||||
'export_confirmed_option': exportData.exportConfirmedOption,
|
||||
'export_format_option': jQuery(':radio[name="option_format"]:checked').val(),
|
||||
'group_by_segment_option': (groupBySegmentOptionElement.is(":visible")) ? groupBySegmentOptionElement.prop('checked') : false,
|
||||
'segments': (exportData.segments) ? segmentsContainerElement.val() : false,
|
||||
'subscriberFields': subscriberFieldsContainerElement.val()
|
||||
'subscriber_fields': subscriberFieldsContainerElement.val()
|
||||
})
|
||||
})
|
||||
.done(function (response) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,15 +6,14 @@ if(!defined('ABSPATH')) exit;
|
||||
class Env {
|
||||
static $version;
|
||||
static $plugin_name;
|
||||
static $plugin_url;
|
||||
static $plugin_path;
|
||||
static $file;
|
||||
static $path;
|
||||
static $views_path;
|
||||
static $assets_path;
|
||||
static $assets_url;
|
||||
static $temp_name;
|
||||
static $temp_path;
|
||||
static $temp_URL;
|
||||
static $languages_path;
|
||||
static $lib_path;
|
||||
static $plugin_prefix;
|
||||
@ -34,12 +33,11 @@ class Env {
|
||||
self::$file = $file;
|
||||
self::$path = dirname(self::$file);
|
||||
self::$plugin_name = 'mailpoet';
|
||||
self::$plugin_url = plugin_dir_url(__FILE__);
|
||||
self::$views_path = self::$path . '/views';
|
||||
self::$assets_path = self::$path . '/assets';
|
||||
self::$assets_url = plugins_url('/assets', $file);
|
||||
self::$temp_name = 'temp';
|
||||
self::$temp_path = self::$path . '/' . self::$temp_name;
|
||||
self::$temp_path = wp_upload_dir()['path'];
|
||||
self::$temp_URL = wp_upload_dir()['url'];
|
||||
self::$languages_path = self::$path . '/lang';
|
||||
self::$lib_path = self::$path . '/lib';
|
||||
self::$plugin_prefix = 'mailpoet_';
|
||||
|
@ -75,7 +75,7 @@ class Initializer {
|
||||
define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
|
||||
define('MP_NEWSLETTER_OPTION_FIELDS_TABLE', $newsletter_option_fields);
|
||||
define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option);
|
||||
define('MP_SENDING_QUEUE_TABLE', $sending_queues);
|
||||
define('MP_SENDING_QUEUES_TABLE', $sending_queues);
|
||||
define('MP_NEWSLETTER_STATISTICS_TABLE', $newsletter_statistics);
|
||||
}
|
||||
|
||||
@ -113,7 +113,6 @@ class Initializer {
|
||||
}
|
||||
|
||||
function setupAnalytics() {
|
||||
|
||||
$widget = new Analytics();
|
||||
$widget->init();
|
||||
}
|
||||
@ -143,13 +142,15 @@ class Initializer {
|
||||
}
|
||||
|
||||
function runQueueSupervisor() {
|
||||
if(php_sapi_name() === 'cli') return;
|
||||
try {
|
||||
$supervisor = new Supervisor();
|
||||
$supervisor->checkDaemon();
|
||||
} catch (\Exception $e) {}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
function setupImages() {
|
||||
add_image_size('mailpoet_newsletter_max', 1320);
|
||||
}
|
||||
}
|
||||
}
|
@ -179,7 +179,7 @@ class BlankTemplate {
|
||||
),
|
||||
"h1" => array(
|
||||
"fontColor" => "#111111",
|
||||
"fontFamily" => "Arial Black",
|
||||
"fontFamily" => "Arial",
|
||||
"fontSize" => "24px"
|
||||
),
|
||||
"h2" => array(
|
||||
|
@ -7,15 +7,20 @@ use MailPoet\Util\Helpers;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class PublicAPI {
|
||||
public $api;
|
||||
public $section;
|
||||
public $action;
|
||||
public $request_payload;
|
||||
|
||||
function __construct() {
|
||||
# http://example.com/?mailpoet-api§ion=&action=&payload=
|
||||
# http://example.com/?mailpoet-api§ion=&action=&request_payload=
|
||||
$this->api = isset($_GET['mailpoet-api']) ? true : false;
|
||||
$this->section = isset($_GET['section']) ? $_GET['section'] : false;
|
||||
$this->action = isset($_GET['action']) ?
|
||||
Helpers::underscoreToCamelCase($_GET['action']) :
|
||||
false;
|
||||
$this->payload = isset($_GET['payload']) ?
|
||||
json_decode(urldecode($_GET['payload']), true) :
|
||||
$this->request_payload = isset($_GET['request_payload']) ?
|
||||
json_decode(urldecode($_GET['request_payload']), true) :
|
||||
false;
|
||||
}
|
||||
|
||||
@ -26,10 +31,9 @@ class PublicAPI {
|
||||
|
||||
function queue() {
|
||||
try {
|
||||
$queue = new Daemon($this->payload);
|
||||
$queue = new Daemon($this->request_payload);
|
||||
$this->_checkAndCallMethod($queue, $this->action);
|
||||
} catch(\Exception $e) {
|
||||
// mailer configuration error
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,86 +10,99 @@ require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Daemon {
|
||||
function __construct($payload = array()) {
|
||||
public $daemon;
|
||||
public $request_payload;
|
||||
public $refreshed_token;
|
||||
public $timer;
|
||||
|
||||
function __construct($request_payload = array()) {
|
||||
set_time_limit(0);
|
||||
ignore_user_abort();
|
||||
list ($this->daemon, $this->daemonData) = $this->getDaemon();
|
||||
$this->refreshedToken = $this->refreshToken();
|
||||
$this->payload = $payload;
|
||||
$this->daemon = $this->getDaemon();
|
||||
$this->refreshed_token = $this->refreshToken();
|
||||
$this->request_payload = $request_payload;
|
||||
$this->timer = microtime(true);
|
||||
}
|
||||
|
||||
function start() {
|
||||
if(!isset($this->payload['session'])) {
|
||||
$this->abortWithError('missing session ID');
|
||||
if(!isset($this->request_payload['session'])) {
|
||||
$this->abortWithError(__('Missing session ID.'));
|
||||
}
|
||||
$this->manageSession('start');
|
||||
$daemon = $this->daemon;
|
||||
$daemonData = $this->daemonData;
|
||||
if(!$daemon) {
|
||||
$daemon = Setting::create();
|
||||
$daemon->name = 'cron_daemon';
|
||||
$daemonData = array(
|
||||
'status' => null,
|
||||
'counter' => 0
|
||||
$this->saveDaemon(
|
||||
array(
|
||||
'status' => 'starting',
|
||||
'counter' => 0
|
||||
)
|
||||
);
|
||||
$daemon->value = json_encode($daemonData);
|
||||
$daemon->save();
|
||||
}
|
||||
if($daemonData['status'] !== 'started') {
|
||||
$_SESSION['cron_daemon'] = 'started';
|
||||
$daemonData['status'] = 'started';
|
||||
$daemonData['token'] = $this->refreshedToken;
|
||||
$_SESSION['cron_daemon'] = array('result' => true);
|
||||
$this->manageSession('end');
|
||||
$daemon->value = json_encode($daemonData);
|
||||
$daemon->save();
|
||||
$this->callSelf();
|
||||
} else {
|
||||
if($daemon['status'] === 'started') {
|
||||
$_SESSION['cron_daemon'] = array(
|
||||
'result' => false,
|
||||
'error' => 'already started'
|
||||
'errors' => array(__('Daemon already running.'))
|
||||
);
|
||||
}
|
||||
if($daemon['status'] === 'starting') {
|
||||
$_SESSION['cron_daemon'] = 'started';
|
||||
$_SESSION['cron_daemon'] = array('result' => true);
|
||||
$this->manageSession('end');
|
||||
$daemon['status'] = 'started';
|
||||
$daemon['token'] = $this->refreshed_token;
|
||||
$this->saveDaemon($daemon);
|
||||
$this->callSelf();
|
||||
}
|
||||
$this->manageSession('end');
|
||||
}
|
||||
|
||||
function run() {
|
||||
if(!$this->daemon || $this->daemonData['status'] !== 'started') {
|
||||
$this->abortWithError('not running');
|
||||
$allowed_statuses = array(
|
||||
'stopping',
|
||||
'starting',
|
||||
'started'
|
||||
);
|
||||
if(!$this->daemon || !in_array($this->daemon['status'], $allowed_statuses)) {
|
||||
$this->abortWithError(__('Invalid daemon status.'));
|
||||
}
|
||||
if(!isset($this->payload['token']) ||
|
||||
$this->payload['token'] !== $this->daemonData['token']
|
||||
if(!isset($this->request_payload['token']) ||
|
||||
$this->request_payload['token'] !== $this->daemon['token']
|
||||
) {
|
||||
$this->abortWithError('invalid token');
|
||||
$this->abortWithError('Invalid token.');
|
||||
}
|
||||
|
||||
try {
|
||||
$sendingQueue = new SendingQueue($this->timer);
|
||||
$sendingQueue->process();
|
||||
$sending_queue = new SendingQueue($this->timer);
|
||||
$sending_queue->process();
|
||||
} catch(Exception $e) {
|
||||
}
|
||||
|
||||
$elapsedTime = microtime(true) - $this->timer;
|
||||
if($elapsedTime < 30) {
|
||||
sleep(30 - $elapsedTime);
|
||||
$elapsed_time = microtime(true) - $this->timer;
|
||||
if($elapsed_time < 30) {
|
||||
sleep(30 - $elapsed_time);
|
||||
}
|
||||
// after each execution, read daemon in case its status was modified
|
||||
$daemon = $this->getDaemon();
|
||||
|
||||
// after each execution, read daemon in case it's status was modified
|
||||
list($daemon, $daemonData) = $this->getDaemon();
|
||||
$daemonData['counter']++;
|
||||
$daemonData['token'] = $this->refreshedToken;
|
||||
$daemon->value = json_encode($daemonData);
|
||||
$daemon->save();
|
||||
if($daemonData['status'] === 'strated') $this->callSelf();
|
||||
if($daemon['status'] === 'stopping') $daemon['status'] = 'stopped';
|
||||
if($daemon['status'] === 'starting') $daemon['status'] = 'started';
|
||||
|
||||
$daemon['token'] = $this->refreshed_token;
|
||||
$daemon['counter']++;
|
||||
|
||||
$this->saveDaemon($daemon);
|
||||
|
||||
if($daemon['status'] === 'started') $this->callSelf();
|
||||
}
|
||||
|
||||
function getDaemon() {
|
||||
$daemon = Setting::where('name', 'cron_daemon')
|
||||
->findOne();
|
||||
return array(
|
||||
($daemon) ? $daemon : null,
|
||||
($daemon) ? json_decode($daemon->value, true) : null
|
||||
return Setting::getValue('cron_daemon');
|
||||
}
|
||||
|
||||
function saveDaemon($daemon_data) {
|
||||
$daemon_data['updated_at'] = time();
|
||||
|
||||
return Setting::setValue(
|
||||
'cron_daemon',
|
||||
$daemon_data
|
||||
);
|
||||
}
|
||||
|
||||
@ -99,24 +112,23 @@ class Daemon {
|
||||
|
||||
function manageSession($action) {
|
||||
switch($action) {
|
||||
case 'start':
|
||||
if(session_id()) {
|
||||
session_write_close();
|
||||
}
|
||||
session_id($this->payload['session']);
|
||||
session_start();
|
||||
break;
|
||||
case 'end':
|
||||
case 'start':
|
||||
if(session_id()) {
|
||||
session_write_close();
|
||||
break;
|
||||
}
|
||||
session_id($this->request_payload['session']);
|
||||
session_start();
|
||||
break;
|
||||
case 'end':
|
||||
session_write_close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function callSelf() {
|
||||
$payload = json_encode(array('token' => $this->refreshedToken));
|
||||
Supervisor::getRemoteUrl(
|
||||
'/?mailpoet-api§ion=queue&action=run&payload=' . urlencode($payload)
|
||||
|
||||
$payload = json_encode(array('token' => $this->refreshed_token));
|
||||
Supervisor::accessRemoteUrl(
|
||||
'/?mailpoet-api§ion=queue&action=run&request_payload=' . urlencode($payload)
|
||||
);
|
||||
exit;
|
||||
}
|
||||
@ -125,7 +137,7 @@ class Daemon {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => $error
|
||||
'errors' => array($error)
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
@ -1,38 +1,47 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Config\Env;
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Supervisor {
|
||||
function __construct($forceStart = false) {
|
||||
$this->forceStart = $forceStart;
|
||||
public $daemon;
|
||||
|
||||
function __construct($force_start = false) {
|
||||
$this->force_start = $force_start;
|
||||
if(!Env::isPluginActivated()) {
|
||||
throw new \Exception('Database has not been configured.');
|
||||
throw new \Exception(__('MailPoet is not activated.'));
|
||||
}
|
||||
list ($this->daemon, $this->daemonData) = $this->getDaemon();
|
||||
$this->daemon = $this->getDaemon();
|
||||
}
|
||||
|
||||
function checkDaemon() {
|
||||
if(!$this->daemon) {
|
||||
return $this->startDaemon();
|
||||
}
|
||||
if(!$this->forceStart && $this->daemonData['status'] === 'stopped') {
|
||||
return;
|
||||
if(
|
||||
!$this->force_start &&
|
||||
in_array($this->daemon['status'], array('stopped', 'stopping'))
|
||||
) {
|
||||
return $this->daemon['status'];
|
||||
}
|
||||
$currentTime = Carbon::now('UTC');
|
||||
$lastUpdateTime = Carbon::createFromFormat(
|
||||
'Y-m-d H:i:s',
|
||||
$this->daemon->updated_at, 'UTC'
|
||||
);
|
||||
$timeSinceLastStart = $currentTime->diffInSeconds($lastUpdateTime);
|
||||
if($timeSinceLastStart < 40) return;
|
||||
$this->daemonData['status'] = null;
|
||||
$this->daemon->value = json_encode($this->daemonData);
|
||||
$this->daemon->save();
|
||||
|
||||
$elapsed_time = time() - (int)$this->daemon['updated_at'];
|
||||
|
||||
if($elapsed_time < 40) {
|
||||
if(!$this->force_start) {
|
||||
return;
|
||||
}
|
||||
if($this->daemon['status'] === 'stopping' ||
|
||||
$this->daemon['status'] === 'starting'
|
||||
) {
|
||||
return $this->daemon['status'];
|
||||
}
|
||||
}
|
||||
$this->daemon['status'] = 'starting';
|
||||
$this->saveDaemon($this->daemon);
|
||||
return $this->startDaemon();
|
||||
}
|
||||
|
||||
@ -41,9 +50,10 @@ class Supervisor {
|
||||
$sessionId = session_id();
|
||||
session_write_close();
|
||||
$_SESSION['cron_daemon'] = null;
|
||||
$payload = json_encode(array('session' => $sessionId));
|
||||
self::getRemoteUrl(
|
||||
'/?mailpoet-api§ion=queue&action=start&payload=' . urlencode($payload)
|
||||
$requestPayload = json_encode(array('session' => $sessionId));
|
||||
self::accessRemoteUrl(
|
||||
'/?mailpoet-api§ion=queue&action=start&request_payload=' .
|
||||
urlencode($requestPayload)
|
||||
);
|
||||
session_start();
|
||||
$daemonStatus = $_SESSION['cron_daemon'];
|
||||
@ -53,19 +63,20 @@ class Supervisor {
|
||||
}
|
||||
|
||||
function getDaemon() {
|
||||
$daemon = Setting::where('name', 'cron_daemon')
|
||||
->findOne();
|
||||
$daemonData = ($daemon) ? json_decode($daemon->value, true) : false;
|
||||
return array(
|
||||
$daemon,
|
||||
$daemonData
|
||||
return Setting::getValue('cron_daemon');
|
||||
}
|
||||
|
||||
function saveDaemon($daemon_data) {
|
||||
return Setting::setValue(
|
||||
'cron_daemon',
|
||||
$daemon_data
|
||||
);
|
||||
}
|
||||
|
||||
static function getRemoteUrl($url) {
|
||||
static function accessRemoteUrl($url) {
|
||||
$args = array(
|
||||
'timeout' => 1,
|
||||
'user-agent' => 'MailPoet (www.mailpoet.com)'
|
||||
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
|
||||
);
|
||||
wp_remote_get(
|
||||
self::getSiteUrl() . $url,
|
||||
@ -74,11 +85,19 @@ class Supervisor {
|
||||
}
|
||||
|
||||
static function getSiteUrl() {
|
||||
if(preg_match('!:\d+/!', site_url())) return site_url();
|
||||
preg_match('!http://(?P<host>.*?):(?P<port>\d+)!', site_url(), $server);
|
||||
// additional check for some sites running on a virtual machine or behind
|
||||
// proxy where there could be different ports (e.g., host:8080 => guest:80)
|
||||
|
||||
// if the site URL does not contain a port, return the URL
|
||||
if(!preg_match('!^https?://.*?:\d+!', site_url())) return site_url();
|
||||
preg_match('!://(?P<host>.*?):(?P<port>\d+)!', site_url(), $server);
|
||||
// connect to the URL with port
|
||||
$fp = @fsockopen($server['host'], $server['port'], $errno, $errstr, 1);
|
||||
return ($fp) ?
|
||||
site_url() :
|
||||
preg_replace('/(?=:\d+):\d+/', '$1', site_url());
|
||||
if($fp) return site_url();
|
||||
// connect to the URL without port
|
||||
$fp = @fsockopen($server['host'], $server['port'], $errno, $errstr, 1);
|
||||
if($fp) return preg_replace('!(?=:\d+):\d+!', '$1', site_url());
|
||||
// throw an error if all connections fail
|
||||
throw new \Exception(__('Site URL is unreachable.'));
|
||||
}
|
||||
}
|
@ -1,114 +1,134 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers;
|
||||
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterStatistics;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Router\Mailer;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingQueue {
|
||||
public $timer;
|
||||
|
||||
function __construct($timer = false) {
|
||||
$this->timer = ($timer) ? $timer : microtime(true);
|
||||
}
|
||||
|
||||
function process() {
|
||||
$queues =
|
||||
\MailPoet\Models\SendingQueue::orderByDesc('priority')
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
||||
->findResultSet();
|
||||
foreach($queues as $queue) {
|
||||
$newsletter = Newsletter::findOne($queue->newsletter_id);
|
||||
// TODO: implement mailer sending frequency limits
|
||||
foreach($this->getQueues() as $queue) {
|
||||
$newsletter = Newsletter::findOne($queue->newsletter_id)
|
||||
->asArray();
|
||||
if(!$newsletter) {
|
||||
continue;
|
||||
};
|
||||
$newsletter = $newsletter->asArray();
|
||||
$mailer = new Mailer($httpRequest = false);
|
||||
if(!empty($newsletter['sender_address']) &&
|
||||
!empty($newsletter['sender_name'])
|
||||
) {
|
||||
$mailer->fromName = $newsletter['sender_name'];
|
||||
$mailer->fromEmail = $newsletter['sender_address'];
|
||||
$mailer->fromNameEmail = sprintf(
|
||||
'%s <%s>',
|
||||
$mailer->fromName,
|
||||
$mailer->fromEmail
|
||||
);
|
||||
}
|
||||
if(!empty($newsletter['reply_to_address']) &&
|
||||
!empty($newsletter['reply_to_name'])
|
||||
) {
|
||||
$mailer->replyToName = $newsletter['reply_to_name'];
|
||||
$mailer->replyToEmail = $newsletter['reply_to_address'];
|
||||
$mailer->replyToNameEmail = sprintf(
|
||||
'%s <%s>',
|
||||
$mailer->replyToName,
|
||||
$mailer->replyToEmail
|
||||
);
|
||||
}
|
||||
$mailer->mailer = $mailer->buildMailer();
|
||||
$renderer = new Renderer(json_decode($newsletter['body'], true));
|
||||
$newsletter = array(
|
||||
'subject' => $newsletter['subject'],
|
||||
'id' => $newsletter['id'],
|
||||
'body' => array(
|
||||
'html' => $renderer->renderAll(),
|
||||
'text' => ''
|
||||
// TODO: add text body
|
||||
)
|
||||
);
|
||||
$mailer = $this->configureMailerForNewsletter($newsletter);
|
||||
$newsletter = $this->renderNewsletter($newsletter);
|
||||
$subscribers = json_decode($queue->subscribers, true);
|
||||
$subscribersToProcess = $subscribers['to_process'];
|
||||
if(!isset($subscribers['failed'])) $subscribers['failed'] = array();
|
||||
$subscribers_to_process = $subscribers['to_process'];
|
||||
if(!isset($subscribers['processed'])) $subscribers['processed'] = array();
|
||||
foreach(array_chunk($subscribersToProcess, 200) as $subscriberIds) {
|
||||
$dbSubscribers = Subscriber::whereIn('id', $subscriberIds)
|
||||
if(!isset($subscribers['failed'])) $subscribers['failed'] = array();
|
||||
foreach(array_chunk($subscribers_to_process, 200) as $subscriber_ids) {
|
||||
$db_subscribers = Subscriber::whereIn('id', $subscriber_ids)
|
||||
->findArray();
|
||||
foreach($dbSubscribers as $i => $dbSubscriber) {
|
||||
foreach($db_subscribers as $db_subscriber) {
|
||||
$this->checkExecutionTimer();
|
||||
// TODO: replace shortcodes in the newsletter
|
||||
$result = $mailer->mailer->send(
|
||||
$newsletter,
|
||||
$mailer->transformSubscriber($dbSubscriber)
|
||||
);
|
||||
$newsletterStatistics = NewsletterStatistics::create();
|
||||
$newsletterStatistics->subscriber_id = $dbSubscriber['id'];
|
||||
$newsletterStatistics->newsletter_id = $newsletter['id'];
|
||||
$newsletterStatistics->queue_id = $queue->id;
|
||||
$newsletterStatistics->save();
|
||||
$result = $this->sendNewsletter(
|
||||
$mailer,
|
||||
$this->processNewsletter($newsletter),
|
||||
$db_subscriber);
|
||||
if($result) {
|
||||
$subscribers['processed'][] = $dbSubscriber['id'];
|
||||
$this->updateStatistics($newsletter['id'], $db_subscriber['id'], $queue->id);
|
||||
$subscribers['processed'][] = $db_subscriber['id'];
|
||||
} else {
|
||||
$subscribers['failed'][] = $dbSubscriber['id'];
|
||||
$subscribers['failed'][] = $db_subscriber['id'];
|
||||
}
|
||||
$subscribers['to_process'] = array_values(
|
||||
array_diff(
|
||||
$subscribers['to_process'],
|
||||
array_merge($subscribers['processed'], $subscribers['failed'])
|
||||
)
|
||||
);
|
||||
$queue->count_processed =
|
||||
count($subscribers['processed']) + count($subscribers['failed']);
|
||||
$queue->count_to_process = count($subscribers['to_process']);
|
||||
$queue->count_failed = count($subscribers['failed']);
|
||||
$queue->count_total =
|
||||
$queue->count_processed + $queue->count_to_process;
|
||||
if(!$queue->count_to_process) {
|
||||
$queue->processed_at = date('Y-m-d H:i:s');
|
||||
$queue->status = 'completed';
|
||||
}
|
||||
$queue->subscribers = json_encode($subscribers);
|
||||
$queue->save();
|
||||
$this->updateQueue($queue, $subscribers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processNewsletter($newsletter) {
|
||||
// TODO: replace shortcodes, etc..
|
||||
return $newsletter;
|
||||
}
|
||||
|
||||
function sendNewsletter($mailer, $newsletter, $subscriber) {
|
||||
return $mailer->mailer_instance->send(
|
||||
$newsletter,
|
||||
$mailer->transformSubscriber($subscriber)
|
||||
);
|
||||
}
|
||||
|
||||
function updateStatistics($newsletter_id, $subscriber_id, $queue_id) {
|
||||
$newsletter_statistic = NewsletterStatistics::create();
|
||||
$newsletter_statistic->subscriber_id = $newsletter_id;
|
||||
$newsletter_statistic->newsletter_id = $subscriber_id;
|
||||
$newsletter_statistic->queue_id = $queue_id;
|
||||
$newsletter_statistic->save();
|
||||
}
|
||||
|
||||
function updateQueue($queue, $subscribers) {
|
||||
$subscribers['to_process'] = array_values(
|
||||
array_diff(
|
||||
$subscribers['to_process'],
|
||||
array_merge($subscribers['processed'], $subscribers['failed'])
|
||||
)
|
||||
);
|
||||
$queue->count_processed =
|
||||
count($subscribers['processed']) + count($subscribers['failed']);
|
||||
$queue->count_to_process = count($subscribers['to_process']);
|
||||
$queue->count_failed = count($subscribers['failed']);
|
||||
$queue->count_total =
|
||||
$queue->count_processed + $queue->count_to_process;
|
||||
if(!$queue->count_to_process) {
|
||||
$queue->processed_at = date('Y-m-d H:i:s');
|
||||
$queue->status = 'completed';
|
||||
}
|
||||
$queue->subscribers = json_encode($subscribers);
|
||||
$queue->save();
|
||||
}
|
||||
|
||||
function configureMailerForNewsletter($newsletter) {
|
||||
if(!empty($newsletter['sender_address']) && !empty($newsletter['sender_name'])) {
|
||||
$sender = array(
|
||||
'name' => $newsletter['sender_name'],
|
||||
'address' => $newsletter['sender_address']
|
||||
);
|
||||
} else {
|
||||
$sender = false;
|
||||
}
|
||||
if(!empty($newsletter['reply_to_address']) && !empty($newsletter['reply_to_name'])) {
|
||||
$reply_to = array(
|
||||
'name' => $newsletter['reply_to_name'],
|
||||
'address' => $newsletter['reply_to_address']
|
||||
);
|
||||
} else {
|
||||
$reply_to = false;
|
||||
}
|
||||
$mailer = new Mailer($method = false, $sender, $reply_to);
|
||||
return $mailer;
|
||||
}
|
||||
|
||||
function checkExecutionTimer() {
|
||||
$elapsedTime = microtime(true) - $this->timer;
|
||||
if($elapsedTime >= 28) throw new \Exception('Maximum execution time reached.');
|
||||
$elapsed_time = microtime(true) - $this->timer;
|
||||
if($elapsed_time >= 30) throw new \Exception('Maximum execution time reached.');
|
||||
}
|
||||
|
||||
function getQueues() {
|
||||
return \MailPoet\Models\SendingQueue::orderByDesc('priority')
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
||||
->findResultSet();
|
||||
}
|
||||
|
||||
function renderNewsletter($newsletter) {
|
||||
$renderer = new Renderer(json_decode($newsletter['body'], true));
|
||||
// TODO: update once text rendering is implemented/enderer returns an array
|
||||
$newsletter['body'] = array('html' => $renderer->render(), 'text' => '');
|
||||
return $newsletter;
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\API;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class AmazonSES {
|
||||
function __construct($region, $accessKey, $secretKey, $from) {
|
||||
$this->awsAccessKey = $accessKey;
|
||||
$this->awsSecret_key = $secretKey;
|
||||
$this->awsRegion = $region;
|
||||
$this->awsEndpoint = sprintf('email.%s.amazonaws.com', $region);
|
||||
$this->awsSigningAlgorithm = 'AWS4-HMAC-SHA256';
|
||||
$this->awsService = 'ses';
|
||||
$this->awsTerminationString = 'aws4_request';
|
||||
$this->hashAlgorithm = 'sha256';
|
||||
$this->url = 'https://' . $this->awsEndpoint;
|
||||
$this->from = $from;
|
||||
$this->date = gmdate('Ymd\THis\Z');
|
||||
$this->dateWithoutTime = gmdate('Ymd');
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
$result = wp_remote_post(
|
||||
$this->url,
|
||||
$this->request($newsletter, $subscriber)
|
||||
);
|
||||
return (
|
||||
!is_wp_error($result) === true &&
|
||||
wp_remote_retrieve_response_code($result) === 200
|
||||
);
|
||||
}
|
||||
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'Action' => 'SendEmail',
|
||||
'Version' => '2010-12-01',
|
||||
'Source' => $this->from,
|
||||
'Destination.ToAddresses.member.1' => $subscriber,
|
||||
'Message.Subject.Data' => $newsletter['subject'],
|
||||
'ReturnPath' => $this->from
|
||||
);
|
||||
if(!empty($newsletter['body']['html'])) {
|
||||
$body['Message.Body.Html.Data'] = $newsletter['body']['html'];
|
||||
}
|
||||
if(!empty($newsletter['body']['text'])) {
|
||||
$body['Message.Body.Text.Data'] = $newsletter['body']['text'];
|
||||
}
|
||||
return $body;
|
||||
}
|
||||
|
||||
function request($newsletter, $subscriber) {
|
||||
$body = $this->getBody($newsletter, $subscriber);
|
||||
return array(
|
||||
'timeout' => 10,
|
||||
'httpversion' => '1.1',
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Host' => $this->awsEndpoint,
|
||||
'Authorization' => $this->signRequest($body),
|
||||
'X-Amz-Date' => $this->date
|
||||
),
|
||||
'body' => urldecode(http_build_query($body))
|
||||
);
|
||||
}
|
||||
|
||||
function signRequest($body) {
|
||||
$stringToSign = $this->createStringToSign(
|
||||
$this->getCredentialScope(),
|
||||
$this->getCanonicalRequest($body)
|
||||
);
|
||||
$signature = hash_hmac($this->hashAlgorithm, $stringToSign, $this->getSigningKey());
|
||||
|
||||
return sprintf(
|
||||
'%s Credential=%s/%s, SignedHeaders=host;x-amz-date, Signature=%s',
|
||||
$this->awsSigningAlgorithm,
|
||||
$this->awsAccessKey,
|
||||
$this->getCredentialScope(),
|
||||
$signature);
|
||||
}
|
||||
|
||||
function getCredentialScope() {
|
||||
return sprintf('%s/%s/%s/%s', $this->dateWithoutTime, $this->awsRegion, $this->awsService, $this->awsTerminationString);
|
||||
}
|
||||
|
||||
function getCanonicalRequest($body) {
|
||||
return implode("\n", array(
|
||||
'POST',
|
||||
'/',
|
||||
'',
|
||||
'host:' . $this->awsEndpoint,
|
||||
'x-amz-date:' . $this->date,
|
||||
'',
|
||||
'host;x-amz-date',
|
||||
hash($this->hashAlgorithm, urldecode(http_build_query($body)))
|
||||
));
|
||||
}
|
||||
|
||||
function createStringToSign($credentialScope, $canonicalRequest) {
|
||||
return implode("\n", array(
|
||||
$this->awsSigningAlgorithm,
|
||||
$this->date,
|
||||
$credentialScope,
|
||||
hash($this->hashAlgorithm, $canonicalRequest)
|
||||
));
|
||||
}
|
||||
|
||||
function getSigningKey() {
|
||||
$dateKey = hash_hmac($this->hashAlgorithm, $this->dateWithoutTime, 'AWS4' . $this->awsSecret_key, true);
|
||||
$regionKey = hash_hmac($this->hashAlgorithm, $this->awsRegion, $dateKey, true);
|
||||
$serviceKey = hash_hmac($this->hashAlgorithm, $this->awsService, $regionKey, true);
|
||||
return hash_hmac($this->hashAlgorithm, $this->awsTerminationString, $serviceKey, true);
|
||||
}
|
||||
}
|
146
lib/Mailer/Mailer.php
Normal file
146
lib/Mailer/Mailer.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer;
|
||||
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Mailer {
|
||||
public $mailer;
|
||||
public $sender;
|
||||
public $reply_to;
|
||||
public $mailer_instance;
|
||||
|
||||
function __construct($mailer = false, $sender = false, $reply_to = false) {
|
||||
$this->mailer = $this->getMailer($mailer);
|
||||
$this->sender = $this->getSender($sender);
|
||||
$this->reply_to = $this->getReplyTo($reply_to);
|
||||
$this->mailer_instance = $this->buildMailer();
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
$subscriber = $this->transformSubscriber($subscriber);
|
||||
return $this->mailer_instance->send($newsletter, $subscriber);
|
||||
}
|
||||
|
||||
function buildMailer() {
|
||||
switch($this->mailer['method']) {
|
||||
case 'AmazonSES':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['region'],
|
||||
$this->mailer['access_key'],
|
||||
$this->mailer['secret_key'],
|
||||
$this->sender['from_name_email']
|
||||
);
|
||||
break;
|
||||
case 'ElasticEmail':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['api_key'],
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
case 'MailGun':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['domain'],
|
||||
$this->mailer['api_key'],
|
||||
$this->sender['from_name_email']
|
||||
);
|
||||
break;
|
||||
case 'MailPoet':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['mailpoet_api_key'],
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
case 'Mandrill':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['api_key'],
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
case 'SendGrid':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['api_key'],
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
case 'WPMail':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
case 'SMTP':
|
||||
$mailer_instance = new $this->mailer['class'](
|
||||
$this->mailer['host'],
|
||||
$this->mailer['port'],
|
||||
$this->mailer['authentication'],
|
||||
$this->mailer['login'],
|
||||
$this->mailer['password'],
|
||||
$this->mailer['encryption'],
|
||||
$this->sender['from_email'],
|
||||
$this->sender['from_name']
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception(__('Mailing method does not exist.'));
|
||||
break;
|
||||
}
|
||||
return $mailer_instance;
|
||||
}
|
||||
|
||||
function getMailer($mailer = false) {
|
||||
if(!$mailer) {
|
||||
$mailer = Setting::getValue('mta', null);
|
||||
if(!$mailer || !isset($mailer['method'])) throw new \Exception(__('Mailer is not configured.'));
|
||||
}
|
||||
$mailer['class'] = 'MailPoet\\Mailer\\Methods\\' . $mailer['method'];
|
||||
return $mailer;
|
||||
}
|
||||
|
||||
function getSender($sender = false) {
|
||||
if(!$sender) {
|
||||
$sender = Setting::getValue('sender', null);
|
||||
if(!$sender) throw new \Exception(__('Sender name and email are not configured.'));
|
||||
}
|
||||
return array(
|
||||
'from_name' => $sender['name'],
|
||||
'from_email' => $sender['address'],
|
||||
'from_name_email' => sprintf('%s <%s>', $sender['name'], $sender['address'])
|
||||
);
|
||||
}
|
||||
|
||||
function getReplyTo($reply_to = false) {
|
||||
if(!$reply_to) {
|
||||
$reply_to = Setting::getValue('reply_to', null);
|
||||
if(!$reply_to) {
|
||||
$reply_to = array(
|
||||
'name' => $this->sender['from_name'],
|
||||
'address' => $this->sender['from_email']
|
||||
);
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'reply_to_name' => $reply_to['name'],
|
||||
'reply_to_email' => $reply_to['address'],
|
||||
'reply_to_name_email' => sprintf('%s <%s>', $reply_to['name'], $reply_to['address'])
|
||||
);
|
||||
}
|
||||
|
||||
function transformSubscriber($subscriber) {
|
||||
if(!is_array($subscriber)) return $subscriber;
|
||||
if(isset($subscriber['address'])) $subscriber['email'] = $subscriber['address'];
|
||||
$first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : '';
|
||||
$last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : '';
|
||||
if(!$first_name && !$last_name) return $subscriber['email'];
|
||||
$subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']);
|
||||
$subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber));
|
||||
return $subscriber;
|
||||
}
|
||||
}
|
155
lib/Mailer/Methods/AmazonSES.php
Normal file
155
lib/Mailer/Methods/AmazonSES.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class AmazonSES {
|
||||
public $aws_access_key;
|
||||
public $aws_secret_key;
|
||||
public $aws_region;
|
||||
public $aws_endpoint;
|
||||
public $aws_signing_algorithm;
|
||||
public $aws_service;
|
||||
public $aws_termination_string;
|
||||
public $hash_algorithm;
|
||||
public $url;
|
||||
public $from;
|
||||
public $date;
|
||||
public $date_without_time;
|
||||
|
||||
function __construct($region, $access_key, $secret_key, $from) {
|
||||
$this->aws_access_key = $access_key;
|
||||
$this->aws_secret_key = $secret_key;
|
||||
$this->aws_region = $region;
|
||||
$this->aws_endpoint = sprintf('email.%s.amazonaws.com', $region);
|
||||
$this->aws_signing_algorithm = 'AWS4-HMAC-SHA256';
|
||||
$this->aws_service = 'ses';
|
||||
$this->aws_termination_string = 'aws4_request';
|
||||
$this->hash_algorithm = 'sha256';
|
||||
$this->url = 'https://' . $this->aws_endpoint;
|
||||
$this->from = $from;
|
||||
$this->date = gmdate('Ymd\THis\Z');
|
||||
$this->date_without_time = gmdate('Ymd');
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
$result = wp_remote_post(
|
||||
$this->url,
|
||||
$this->request($newsletter, $subscriber)
|
||||
);
|
||||
return (
|
||||
!is_wp_error($result) === true &&
|
||||
wp_remote_retrieve_response_code($result) === 200
|
||||
);
|
||||
}
|
||||
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'Action' => 'SendEmail',
|
||||
'Version' => '2010-12-01',
|
||||
'Source' => $this->from,
|
||||
'Destination.ToAddresses.member.1' => $subscriber,
|
||||
'Message.Subject.Data' => $newsletter['subject'],
|
||||
'ReturnPath' => $this->from
|
||||
);
|
||||
if(!empty($newsletter['body']['html'])) {
|
||||
$body['Message.Body.Html.Data'] = $newsletter['body']['html'];
|
||||
}
|
||||
if(!empty($newsletter['body']['text'])) {
|
||||
$body['Message.Body.Text.Data'] = $newsletter['body']['text'];
|
||||
}
|
||||
return $body;
|
||||
}
|
||||
|
||||
function request($newsletter, $subscriber) {
|
||||
$body = $this->getBody($newsletter, $subscriber);
|
||||
return array(
|
||||
'timeout' => 10,
|
||||
'httpversion' => '1.1',
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Host' => $this->aws_endpoint,
|
||||
'Authorization' => $this->signRequest($body),
|
||||
'X-Amz-Date' => $this->date
|
||||
),
|
||||
'body' => urldecode(http_build_query($body))
|
||||
);
|
||||
}
|
||||
|
||||
function signRequest($body) {
|
||||
$string_to_sign = $this->createStringToSign(
|
||||
$this->getCredentialScope(),
|
||||
$this->getCanonicalRequest($body)
|
||||
);
|
||||
$signature = hash_hmac(
|
||||
$this->hash_algorithm,
|
||||
$string_to_sign,
|
||||
$this->getSigningKey()
|
||||
);
|
||||
|
||||
return sprintf(
|
||||
'%s Credential=%s/%s, SignedHeaders=host;x-amz-date, Signature=%s',
|
||||
$this->aws_signing_algorithm,
|
||||
$this->aws_access_key,
|
||||
$this->getCredentialScope(),
|
||||
$signature);
|
||||
}
|
||||
|
||||
function getCredentialScope() {
|
||||
return sprintf(
|
||||
'%s/%s/%s/%s',
|
||||
$this->date_without_time,
|
||||
$this->aws_region,
|
||||
$this->aws_service,
|
||||
$this->aws_termination_string);
|
||||
}
|
||||
|
||||
function getCanonicalRequest($body) {
|
||||
return implode("\n", array(
|
||||
'POST',
|
||||
'/',
|
||||
'',
|
||||
'host:' . $this->aws_endpoint,
|
||||
'x-amz-date:' . $this->date,
|
||||
'',
|
||||
'host;x-amz-date',
|
||||
hash($this->hash_algorithm, urldecode(http_build_query($body)))
|
||||
));
|
||||
}
|
||||
|
||||
function createStringToSign($credential_scope, $canonical_request) {
|
||||
return implode("\n", array(
|
||||
$this->aws_signing_algorithm,
|
||||
$this->date,
|
||||
$credential_scope,
|
||||
hash($this->hash_algorithm, $canonical_request)
|
||||
));
|
||||
}
|
||||
|
||||
function getSigningKey() {
|
||||
$date_key = hash_hmac(
|
||||
$this->hash_algorithm,
|
||||
$this->date_without_time,
|
||||
'AWS4' . $this->aws_secret_key,
|
||||
true
|
||||
);
|
||||
$region_key = hash_hmac(
|
||||
$this->hash_algorithm,
|
||||
$this->aws_region,
|
||||
$date_key,
|
||||
true
|
||||
);
|
||||
$service_key = hash_hmac(
|
||||
$this->hash_algorithm,
|
||||
$this->aws_service,
|
||||
$region_key,
|
||||
true
|
||||
);
|
||||
return hash_hmac(
|
||||
$this->hash_algorithm,
|
||||
$this->aws_termination_string,
|
||||
$service_key,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
@ -1,14 +1,18 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\API;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class ElasticEmail {
|
||||
function __construct($apiKey, $fromEmail, $fromName) {
|
||||
$this->url = 'https://api.elasticemail.com/mailer/send';
|
||||
$this->apiKey = $apiKey;
|
||||
$this->fromEmail = $fromEmail;
|
||||
$this->fromName = $fromName;
|
||||
public $url = 'https://api.elasticemail.com/mailer/send';
|
||||
public $api_key;
|
||||
public $from_email;
|
||||
public $from_name;
|
||||
|
||||
function __construct($api_key, $from_email, $from_name) {
|
||||
$this->api_key = $api_key;
|
||||
$this->from_email = $from_email;
|
||||
$this->from_name = $from_name;
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
@ -23,9 +27,9 @@ class ElasticEmail {
|
||||
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'api_key' => $this->apiKey,
|
||||
'from' => $this->fromEmail,
|
||||
'from_name' => $this->fromName,
|
||||
'api_key' => $this->api_key,
|
||||
'from' => $this->from_email,
|
||||
'from_name' => $this->from_name,
|
||||
'to' => $subscriber,
|
||||
'subject' => $newsletter['subject']
|
||||
);
|
@ -1,12 +1,16 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\API;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class MailGun {
|
||||
function __construct($domain, $apiKey, $from) {
|
||||
public $url;
|
||||
public $api_key;
|
||||
public $from;
|
||||
|
||||
function __construct($domain, $api_key, $from) {
|
||||
$this->url = sprintf('https://api.mailgun.net/v3/%s/messages', $domain);
|
||||
$this->apiKey = $apiKey;
|
||||
$this->api_key = $api_key;
|
||||
$this->from = $from;
|
||||
}
|
||||
|
||||
@ -37,7 +41,7 @@ class MailGun {
|
||||
}
|
||||
|
||||
function auth() {
|
||||
return 'Basic ' . base64_encode('api:' . $this->apiKey);
|
||||
return 'Basic ' . base64_encode('api:' . $this->api_key);
|
||||
}
|
||||
|
||||
function request($newsletter, $subscriber) {
|
@ -1,16 +1,20 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class MailPoet {
|
||||
function __construct($apiKey, $fromEmail, $fromName) {
|
||||
$this->url = 'https://bridge.mailpoet.com/api/messages';
|
||||
$this->apiKey = $apiKey;
|
||||
$this->fromEmail = $fromEmail;
|
||||
$this->fromName = $fromName;
|
||||
public $url = 'https://bridge.mailpoet.com/api/messages';
|
||||
public $api_key;
|
||||
public $from_email;
|
||||
public $from_name;
|
||||
|
||||
function __construct($api_key, $from_email, $from_name) {
|
||||
$this->api_key = $api_key;
|
||||
$this->from_email = $from_email;
|
||||
$this->from_name = $from_name;
|
||||
}
|
||||
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
$result = wp_remote_post(
|
||||
$this->url,
|
||||
@ -21,20 +25,20 @@ class MailPoet {
|
||||
wp_remote_retrieve_response_code($result) === 201
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function processSubscriber($subscriber) {
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
|
||||
if(!isset($subscriberData['email'])) {
|
||||
$subscriberData = array(
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriber_data);
|
||||
if(!isset($subscriber_data['email'])) {
|
||||
$subscriber_data = array(
|
||||
'email' => $subscriber,
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'email' => $subscriberData['email'],
|
||||
'name' => (isset($subscriberData['name'])) ? $subscriberData['name'] : ''
|
||||
'email' => $subscriber_data['email'],
|
||||
'name' => (isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'to' => (array(
|
||||
@ -42,8 +46,8 @@ class MailPoet {
|
||||
'name' => $subscriber['name']
|
||||
)),
|
||||
'from' => (array(
|
||||
'address' => $this->fromEmail,
|
||||
'name' => $this->fromName
|
||||
'address' => $this->from_email,
|
||||
'name' => $this->from_name
|
||||
)),
|
||||
'subject' => $newsletter['subject']
|
||||
);
|
||||
@ -55,11 +59,11 @@ class MailPoet {
|
||||
}
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
||||
function auth() {
|
||||
return 'Basic ' . base64_encode('api:' . $this->apiKey);
|
||||
return 'Basic ' . base64_encode('api:' . $this->api_key);
|
||||
}
|
||||
|
||||
|
||||
function request($newsletter, $subscriber) {
|
||||
$body = array($this->getBody($newsletter, $subscriber));
|
||||
return array(
|
@ -1,14 +1,18 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\API;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Mandrill {
|
||||
function __construct($apiKey, $fromEmail, $fromName) {
|
||||
$this->url = 'https://mandrillapp.com/api/1.0/messages/send.json';
|
||||
$this->apiKey = $apiKey;
|
||||
$this->fromName = $fromName;
|
||||
$this->fromEmail = $fromEmail;
|
||||
public $url = 'https://mandrillapp.com/api/1.0/messages/send.json';
|
||||
public $api_key;
|
||||
public $from_email;
|
||||
public $from_name;
|
||||
|
||||
function __construct($api_key, $from_email, $from_name) {
|
||||
$this->api_key = $api_key;
|
||||
$this->from_name = $from_name;
|
||||
$this->from_email = $from_email;
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
@ -24,24 +28,24 @@ class Mandrill {
|
||||
}
|
||||
|
||||
function processSubscriber($subscriber) {
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
|
||||
if(!isset($subscriberData['email'])) {
|
||||
$subscriberData = array(
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriber_data);
|
||||
if(!isset($subscriber_data['email'])) {
|
||||
$subscriber_data = array(
|
||||
'email' => $subscriber,
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'email' => $subscriberData['email'],
|
||||
'name' => (isset($subscriberData['name'])) ? $subscriberData['name'] : ''
|
||||
'email' => $subscriber_data['email'],
|
||||
'name' => (isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
|
||||
);
|
||||
}
|
||||
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'key' => $this->apiKey,
|
||||
'key' => $this->api_key,
|
||||
'message' => array(
|
||||
'from_email' => $this->fromEmail,
|
||||
'from_name' => $this->fromName,
|
||||
'from_email' => $this->from_email,
|
||||
'from_name' => $this->from_name,
|
||||
'to' => array($subscriber),
|
||||
'subject' => $newsletter['subject']
|
||||
),
|
@ -1,19 +1,30 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SMTP {
|
||||
function __construct($host, $port, $authentication, $login = null, $password = null, $encryption,
|
||||
$fromEmail, $fromName) {
|
||||
public $host;
|
||||
public $port;
|
||||
public $authentication;
|
||||
public $login;
|
||||
public $password;
|
||||
public $encryption;
|
||||
public $from_name;
|
||||
public $from_email;
|
||||
public $mailer;
|
||||
|
||||
function __construct(
|
||||
$host, $port, $authentication, $login = null, $password = null, $encryption,
|
||||
$from_email, $from_name) {
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->authentication = $authentication;
|
||||
$this->login = $login;
|
||||
$this->password = $password;
|
||||
$this->encryption = $encryption;
|
||||
$this->fromName = $fromName;
|
||||
$this->fromEmail = $fromEmail;
|
||||
$this->from_name = $from_name;
|
||||
$this->from_email = $from_email;
|
||||
$this->mailer = $this->buildMailer();
|
||||
}
|
||||
|
||||
@ -42,7 +53,7 @@ class SMTP {
|
||||
|
||||
function createMessage($newsletter, $subscriber) {
|
||||
$message = \Swift_Message::newInstance()
|
||||
->setFrom(array($this->fromEmail => $this->fromName))
|
||||
->setFrom(array($this->from_email => $this->from_name))
|
||||
->setTo($this->processSubscriber($subscriber))
|
||||
->setSubject($newsletter['subject']);
|
||||
if(!empty($newsletter['body']['html'])) {
|
||||
@ -55,15 +66,15 @@ class SMTP {
|
||||
}
|
||||
|
||||
function processSubscriber($subscriber) {
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
|
||||
if(!isset($subscriberData['email'])) {
|
||||
$subscriberData = array(
|
||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriber_data);
|
||||
if(!isset($subscriber_data['email'])) {
|
||||
$subscriber_data = array(
|
||||
'email' => $subscriber,
|
||||
);
|
||||
}
|
||||
return array(
|
||||
$subscriberData['email'] =>
|
||||
(isset($subscriberData['name'])) ? $subscriberData['name'] : ''
|
||||
$subscriber_data['email'] =>
|
||||
(isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
|
||||
);
|
||||
}
|
||||
}
|
@ -1,14 +1,18 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer\API;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendGrid {
|
||||
function __construct($apiKey, $fromEmail, $fromName) {
|
||||
$this->url = 'https://api.sendgrid.com/api/mail.send.json';
|
||||
$this->apiKey = $apiKey;
|
||||
$this->fromEmail = $fromEmail;
|
||||
$this->fromName = $fromName;
|
||||
public $url = 'https://api.sendgrid.com/api/mail.send.json';
|
||||
public $api_key;
|
||||
public $from_email;
|
||||
public $from_name;
|
||||
|
||||
function __construct($api_key, $from_email, $from_name) {
|
||||
$this->api_key = $api_key;
|
||||
$this->from_email = $from_email;
|
||||
$this->from_name = $from_name;
|
||||
}
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
@ -27,8 +31,8 @@ class SendGrid {
|
||||
function getBody($newsletter, $subscriber) {
|
||||
$body = array(
|
||||
'to' => $subscriber,
|
||||
'from' => $this->fromEmail,
|
||||
'fromname' => $this->fromName,
|
||||
'from' => $this->from_email,
|
||||
'from_name' => $this->from_name,
|
||||
'subject' => $newsletter['subject']
|
||||
);
|
||||
if(!empty($newsletter['body']['html'])) {
|
||||
@ -41,7 +45,7 @@ class SendGrid {
|
||||
}
|
||||
|
||||
function auth() {
|
||||
return 'Bearer ' . $this->apiKey;
|
||||
return 'Bearer ' . $this->api_key;
|
||||
}
|
||||
|
||||
function request($newsletter, $subscriber) {
|
@ -1,22 +1,22 @@
|
||||
<?php
|
||||
namespace MailPoet\Mailer;
|
||||
namespace MailPoet\Mailer\Methods;
|
||||
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class WPMail {
|
||||
function __construct($fromEmail, $fromName) {
|
||||
$this->fromEmail = $fromEmail;
|
||||
$this->fromName = $fromName;
|
||||
add_filter('wp_mail_from', array(
|
||||
$this,
|
||||
'setFromEmail'
|
||||
));
|
||||
$this->filters = array(
|
||||
'wp_mail_from' => 'setFromEmail',
|
||||
'wp_mail_from_name' => 'setFromName',
|
||||
'wp_mail_content_type' => 'setContentType'
|
||||
);
|
||||
public $from_email;
|
||||
public $from_name;
|
||||
public $filters = array(
|
||||
'wp_mail_from' => 'setFromEmail',
|
||||
'wp_mail_from_name' => 'setFromName',
|
||||
'wp_mail_content_type' => 'setContentType'
|
||||
);
|
||||
|
||||
function __construct($from_email, $from_name) {
|
||||
$this->from_email = $from_email;
|
||||
$this->from_name = $from_name;
|
||||
}
|
||||
|
||||
function addFilters() {
|
||||
@ -38,11 +38,11 @@ class WPMail {
|
||||
}
|
||||
|
||||
function setFromEmail() {
|
||||
return $this->fromEmail;
|
||||
return $this->from_email;
|
||||
}
|
||||
|
||||
function setFromName() {
|
||||
return $this->fromName;
|
||||
return $this->from_name;
|
||||
}
|
||||
|
||||
function setContentType() {
|
||||
@ -53,7 +53,9 @@ class WPMail {
|
||||
$this->addFilters();
|
||||
$result = wp_mail(
|
||||
$subscriber, $newsletter['subject'],
|
||||
(!empty($newsletter['body']['html'])) ? $newsletter['body']['html'] : $newsletter['body']['text']
|
||||
(!empty($newsletter['body']['html'])) ?
|
||||
$newsletter['body']['html'] :
|
||||
$newsletter['body']['text']
|
||||
);
|
||||
$this->removeFilters();
|
||||
return ($result === true);
|
@ -4,7 +4,7 @@ namespace MailPoet\Models;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingQueue extends Model {
|
||||
public static $_table = MP_SENDING_QUEUE_TABLE;
|
||||
public static $_table = MP_SENDING_QUEUES_TABLE;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
@ -154,7 +154,7 @@ class Subscriber extends Model {
|
||||
$orm = $orm->selectExpr(
|
||||
'CASE WHEN ' .
|
||||
MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' .
|
||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END as "' . $customField['name'].'"');
|
||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END as "' . $customField['id'].'"');
|
||||
}
|
||||
$orm = $orm
|
||||
->leftOuterJoin(
|
||||
|
@ -1,47 +1,40 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
|
||||
class Button {
|
||||
static function render($element) {
|
||||
$stylesHelper = new StylesHelper();
|
||||
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_button mailpoet_padded" valign = "top" >
|
||||
<div>
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td align="' . $element['styles']['block']['textAlign'] . '">
|
||||
<!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
href="' . $element['url'] . '"
|
||||
style="height:' . $element['styles']['block']['lineHeight'] . ';
|
||||
width:' . $element['styles']['block']['width'] . ';
|
||||
v-text-anchor:middle;"
|
||||
arcsize="' . round($element['styles']['block']['borderRadius'] / $element['styles']['block']['lineHeight'] * 100) . '%"
|
||||
strokecolor="' . $element['styles']['block']['borderColor'] . '"
|
||||
fillcolor="' . $element['styles']['block']['backgroundColor'] . '">
|
||||
<tr>
|
||||
<td class="mailpoet_padded" valign="top">
|
||||
<div>
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;">
|
||||
<tr>
|
||||
<td class="mailpoet_button-container" style="padding:8px 0;text-align:' . $element['styles']['block']['textAlign'] . ';"><!--[if mso]>
|
||||
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
href="' . $element['url'] . '"
|
||||
style="height:' . $element['styles']['block']['lineHeight'] . ';
|
||||
width:' . $element['styles']['block']['width'] . ';
|
||||
v-text-anchor:middle;"
|
||||
arcsize="' . round($element['styles']['block']['borderRadius'] / $element['styles']['block']['lineHeight'] * 100) . '%"
|
||||
strokeweight="1px"
|
||||
strokecolor="' . $element['styles']['block']['borderColor'] . '"
|
||||
fillcolor="' . $element['styles']['block']['backgroundColor'] . '">
|
||||
<w:anchorlock/>
|
||||
<center style="color:' . $element['styles']['block']['fontColor'] . ';
|
||||
font-family:' . $element['styles']['block']['fontFamily'] . ';
|
||||
font-size:' . $element['styles']['block']['fontSize'] . ';
|
||||
font-weight:bold;">' . $element['text'] . '
|
||||
font-family:' . $element['styles']['block']['fontFamily'] . ';
|
||||
font-size:' . $element['styles']['block']['fontSize'] . ';
|
||||
font-weight:bold;">' . $element['text'] . '
|
||||
</center>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
<a class="mailpoet_button"
|
||||
href="' . $element['url'] . '"
|
||||
style="display:inline-block;text-align:center;text-decoration:none;-webkit-text-size-adjust:none;mso-hide:all;' . $stylesHelper->getBlockStyles($element, array('textAlign')) . '"> ' . $element['text'] . '
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
<![endif]--><a class="mailpoet_button" href="' . $element['url'] . '" style="display:inline-block;-webkit-text-size-adjust:none;mso-hide:all;text-decoration:none!important;text-align:center;' . StylesHelper::getBlockStyles($element, $exclude = array('textAlign')) . '"> ' . $element['text'] . '
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,23 +1,34 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
|
||||
class Divider {
|
||||
static function render($element) {
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_divider mailpoet_padded"
|
||||
style="background-color: ' . $element['styles']['block']['backgroundColor'] . '; padding: ' . $element['styles']['block']['padding'] . ' 0;"
|
||||
valign="top">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td style="border-top-width: ' . $element['styles']['block']['borderWidth'] . ';
|
||||
border-top-style: ' . $element['styles']['block']['borderStyle'] . ';
|
||||
border-top-color: ' . $element['styles']['block']['borderColor'] . ';">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_divider" valign="top" ' .
|
||||
(($element['styles']['block']['backgroundColor'] !== 'transparent') ?
|
||||
'bgColor="' . $element['styles']['block']['backgroundColor'] . '" style="background-color:' . $element['styles']['block']['backgroundColor'] . ';' :
|
||||
'style="'
|
||||
) .
|
||||
sprintf('padding: %s %spx %s %spx;',
|
||||
$element['styles']['block']['padding'],
|
||||
StylesHelper::$padding_width,
|
||||
$element['styles']['block']['padding'],
|
||||
StylesHelper::$padding_width) . '">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0"
|
||||
style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;">
|
||||
<tr>
|
||||
<td class="mailpoet_divider-cell"
|
||||
style="border-top-width: ' . $element['styles']['block']['borderWidth'] . ';
|
||||
border-top-style: ' . $element['styles']['block']['borderStyle'] . ';
|
||||
border-top-color: ' . $element['styles']['block']['borderColor'] . ';">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,30 +1,27 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
|
||||
class Footer {
|
||||
static function render($element) {
|
||||
$stylesHelper = new StylesHelper();
|
||||
|
||||
// apply link styles
|
||||
if(isset($element['styles']['link'])) {
|
||||
$element['text'] = str_replace('<a', '<a style="' . $stylesHelper->getStyles($element['styles'], 'link') . '"', $element['text']);
|
||||
$element['text'] = str_replace(
|
||||
'<a',
|
||||
'<a style="'
|
||||
. StylesHelper::getStyles($element['styles'], 'link')
|
||||
. '"', $element['text']
|
||||
);
|
||||
}
|
||||
|
||||
// apply text styles
|
||||
if(isset($element['styles']['link'])) {
|
||||
$element['text'] = str_replace('<p', '<p style="' . $stylesHelper->getStyles($element['styles'], 'text') . '"', $element['text']);
|
||||
}
|
||||
|
||||
$element['text'] = preg_replace('/\n/', '<br /><br />', $element['text']);
|
||||
$element['text'] = preg_replace('/(<\/?p>)/', '', $element['text']);
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_footer"
|
||||
style="' . $stylesHelper->getStyles($element['styles'], 'block') . '"
|
||||
valign="top">
|
||||
<div>' . $element['text'] . '</div>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_padded_header_footer mailpoet_footer" bgcolor="' . $element['styles']['block']['backgroundColor'] . '"
|
||||
style="' . StylesHelper::getBlockStyles($element) . StylesHelper::getStyles($element['styles'], 'text') . '">
|
||||
' . $element['text'] . '
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,30 +1,27 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
|
||||
class Header {
|
||||
static function render($element) {
|
||||
$stylesHelper = new StylesHelper();
|
||||
|
||||
// apply link styles
|
||||
if(isset($element['styles']['link'])) {
|
||||
$element['text'] = str_replace('<a', '<a style="' . $stylesHelper->getStyles($element['styles'], 'link') . '"', $element['text']);
|
||||
$element['text'] = str_replace(
|
||||
'<a',
|
||||
'<a style="'
|
||||
. StylesHelper::getStyles($element['styles'], 'link')
|
||||
. '"', $element['text']
|
||||
);
|
||||
}
|
||||
|
||||
// apply text styles
|
||||
if(isset($element['styles']['link'])) {
|
||||
$element['text'] = str_replace('<p', '<p style="' . $stylesHelper->getStyles($element['styles'], 'text') . '"', $element['text']);
|
||||
}
|
||||
|
||||
$element['text'] = preg_replace('/\n/', '<br /><br />', $element['text']);
|
||||
$element['text'] = preg_replace('/(<\/?p>)/', '', $element['text']);
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_header"
|
||||
style="' . $stylesHelper->getBlockStyles($element) . '"
|
||||
valign="top">
|
||||
<div>' . $element['text'] . '</div>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_padded_header_footer mailpoet_header" bgcolor="' . $element['styles']['block']['backgroundColor'] . '"
|
||||
style="' . StylesHelper::getBlockStyles($element) . StylesHelper::getStyles($element['styles'], 'text') . '">
|
||||
' . $element['text'] . '
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,24 +1,42 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\Columns\ColumnsHelper;
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
|
||||
class Image {
|
||||
static function render($element) {
|
||||
$stylesHelper = new StylesHelper();
|
||||
|
||||
$element['width'] = (int) $element['width'];
|
||||
|
||||
static function render($element, $columnCount) {
|
||||
$element = self::getImageDimensions($element, $columnCount);
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_image ' . (($element['padded'] === true) ? "mailpoet_padded" : "") . '"
|
||||
style="' . $stylesHelper->getBlockStyles($element) . '"
|
||||
valign="top">
|
||||
<img style="top:0; left:0; height: auto; width:100%;"
|
||||
src="' . $element['src'] . '"
|
||||
width="' . (($element['padded'] === true) ? $element['width'] - (20 * 2) : $element['width']) . '">
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_image ' . $element['paddedClass'] . '" align="center" valign="top">
|
||||
<img style="max-width:' . $element['width'] . 'px;" src="' . $element['src'] . '"
|
||||
width="' . $element['width'] . '" height="' . $element['height'] . '" alt="' . $element['alt'] . '"/>
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
|
||||
static function getImageDimensions($element, $column_count) {
|
||||
$column_width = ColumnsHelper::columnWidth($column_count);
|
||||
$padded_width = StylesHelper::$padding_width * 2;
|
||||
// resize image if it's wider than the column width
|
||||
if((int) $element['width'] >= $column_width) {
|
||||
$ratio = (int) $element['width'] / $column_width;
|
||||
$element['width'] = $column_width;
|
||||
$element['height'] = ceil((int) $element['height'] / $ratio);
|
||||
}
|
||||
if($element['padded'] == "true" && $element['width'] >= $column_width) {
|
||||
// resize image if the padded option is on
|
||||
$ratio = (int) $element['width'] / ((int) $element['width'] - $padded_width);
|
||||
$element['width'] = (int) $element['width'] - $padded_width;
|
||||
$element['height'] = ceil((int) $element['height'] / $ratio);
|
||||
$element['paddedClass'] = 'mailpoet_padded';
|
||||
} else {
|
||||
$element['width'] = (int) $element['width'];
|
||||
$element['height'] = (int) $element['height'];
|
||||
$element['paddedClass'] = '';
|
||||
}
|
||||
return $element;
|
||||
}
|
||||
}
|
@ -1,24 +1,24 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
class Renderer {
|
||||
function render($data) {
|
||||
array_map(function ($block) use (&$blockContent, &$columns) {
|
||||
$blockContent .= $this->createElementFromBlockType($block);
|
||||
function render($data, $column_count) {
|
||||
$block_content = '';
|
||||
array_map(function ($block) use (&$block_content, &$columns, $column_count) {
|
||||
$block_content .= $this->createElementFromBlockType($block, $column_count);
|
||||
if(isset($block['blocks'])) {
|
||||
$blockContent = $this->render($block);
|
||||
$block_content = $this->render($block, $column_count);
|
||||
}
|
||||
// vertical orientation denotes column container
|
||||
if($block['type'] === 'container' && $block['orientation'] === 'vertical') {
|
||||
$columns[] = $blockContent;
|
||||
$columns[] = $block_content;
|
||||
}
|
||||
}, $data['blocks']);
|
||||
|
||||
return (isset($columns)) ? $columns : $blockContent;
|
||||
return (isset($columns)) ? $columns : $block_content;
|
||||
}
|
||||
|
||||
function createElementFromBlockType($block) {
|
||||
$blockClass = __NAMESPACE__ . '\\' . ucfirst($block['type']);
|
||||
return (class_exists($blockClass)) ? $blockClass::render($block) : '';
|
||||
function createElementFromBlockType($block, $column_count) {
|
||||
$block_class = __NAMESPACE__ . '\\' . ucfirst($block['type']);
|
||||
return (class_exists($block_class)) ? $block_class::render($block, $column_count) : '';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,26 +1,23 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
class Social {
|
||||
static function render($element) {
|
||||
$iconsBlock = '';
|
||||
|
||||
$icons_block = '';
|
||||
if(is_array($element['icons'])) {
|
||||
foreach ($element['icons'] as $icon) {
|
||||
$iconsBlock .= '
|
||||
<a href="' . $icon['link'] . '">
|
||||
<img src="' . $icon['image'] . '" width = "32" height = "32" style="width: 32px; height: 32px;" alt="' . $icon['iconType'] . '">
|
||||
</a>
|
||||
<img src="http://mp3.mailpoet.net/spacer.gif" width = "10" height = "1" style=" width: 10px; height: 1px;">';
|
||||
foreach($element['icons'] as $index => $icon) {
|
||||
$icons_block .= '
|
||||
<a href="' . $icon['link'] . '" style="text-decoration:none!important;">
|
||||
<img src="' . $icon['image'] . '" width="' . (int) $icon['width'] . '" height="' . (int) $icon['height'] . '" style="width:' . $icon['width'] . ';height:' . $icon['width'] . ';-ms-interpolation-mode:bicubic;border:0;display:inline;outline:none;" alt="' . $icon['iconType'] . '">
|
||||
</a>';
|
||||
}
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_padded" valign="top" align="center">
|
||||
' . $icons_block . '
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_social" valign="top">
|
||||
<div class="mailpoet_social-icon mailpoet_padded">' . $iconsBlock . ' </div>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,23 +1,12 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
class Spacer {
|
||||
static function render($element) {
|
||||
|
||||
$stylesHelper = new StylesHelper();
|
||||
|
||||
// if the parent container (column) has background set and the divider element has a transparent background,
|
||||
// it will assume the newsletter background, not that of the parent container
|
||||
if($element['styles']['block']['backgroundColor'] === 'transparent') {
|
||||
unset($element['styles']['block']['backgroundColor']);
|
||||
}
|
||||
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_spacer" style="' . $stylesHelper->getBlockStyles($element) . '" valign="top"> </td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_spacer" height="' . (int) $element['styles']['block']['height'] . '" valign="top"></td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
}
|
@ -1,114 +1,110 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
class Text {
|
||||
static $typeFace = array(
|
||||
'Arial' => "Arial, 'Helvetica Neue', Helvetica, sans-serif",
|
||||
'Comic Sans MS' => "'Comic Sans MS', 'Marker Felt-Thin', Arial, sans-serif",
|
||||
'Courier New' => "'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Typewriter', monospace",
|
||||
'Georgia' => "Georgia, Times, 'Times New Roman', serif",
|
||||
'Lucida' => "'Lucida Sans Unicode', 'Lucida Grande', sans-serif",
|
||||
'Tahoma' => "Tahoma, Verdana, Segoe, sans-serif",
|
||||
'Times New Roman' => "'Times New Roman', Times, Baskerville, Georgia, serif",
|
||||
'Trebuchet MS' => "'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif",
|
||||
'Verdana' => "Verdana, Geneva, sans-serif"
|
||||
);
|
||||
|
||||
static function render($element) {
|
||||
$html = $element['text'];
|
||||
|
||||
$html = self::convertBlockquotesToTables($html);
|
||||
$html = self::addLineBreakAfterTags($html);
|
||||
$html = self::removeEmptyTags($html);
|
||||
$html = self::convertEmptyParagraphsToLineBreaks($html);
|
||||
$html = self::convertParagraphsToTables($html);
|
||||
$html = self::removeLastBreakLine($html);
|
||||
|
||||
$html = self::addLineBreakAfterTags($html);
|
||||
$html = self::styleLists($html);
|
||||
$html = self::styleHeadings($html);
|
||||
$html = self::removeLastElementBreakLine($html);
|
||||
$template = '
|
||||
<tr>
|
||||
<td class="mailpoet_col mailpoet_text mailpoet_padded" valign="top">' . $html . ' </td>
|
||||
</tr>';
|
||||
|
||||
<tr>
|
||||
<td class="mailpoet_text mailpoet_padded" valign="top" style="word-break:break-word;word-wrap:break-word;">
|
||||
' . $html . '
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
|
||||
static function removeLastBreakLine($html) {
|
||||
return preg_replace('/<br>([^<br>]*)$/s', '', $html);
|
||||
}
|
||||
|
||||
static function convertParagraphsToTables($html) {
|
||||
$html = preg_replace('/<p>(.*?)<\/p>/', '
|
||||
<table cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<span class="paragraph">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tr>
|
||||
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;">
|
||||
$1
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>', $html);
|
||||
|
||||
return preg_replace('/<p(.+style=\".*?\")?>(.*?)<\/p>/', '
|
||||
<table cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td $1>
|
||||
<span class="paragraph">
|
||||
<br /><br />
|
||||
</td>
|
||||
</tr>
|
||||
</table>'
|
||||
, $html);
|
||||
$html = preg_replace('/<p style=\"(.*)\">(.*?)<\/p>/', '
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tr>
|
||||
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;$1">
|
||||
$2
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>', $html);
|
||||
<br /><br />
|
||||
</td>
|
||||
</tr>
|
||||
</table>'
|
||||
, $html);
|
||||
return $html;
|
||||
}
|
||||
|
||||
static function convertEmptyParagraphsToLineBreaks($html) {
|
||||
return preg_replace('/<p(?:.+style=\".*?\")?><\/p>/', '<br>', $html);
|
||||
|
||||
|
||||
static function removeLastElementBreakLine($html) {
|
||||
return preg_replace('/<br\/>([^<br\/>]*)$/s', '', $html);
|
||||
}
|
||||
|
||||
|
||||
static function addLineBreakAfterTags($html) {
|
||||
return preg_replace('/(<\/(ul|ol|h\d)>)/', '$1<br>', $html);
|
||||
return preg_replace('/(<\/(ul|ol|h\d)>)/', '$1<br />', $html);
|
||||
}
|
||||
|
||||
|
||||
static function convertBlockquotesToTables($html) {
|
||||
$template = '
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="mailpoet_blockquote">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top">$1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>';
|
||||
|
||||
return preg_replace('/<blockquote>(.*?)<\/blockquote>/s', $template, $html);
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="2" bgcolor="#565656"></td>
|
||||
<td width="10"></td>
|
||||
<td valign="top">
|
||||
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tr>
|
||||
<td class="mailpoet_blockquote">
|
||||
$1
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>';
|
||||
preg_match('/<blockquote>.*?<\/blockquote>/s', $html, $blockquotes);
|
||||
foreach($blockquotes as $index => $blockquote) {
|
||||
$blockquote = preg_replace('/<\/p>\n<p>/', '<br/><br/>', $blockquote);
|
||||
$blockquote = preg_replace('/<\/?p>/', '', $blockquote);
|
||||
$blockquote = preg_replace(
|
||||
'/<blockquote>(.*?)<\/blockquote>/s',
|
||||
$template,
|
||||
$blockquote
|
||||
);
|
||||
$html = preg_replace(
|
||||
'/' . preg_quote($blockquotes[$index], '/') . '/',
|
||||
$blockquote,
|
||||
$html
|
||||
);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
static function removeEmptyTags($html) {
|
||||
$pattern = <<<'EOD'
|
||||
~
|
||||
<
|
||||
(?:
|
||||
!--[^-]*(?:-(?!->)[^-]*)*-->[^<]*(*SKIP)(*F) # skip comments
|
||||
|
|
||||
( # group 1
|
||||
(span|em|strong) # tag name in group 2
|
||||
[^"'>]* #'"# all that is not a quote or a closing angle bracket
|
||||
(?: # quoted attributes
|
||||
"[^\\"]*(?:\\.[^\\"]*)*+" [^"'>]* #'"# double quote
|
||||
|
|
||||
'[^\\']*(?:\\.[^\\']*)*+' [^"'>]* #'"# single quote
|
||||
)*+
|
||||
>
|
||||
\s*
|
||||
(?:
|
||||
<!--[^-]*(?:-(?!->)[^-]*)*+--> \s* # html comments
|
||||
|
|
||||
<(?1) \s* # recursion with the group 1
|
||||
)*+
|
||||
</\2> # closing tag
|
||||
) # end of the group 1
|
||||
)
|
||||
~sxi
|
||||
EOD;
|
||||
|
||||
return preg_replace($pattern, '', $html);
|
||||
|
||||
static function styleHeadings($html) {
|
||||
return preg_replace(
|
||||
'/<(h[1-6])(?:.+style=\"(.*)?\")?>/',
|
||||
'<$1 style="margin:0;font-style:normal;font-weight:normal;$2">',
|
||||
$html
|
||||
);
|
||||
}
|
||||
|
||||
static function styleLists($html) {
|
||||
$html = preg_replace(
|
||||
'/<(ul|ol)>/',
|
||||
'<$1 class="mailpoet_paragraph" style="padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;">',
|
||||
$html
|
||||
);
|
||||
$html = preg_replace('/<li>/', '<li class="mailpoet_paragraph">', $html);
|
||||
return $html;
|
||||
}
|
||||
}
|
38
lib/Newsletter/Renderer/Columns/ColumnsHelper.php
Normal file
38
lib/Newsletter/Renderer/Columns/ColumnsHelper.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Columns;
|
||||
|
||||
class ColumnsHelper {
|
||||
static $columns_width = array(
|
||||
1 => 660,
|
||||
2 => 330,
|
||||
3 => 220
|
||||
);
|
||||
|
||||
static $columns_class = array(
|
||||
1 => 'cols-one',
|
||||
2 => 'cols-two',
|
||||
3 => 'cols-three'
|
||||
);
|
||||
|
||||
static $columns_alignment = array(
|
||||
1 => null,
|
||||
2 => 'left',
|
||||
3 => 'right'
|
||||
);
|
||||
|
||||
static function columnWidth($columns_count) {
|
||||
return self::$columns_width[$columns_count];
|
||||
}
|
||||
|
||||
static function columnClass($columns_count) {
|
||||
return self::$columns_class[$columns_count];
|
||||
}
|
||||
|
||||
static function columnClasses() {
|
||||
return self::$columns_class;
|
||||
}
|
||||
|
||||
static function columnAlignment($columns_count) {
|
||||
return self::$columns_alignment[$columns_count];
|
||||
}
|
||||
}
|
@ -1,76 +1,78 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer\Columns;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer\Columns;
|
||||
|
||||
class Renderer {
|
||||
public $columnWidths = array(
|
||||
1 => 600,
|
||||
2 => 300,
|
||||
3 => 200
|
||||
);
|
||||
|
||||
public $columnClasses = array(
|
||||
1 => 'mailpoet_col-one',
|
||||
2 => 'mailpoet_col-two',
|
||||
3 => 'mailpoet_col-three'
|
||||
);
|
||||
|
||||
function render($columnsCount, $columnsData) {
|
||||
$columnWidth = $this->columnWidths[$columnsCount];
|
||||
$columnClass = $this->columnClasses[$columnsCount];
|
||||
|
||||
// open column container
|
||||
$columnContainerTemplate = '
|
||||
<tr>
|
||||
<td class="mailpoet_content" align="left" style="border-collapse: collapse;">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="mailpoet_cols-wrapper" style="border-collapse: collapse; padding-left: 0px; padding-right: 0px;">
|
||||
<!--[if mso]>
|
||||
<table border="0" width="100%" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="' . $columnWidth . '" style="width: ' . $columnWidth . 'px;" valign="top">
|
||||
<![endif]-->';
|
||||
|
||||
$columnOpenTemplate = '
|
||||
<table width="' . $columnWidth . '"
|
||||
border="0" cellpadding="0" cellspacing="0" align="left" class="mailpoet_force-row ' . $columnClass . ' mailpoet_col"
|
||||
style="width: ' . $columnWidth . 'px; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt;
|
||||
table-layout: fixed; margin-left: auto; margin-right: auto;" bgcolor="#999999">
|
||||
<tbody>';
|
||||
|
||||
$columnCloseTemplate = '
|
||||
</tbody>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
<td width="' . $columnWidth . '" style="width: ' . $columnWidth . 'px;" valign="top">
|
||||
<![endif]-->';
|
||||
|
||||
foreach ($columnsData as $index => $columnData) {
|
||||
$index++;
|
||||
$columnContainerTemplate .= $columnOpenTemplate . $columnData;
|
||||
if($columnsCount > 1 && $index != $columnsCount) {
|
||||
$columnContainerTemplate .= $columnCloseTemplate;
|
||||
}
|
||||
function render($column_styles, $columns_count, $columns_data) {
|
||||
$styles = $column_styles['block'];
|
||||
$width = ColumnsHelper::columnWidth($columns_count);
|
||||
$class = ColumnsHelper::columnClass($columns_count);
|
||||
$alignment = ColumnsHelper::columnAlignment($columns_count);
|
||||
$template = ($columns_count === 1) ?
|
||||
$this->getOneColumnTemplate($styles, $class) :
|
||||
$this->getMultipleColumnsTemplate($styles, $width, $alignment, $class);
|
||||
$result = array_map(function ($content) use ($template) {
|
||||
return $template['content_start'] . $content . $template['content_end'];
|
||||
}, $columns_data);
|
||||
$result = implode('', $result);
|
||||
if($columns_count !== 1) {
|
||||
$result = $template['container_start'] . $result . $template['container_end'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// close column container
|
||||
$columnContainerTemplate .= '
|
||||
</tbody>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
function getOneColumnTemplate($styles, $class) {
|
||||
$template['content_start'] = '
|
||||
<tr>
|
||||
<td class="mailpoet_content" align="center" style="border-collapse:collapse">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding-left:0;padding-right:0">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="mailpoet_' . $class . '" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;background-color:' . $styles['backgroundColor'] . '!important;" bgcolor="' . $styles['backgroundColor'] . '">
|
||||
<tbody>';
|
||||
$template['content_end'] = '
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>';
|
||||
return $template;
|
||||
}
|
||||
|
||||
function getMultipleColumnsTemplate($styles, $width, $alignment, $class) {
|
||||
$template['container_start'] = '
|
||||
<tr>
|
||||
<td class="mailpoet_content-' . $class . '" align="left" style="border-collapse:collapse;background-color:' . $styles['backgroundColor'] . '!important;" bgcolor="' . $styles['backgroundColor'] . '">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" style="font-size:0;"><!--[if mso]>
|
||||
<table border="0" width="100%" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>';
|
||||
$template['content_start'] = '
|
||||
<td width="' . $width . '" valign="top">
|
||||
<![endif]--><div style="display:inline-block; max-width:' . $width . 'px; vertical-align:top; width:100%;">
|
||||
<table width="' . $width . '" class="mailpoet_' . $class . '" border="0" cellpadding="0" cellspacing="0" align="' . $alignment . '" style="width:100%;max-width:' . $width . 'px;border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;">
|
||||
<tbody>';
|
||||
$template['content_end'] = '
|
||||
</tbody>
|
||||
</table>
|
||||
</div><!--[if mso]>
|
||||
</td>';
|
||||
$template['container_end'] = '
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<![endif]--></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
return $columnContainerTemplate;
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,87 +1,124 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Renderer {
|
||||
public $template = 'Template.html';
|
||||
public $blocks_renderer;
|
||||
public $columns_renderer;
|
||||
public $DOM_parser;
|
||||
public $CSS_inliner;
|
||||
public $newsletter;
|
||||
|
||||
function __construct($newsletterData) {
|
||||
$this->blocksRenderer = new Blocks\Renderer();
|
||||
$this->columnsRenderer = new Columns\Renderer();
|
||||
$this->stylesHelper = new StylesHelper();
|
||||
$this->DOMQuery = new \pQuery();
|
||||
$this->CSSInliner = new \MailPoet\Util\CSS();
|
||||
$this->data = $newsletterData;
|
||||
function __construct($newsletter) {
|
||||
$this->blocks_renderer = new Blocks\Renderer();
|
||||
$this->columns_renderer = new Columns\Renderer();
|
||||
$this->DOM_parser = new \pQuery();
|
||||
$this->CSS_inliner = new \MailPoet\Util\CSS();
|
||||
$this->newsletter = $newsletter;
|
||||
$this->template = file_get_contents(dirname(__FILE__) . '/' . $this->template);
|
||||
}
|
||||
|
||||
function renderAll() {
|
||||
$newsletterContent = $this->renderContent($this->data['content']);
|
||||
$newsletterStyles = $this->renderStyles($this->data['globalStyles']);
|
||||
|
||||
$renderedTemplate = $this->renderTemplate($this->template, array(
|
||||
$newsletterStyles,
|
||||
$newsletterContent
|
||||
function render() {
|
||||
$newsletter_data = (is_array($this->newsletter['body'])) ?
|
||||
$this->newsletter['body'] :
|
||||
json_decode($this->newsletter['body'], true);
|
||||
$newsletter_body = $this->renderBody($newsletter_data['content']);
|
||||
$newsletter_styles = $this->renderStyles($newsletter_data['globalStyles']);
|
||||
$newsletter_subject = $this->newsletter['subject'];
|
||||
$newsletter_preheader = $this->newsletter['preheader'];
|
||||
$template = $this->injectContentIntoTemplate($this->template, array(
|
||||
$newsletter_subject,
|
||||
$newsletter_styles,
|
||||
$newsletter_preheader,
|
||||
$newsletter_body
|
||||
));
|
||||
$renderedTemplateWithInlinedStyles = $this->inlineCSSStyles($renderedTemplate);
|
||||
|
||||
return $this->postProcessRenderedTemplate($renderedTemplateWithInlinedStyles);
|
||||
$template = $this->inlineCSSStyles($template);
|
||||
return $this->postProcessTemplate($template);
|
||||
}
|
||||
|
||||
function renderContent($content) {
|
||||
$newsletterContent = array_map(function ($contentBlock) {
|
||||
$columnCount = count($contentBlock['blocks']);
|
||||
$columnData = $this->blocksRenderer->render($contentBlock);
|
||||
return $this->columnsRenderer->render($columnCount, $columnData);
|
||||
function renderBody($content) {
|
||||
$content = array_map(function ($content_block) {
|
||||
$column_count = count($content_block['blocks']);
|
||||
$column_data = $this->blocks_renderer->render($content_block, $column_count);
|
||||
return $this->columns_renderer->render(
|
||||
$content_block['styles'],
|
||||
$column_count,
|
||||
$column_data
|
||||
);
|
||||
}, $content['blocks']);
|
||||
return implode('', $newsletterContent);
|
||||
return implode('', $content);
|
||||
}
|
||||
|
||||
function renderStyles($styles) {
|
||||
$newsletterStyles = '';
|
||||
foreach ($styles as $selector => $style) {
|
||||
switch ($selector) {
|
||||
$css = '';
|
||||
foreach($styles as $selector => $style) {
|
||||
switch($selector) {
|
||||
case 'h1':
|
||||
$selector = 'h1';
|
||||
break;
|
||||
case 'h2':
|
||||
$selector = 'h2';
|
||||
break;
|
||||
case 'h3':
|
||||
$selector = 'h3';
|
||||
break;
|
||||
case 'text':
|
||||
$selector = 'span.paragraph, ul, ol';
|
||||
$selector = '.mailpoet_paragraph, .mailpoet_blockquote';
|
||||
break;
|
||||
case 'body':
|
||||
$selector = '.mailpoet_content-wrapper';
|
||||
$selector = 'body, .mailpoet-wrapper';
|
||||
break;
|
||||
case 'link':
|
||||
$selector = '.mailpoet_content-wrapper a';
|
||||
$selector = '.mailpoet-wrapper a';
|
||||
break;
|
||||
case 'wrapper':
|
||||
$selector = '.mailpoet_container, .mailpoet_col-one, .mailpoet_col-two, .mailpoet_col-three';
|
||||
$selector = '.mailpoet_content-wrapper';
|
||||
break;
|
||||
}
|
||||
$newsletterStyles .= $selector . '{' . PHP_EOL;
|
||||
foreach ($style as $attribute => $individualStyle) {
|
||||
$newsletterStyles .= $this->stylesHelper->translateCSSAttribute($attribute) . ':' . $individualStyle . ';' . PHP_EOL;
|
||||
if(isset($style['fontSize'])) {
|
||||
$css .= StylesHelper::setFontAndLineHeight(
|
||||
(int) $style['fontSize'],
|
||||
$selector
|
||||
);
|
||||
unset($style['fontSize']);
|
||||
}
|
||||
$newsletterStyles .= '}' . PHP_EOL;
|
||||
if(isset($style['fontFamily'])) {
|
||||
$css .= StylesHelper::setFontFamily(
|
||||
$style['fontFamily'],
|
||||
$selector
|
||||
);
|
||||
unset($style['fontFamily']);
|
||||
}
|
||||
$css .= StylesHelper::setStyle($style, $selector);
|
||||
}
|
||||
|
||||
return $newsletterStyles;
|
||||
return $css;
|
||||
}
|
||||
|
||||
function renderTemplate($template, $data) {
|
||||
function injectContentIntoTemplate($template, $data) {
|
||||
return preg_replace_callback('/{{\w+}}/', function ($matches) use (&$data) {
|
||||
return array_shift($data);
|
||||
}, $template);
|
||||
}
|
||||
|
||||
function inlineCSSStyles($template) {
|
||||
return $this->CSSInliner->inlineCSS(null, $template);
|
||||
return $this->CSS_inliner->inlineCSS(null, $template);
|
||||
}
|
||||
|
||||
function postProcessRenderedTemplate($template) {
|
||||
// remove padding from last element inside each column
|
||||
$DOM = $this->DOMQuery->parseStr($template);
|
||||
$lastColumnElement = $DOM->query('.mailpoet_col > tbody > tr:last-child > td');
|
||||
foreach ($lastColumnElement as $element) {
|
||||
$element->setAttribute('style', str_replace('padding-bottom:20px;', '', $element->attributes['style']));
|
||||
}
|
||||
function renderTextVersion($template) {
|
||||
// TODO: add text rendering
|
||||
return $template;
|
||||
}
|
||||
|
||||
function postProcessTemplate($template) {
|
||||
// replace all !important tags except for in the body tag
|
||||
$DOM = $this->DOM_parser->parseStr($template);
|
||||
$template = $DOM->query('.mailpoet_template');
|
||||
$template->html(
|
||||
str_replace('!important', '', $template->html())
|
||||
);
|
||||
// TODO: return array with html and text body
|
||||
return $DOM->__toString();
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
<?php namespace MailPoet\Newsletter\Renderer;
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Renderer;
|
||||
|
||||
use MailPoet\Newsletter\Renderer\Columns\ColumnsHelper;
|
||||
|
||||
class StylesHelper {
|
||||
public $cssAtributesTable = array(
|
||||
static $css_attributes = array(
|
||||
'backgroundColor' => 'background-color',
|
||||
'fontColor' => 'color',
|
||||
'fontFamily' => 'font-family',
|
||||
@ -14,26 +17,236 @@ class StylesHelper {
|
||||
'borderRadius' => 'border-radius',
|
||||
'lineHeight' => 'line-height'
|
||||
);
|
||||
static $font = array(
|
||||
'Arial' => "Arial, 'Helvetica Neue', Helvetica, sans-serif",
|
||||
'Comic Sans MS' => "'Comic Sans MS', 'Marker Felt-Thin', Arial, sans-serif",
|
||||
'Courier New' => "'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Typewriter', monospace",
|
||||
'Georgia' => "Georgia, Times, 'Times New Roman', serif",
|
||||
'Lucida' => "'Lucida Sans Unicode', 'Lucida Grande', sans-serif",
|
||||
'Tahoma' => 'Tahoma, Verdana, Segoe, sans-serif',
|
||||
'Times New Roman' => "'Times New Roman', Times, Baskerville, Georgia, serif",
|
||||
'Trebuchet MS' => "'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif",
|
||||
'Verdana' => 'Verdana, Geneva, sans-serif'
|
||||
);
|
||||
static $font_size = array(
|
||||
// font_size => array(columnCount => lineHeight);
|
||||
8 => array(
|
||||
1 => "20",
|
||||
2 => "15",
|
||||
3 => "13"
|
||||
),
|
||||
9 => array(
|
||||
1 => "20",
|
||||
2 => "16",
|
||||
3 => "14"
|
||||
),
|
||||
10 => array(
|
||||
1 => "20",
|
||||
2 => "17",
|
||||
3 => "15"
|
||||
),
|
||||
11 => array(
|
||||
1 => "21",
|
||||
2 => "18",
|
||||
3 => "16"
|
||||
),
|
||||
12 => array(
|
||||
1 => "22",
|
||||
2 => "19",
|
||||
3 => "17"
|
||||
),
|
||||
13 => array(
|
||||
1 => "23",
|
||||
2 => "20",
|
||||
3 => "19"
|
||||
),
|
||||
14 => array(
|
||||
1 => "24",
|
||||
2 => "21",
|
||||
3 => "20"
|
||||
),
|
||||
15 => array(
|
||||
1 => "25",
|
||||
2 => "22",
|
||||
3 => "21"
|
||||
),
|
||||
16 => array(
|
||||
1 => "26",
|
||||
2 => "23",
|
||||
3 => "22"
|
||||
),
|
||||
17 => array(
|
||||
1 => "27",
|
||||
2 => "24",
|
||||
3 => "24"
|
||||
),
|
||||
18 => array(
|
||||
1 => "28",
|
||||
2 => "25",
|
||||
3 => "25"
|
||||
),
|
||||
19 => array(
|
||||
1 => "29",
|
||||
2 => "27",
|
||||
3 => "26"
|
||||
),
|
||||
20 => array(
|
||||
1 => "30",
|
||||
2 => "28",
|
||||
3 => "27"
|
||||
),
|
||||
21 => array(
|
||||
1 => "31",
|
||||
2 => "29",
|
||||
3 => "29"
|
||||
),
|
||||
22 => array(
|
||||
1 => "32",
|
||||
2 => "30",
|
||||
3 => "30"
|
||||
),
|
||||
23 => array(
|
||||
1 => "33",
|
||||
2 => "32",
|
||||
3 => "31"
|
||||
),
|
||||
24 => array(
|
||||
1 => "34",
|
||||
2 => "33",
|
||||
3 => "32"
|
||||
),
|
||||
25 => array(
|
||||
1 => "36",
|
||||
2 => "34",
|
||||
3 => "34"
|
||||
),
|
||||
26 => array(
|
||||
1 => "37",
|
||||
2 => "35",
|
||||
3 => "35"
|
||||
),
|
||||
27 => array(
|
||||
1 => "38",
|
||||
2 => "37",
|
||||
3 => "36"
|
||||
),
|
||||
28 => array(
|
||||
1 => "39",
|
||||
2 => "38",
|
||||
3 => "37"
|
||||
),
|
||||
29 => array(
|
||||
1 => "40",
|
||||
2 => "39",
|
||||
3 => "39"
|
||||
),
|
||||
30 => array(
|
||||
1 => "42",
|
||||
2 => "40",
|
||||
3 => "40"
|
||||
),
|
||||
31 => array(
|
||||
1 => "43",
|
||||
2 => "42",
|
||||
3 => "41"
|
||||
),
|
||||
32 => array(
|
||||
1 => "44",
|
||||
2 => "43",
|
||||
3 => "43"
|
||||
),
|
||||
33 => array(
|
||||
1 => "45",
|
||||
2 => "44",
|
||||
3 => "44"
|
||||
),
|
||||
34 => array(
|
||||
1 => "47",
|
||||
2 => "46",
|
||||
3 => "45"
|
||||
),
|
||||
35 => array(
|
||||
1 => "48",
|
||||
2 => "47",
|
||||
3 => "46"
|
||||
),
|
||||
36 => array(
|
||||
1 => "49",
|
||||
2 => "48",
|
||||
3 => "48"
|
||||
),
|
||||
37 => array(
|
||||
1 => "50",
|
||||
2 => "49",
|
||||
3 => "49"
|
||||
),
|
||||
38 => array(
|
||||
1 => "52",
|
||||
2 => "51",
|
||||
3 => "50"
|
||||
),
|
||||
39 => array(
|
||||
1 => "53",
|
||||
2 => "52",
|
||||
3 => "52"
|
||||
),
|
||||
40 => array(
|
||||
1 => "54",
|
||||
2 => "53",
|
||||
3 => "53"
|
||||
)
|
||||
);
|
||||
static $padding_width = 20;
|
||||
|
||||
function getBlockStyles($element, $ignoreSpecificStyles = false) {
|
||||
static function getBlockStyles($element, $ignore_specific_styles = false) {
|
||||
if(!isset($element['styles']['block'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->getStyles($element['styles'], 'block', $ignoreSpecificStyles);
|
||||
return self::getStyles($element['styles'], 'block', $ignore_specific_styles);
|
||||
}
|
||||
|
||||
function getStyles($data, $type, $ignoreSpecificStyles = false) {
|
||||
$styles = array_map(function ($attribute, $style) use($ignoreSpecificStyles) {
|
||||
if(!$ignoreSpecificStyles || !in_array($attribute, $ignoreSpecificStyles)) {
|
||||
return $this->translateCSSAttribute($attribute) . ': ' . $style . ' !important;';
|
||||
static function getStyles($data, $type, $ignore_specific_styles = false) {
|
||||
$styles = array_map(function ($attribute, $style) use ($ignore_specific_styles) {
|
||||
if(!$ignore_specific_styles || !in_array($attribute, $ignore_specific_styles)) {
|
||||
return self::translateCSSAttribute($attribute) . ': ' . $style . ' !important;';
|
||||
}
|
||||
}, array_keys($data[$type]), $data[$type]);
|
||||
|
||||
return implode('', $styles);
|
||||
}
|
||||
|
||||
function translateCSSAttribute($attribute) {
|
||||
return (array_key_exists($attribute, $this->cssAtributesTable)) ? $this->cssAtributesTable[$attribute] : $attribute;
|
||||
static function translateCSSAttribute($attribute) {
|
||||
return (array_key_exists($attribute, self::$css_attributes)) ?
|
||||
self::$css_attributes[$attribute] :
|
||||
$attribute;
|
||||
}
|
||||
}
|
||||
|
||||
static function setFontFamily($font_family, $selector) {
|
||||
$font_family = (isset(self::$font[$font_family])) ?
|
||||
self::$font[$font_family] :
|
||||
self::$font['Arial'];
|
||||
$css = $selector . '{' . PHP_EOL;
|
||||
$css .= 'font-family:' . $font_family . ';' . PHP_EOL;
|
||||
$css .= '}' . PHP_EOL;
|
||||
return $css;
|
||||
}
|
||||
|
||||
static function setFontAndLineHeight($font_size, $selector) {
|
||||
$css = '';
|
||||
foreach(ColumnsHelper::columnClasses() as $column_count => $column_class) {
|
||||
$css .= '.mailpoet_content-' . $column_class . ' ' . $selector . '{' . PHP_EOL;
|
||||
$css .= 'font-size:' . $font_size . 'px;' . PHP_EOL;
|
||||
$css .= 'line-height:' . StylesHelper::$font_size[$font_size][$column_count] . 'px;' . PHP_EOL;
|
||||
$css .= '}' . PHP_EOL;
|
||||
}
|
||||
return $css;
|
||||
}
|
||||
|
||||
static function setStyle($style, $selector) {
|
||||
$css = $selector . '{' . PHP_EOL;
|
||||
foreach($style as $attribute => $individual_style) {
|
||||
$css .= self::translateCSSAttribute($attribute) . ':' . $individual_style . ';' . PHP_EOL;
|
||||
}
|
||||
$css .= '}' . PHP_EOL;
|
||||
return $css;
|
||||
}
|
||||
}
|
@ -1,266 +1,91 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<title>MailPoet Newsletter Template</title>
|
||||
<title>{{newsletter_subject}}</title>
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ExternalClass * {
|
||||
line-height: 130%;
|
||||
}
|
||||
.ExternalClass a {
|
||||
line-height: 140%;
|
||||
}
|
||||
.ExternalClass h1, h2, h3, h1, h2, h3 {
|
||||
Margin: 0;
|
||||
}
|
||||
.ExternalClass ol {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table, td {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.mailpoet_image img {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
border: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
}
|
||||
.mailpoet_padded {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.mailpoet_padded_header_footer {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
@media screen and (max-width: 599px) and (-webkit-min-device-pixel-ratio: 1) {
|
||||
.mailpoet_header {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.mailpoet_button {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 5px 0 !important;
|
||||
}
|
||||
div, .mailpoet_cols-two, .mailpoet_cols-three {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
{{newsletter_styles}}
|
||||
</style>
|
||||
</head>
|
||||
<body style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; mso-line-height-rule: exactly; font-family: Helvetica, Arial, sans-serif; text-align: left; color: #333333; margin: 0; padding: 0;"
|
||||
bgcolor="#F0F0F0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
mso-line-height-rule: exactly;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
p,
|
||||
ol,
|
||||
ul,
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
li {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.ReadMsgBody {
|
||||
width: 100%;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table td {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
img {
|
||||
-ms-interpolation-mode: bicubic;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
td.mailpoet_button, .mailpoet_image, .mailpoet_text, .mailpoet_social {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.mailpoet_button div {
|
||||
padding: 8px 0 8px 0;
|
||||
}
|
||||
|
||||
.yshortcuts a {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.mailpoet_container {
|
||||
width: 600px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.mailpoet_col,
|
||||
.mailpoet_cols-wrapper {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.mailpoet_col-one,
|
||||
.mailpoet_col-two,
|
||||
.mailpoet_col-three {
|
||||
table-layout: fixed;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mailpoet_col-one,
|
||||
.mailpoet_col-two,
|
||||
.mailpoet_col-three,
|
||||
.mailpoet_header,
|
||||
.mailpoet_footer {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mailpoet_footer div, .mailpoet_header div {
|
||||
margin: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
/* .mailpoet_col-one ol,*/
|
||||
.mailpoet_col-one ul {
|
||||
margin-left: 18px;
|
||||
}
|
||||
|
||||
/*.mailpoet_col-two ol,*/
|
||||
.mailpoet_col-two ul {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.mailpoet_col-two li {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/*.mailpoet_col-three ol,*/
|
||||
.mailpoet_col-three ul {
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mailpoet_col-three li {
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.mailpoet_content-wrapper a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.mailpoet_padded {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
/*word-break: break-all;*/
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.mailpoet_centered {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mailpoet_center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mailpoet_right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mailpoet_left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mailpoet_justify {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.mailpoet_blockquote {
|
||||
border-left: 2px #565656 solid;
|
||||
padding-left: 10px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mailpoet_blockquote p.mailpoet_signature {
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mailpoet_social {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mailpoet_social img {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.mailpoet_social div {
|
||||
padding: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
.ios-footer a {
|
||||
color: #aaaaaa !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) and (-webkit-min-device-pixel-ratio: 1) {
|
||||
[class="mailpoet_cols-wrapper"] {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 599px) and (-webkit-min-device-pixel-ratio: 1) {
|
||||
[class~="mailpoet_force-row"],
|
||||
[class="mailpoet_container"] {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
a[class="mailpoet_button"] {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 5px 0 !important;
|
||||
}
|
||||
|
||||
td[class="mailpoet_col"] {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
[class=mailpoet_wrapper] ol,
|
||||
[class=mailpoet_wrapper] ul {
|
||||
margin-left: 18px !important;
|
||||
}
|
||||
|
||||
[class=mailpoet_wrapper] li {
|
||||
padding-left: 2px !important;
|
||||
}
|
||||
|
||||
.mailpoet_social img {
|
||||
height: 32px !important;
|
||||
width: 32px !important;
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{{newsletter_editor_styles}}
|
||||
|
||||
</style>
|
||||
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" class="mailpoet_content-wrapper" valign="top" style="border-collapse:collapse;" bgcolor="#333333">
|
||||
|
||||
<table border="0" width="600" cellpadding="0" cellspacing="0" class="mailpoet_container" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;max-width:600px">
|
||||
<tbody>
|
||||
{{newsletter_editor_content}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
|
||||
<table class="mailpoet_template" border="0" width="100%" cellpadding="0" cellspacing="0"
|
||||
style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="mailpoet_preheader" style="-webkit-text-size-adjust:none;font-size:1px;line-height:1px;color:#333333;" height="1">
|
||||
{{newsletter_preheader}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" class="mailpoet-wrapper" valign="top"><!--[if mso]>
|
||||
<table align="center" border="0" cellspacing="0" cellpadding="0"
|
||||
width="660">
|
||||
<tr>
|
||||
<td class="mailpoet_content-wrapper" align="center" valign="top" width="660">
|
||||
<![endif]--><table class="mailpoet_content-wrapper" border="0" width="660" cellpadding="0" cellspacing="0"
|
||||
style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;max-width:660px;width:100%;">
|
||||
<tbody>
|
||||
{{newsletter_body}}
|
||||
</tbody>
|
||||
</table><!--[if mso]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]--></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -1,38 +1,32 @@
|
||||
<?php
|
||||
namespace MailPoet\Router;
|
||||
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Util\Helpers;
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\Daemon;
|
||||
use MailPoet\Cron\Supervisor;
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Cron {
|
||||
function controlDaemon($data) {
|
||||
switch($data['action']) {
|
||||
case 'start':
|
||||
$supervisor = new \MailPoet\Cron\Supervisor($forceStart = true);
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => $supervisor->checkDaemon()
|
||||
)
|
||||
);
|
||||
exit;
|
||||
break;
|
||||
case 'stop':
|
||||
$status = 'stopped';
|
||||
break;
|
||||
default:
|
||||
$status = 'paused';
|
||||
break;
|
||||
}
|
||||
$daemon = new \MailPoet\Cron\Daemon();
|
||||
if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') {
|
||||
function start() {
|
||||
$supervisor = new Supervisor($forceStart = true);
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => $supervisor->checkDaemon() ? true : false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function stop() {
|
||||
$daemon = new Daemon();
|
||||
if(!$daemon->daemon ||
|
||||
$daemon->daemon['status'] !== 'started'
|
||||
) {
|
||||
$result = false;
|
||||
} else {
|
||||
$daemon->daemonData['status'] = $status;
|
||||
$daemon->daemon->value = json_encode($daemon->daemonData);
|
||||
$result = $daemon->daemon->save();
|
||||
$daemon->daemon['status'] = 'stopping';
|
||||
$result = $daemon->saveDaemon($daemon->daemon);
|
||||
}
|
||||
wp_send_json(
|
||||
array(
|
||||
@ -41,153 +35,29 @@ class Cron {
|
||||
);
|
||||
}
|
||||
|
||||
function getDaemonStatus() {
|
||||
$daemon = new \MailPoet\Cron\BootStrapMenu();
|
||||
wp_send_json($daemon->bootStrap());
|
||||
}
|
||||
|
||||
function addQueue($data) {
|
||||
$queue = SendingQueue::where('newsletter_id', $data['newsletter_id'])
|
||||
->whereNull('status')
|
||||
->findArray();
|
||||
|
||||
!d($queue);
|
||||
exit;
|
||||
$queue = SendingQueue::create();
|
||||
|
||||
$queue->newsletter_id = $data['newsletter_id'];
|
||||
|
||||
|
||||
$subscriber_ids = array();
|
||||
$segments = Segment::whereIn('id', $data['segments'])
|
||||
->findMany();
|
||||
foreach($segments as $segment) {
|
||||
$subscriber_ids = array_merge($subscriber_ids, Helpers::arrayColumn(
|
||||
$segment->subscribers()
|
||||
->findArray(),
|
||||
'id'
|
||||
));
|
||||
}
|
||||
|
||||
$subscriber_ids = array_unique($subscriber_ids);
|
||||
$queue->subscribers = json_encode(
|
||||
array(
|
||||
'to_process' => $subscriber_ids
|
||||
)
|
||||
);
|
||||
|
||||
$queue->count_total = $queue->count_to_process = count($subscriber_ids);
|
||||
$queue->save();
|
||||
function getStatus() {
|
||||
$daemon = Setting::where('name', 'cron_daemon')
|
||||
->findOne();
|
||||
wp_send_json(
|
||||
!$queue->save() ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => 'Queue could not be created.'
|
||||
($daemon) ?
|
||||
array_merge(
|
||||
array(
|
||||
'timeSinceStart' =>
|
||||
Carbon::createFromFormat(
|
||||
'Y-m-d H:i:s',
|
||||
$daemon->created_at,
|
||||
'UTC'
|
||||
)->diffForHumans(),
|
||||
'timeSinceUpdate' =>
|
||||
Carbon::createFromFormat(
|
||||
'Y-m-d H:i:s',
|
||||
$daemon->updated_at,
|
||||
'UTC'
|
||||
)->diffForHumans()
|
||||
),
|
||||
unserialize($daemon->value)
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => array($queue->id)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function addQueues($data) {
|
||||
$result = array_map(function ($queueData) {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $queueData['newsletter_id'];
|
||||
$queue->subscribers = json_encode(
|
||||
array(
|
||||
'to_process' => $queueData['subscribers']
|
||||
)
|
||||
);
|
||||
$queue->count_total = $queue->count_to_process = count($queueData['subscribers']);
|
||||
$queue->save();
|
||||
return array(
|
||||
'newsletter_id' => $queue->newsletter_id,
|
||||
'queue_id' => $queue->id
|
||||
);
|
||||
}, $data);
|
||||
$result = Helpers::arrayColumn($result, 'queue_id', 'newsletter_id');
|
||||
wp_send_json(
|
||||
count($data) != count($result) ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Some queues could not be created.'),
|
||||
'data' => $result
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $result
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function deleteQueue($data) {
|
||||
$queue = SendingQueue::whereNull('deleted_at')
|
||||
->findOne($data['queue_id']);
|
||||
if(!$queue) {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
)
|
||||
);
|
||||
}
|
||||
$queue->deleted_at = 'Y-m-d H:i:s';
|
||||
$queue->save();
|
||||
wp_send_json(array('result' => true));
|
||||
}
|
||||
|
||||
function deleteQueues($data) {
|
||||
$queues = SendingQueue::whereNull('deleted_at')
|
||||
->whereIn('id', $data['queue_ids'])
|
||||
->findResultSet();
|
||||
if(!$queues->count()) {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queues not found.')
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach($queues as $queue) {
|
||||
$queue->deleted_at = 'Y-m-d H:i:s';
|
||||
$queue->save();
|
||||
}
|
||||
wp_send_json(array('result' => true));
|
||||
}
|
||||
|
||||
function getQueueStatus($data) {
|
||||
$queue = SendingQueue::whereNull('deleted_at')
|
||||
->findOne($data['queue_id'])
|
||||
->asArray();
|
||||
wp_send_json(
|
||||
!$queue ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $queue
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getQueuesStatus($data) {
|
||||
$queues = SendingQueue::whereNull('deleted_at')
|
||||
->whereIn('id', $data['queue_ids'])
|
||||
->findArray();
|
||||
wp_send_json(
|
||||
!$queues ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $queues
|
||||
)
|
||||
"false"
|
||||
);
|
||||
}
|
||||
}
|
@ -1,191 +1,20 @@
|
||||
<?php
|
||||
namespace MailPoet\Router;
|
||||
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Mailer {
|
||||
function __construct($httpRequest = true) {
|
||||
$this->mailerType = array(
|
||||
'AmazonSES' => 'API',
|
||||
'ElasticEmail' => 'API',
|
||||
'MailGun' => 'API',
|
||||
'Mandrill' => 'API',
|
||||
'SendGrid' => 'API',
|
||||
'MailPoet' => null,
|
||||
'SMTP' => null,
|
||||
'WPMail' => null
|
||||
);
|
||||
if(!$httpRequest) {
|
||||
list($this->fromName, $this->fromEmail, $this->fromNameEmail)
|
||||
= $this->getSetting('sender');
|
||||
$this->mailer = $this->getSetting('mailer');
|
||||
}
|
||||
}
|
||||
|
||||
function send($data) {
|
||||
$subscriber = $this->transformSubscriber($data['subscriber']);
|
||||
list($fromName, $fromEmail, $fromNameEmail)
|
||||
= $this->getSetting('sender');
|
||||
if(!$fromName && !$fromEmail) {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'errors' => array(__('Please configure your name and e-mail address.'))
|
||||
)
|
||||
);
|
||||
}
|
||||
$data['mailer']['class'] = 'MailPoet\\Mailer\\' .
|
||||
(($this->mailerType[$data['mailer']['method']]) ?
|
||||
$this->mailerType[$data['mailer']['method']] . '\\' . $data['mailer']['method'] :
|
||||
$data['mailer']['method']
|
||||
);
|
||||
$mailer = $this->buildMailer(
|
||||
$data['mailer'],
|
||||
$fromName,
|
||||
$fromEmail,
|
||||
$fromNameEmail
|
||||
$mailer = new \MailPoet\Mailer\Mailer(
|
||||
(isset($data['mailer'])) ? $data['mailer'] : false,
|
||||
(isset($data['sender'])) ? $data['sender'] : false,
|
||||
(isset($data['reply_to'])) ? $data['reply_to'] : false
|
||||
);
|
||||
if(!empty($newsletter['sender_address']) &&
|
||||
!empty($newsletter['sender_name'])
|
||||
) {
|
||||
$mailer->fromName = $newsletter['sender_name'];
|
||||
$mailer->fromEmail = $newsletter['sender_address'];
|
||||
$mailer->fromNameEmail = sprintf(
|
||||
'%s <%s>',
|
||||
$mailer->fromName,
|
||||
$mailer->fromEmail
|
||||
);
|
||||
}
|
||||
if(!empty($newsletter['reply_to_address']) &&
|
||||
!empty($newsletter['reply_to_name'])
|
||||
) {
|
||||
$mailer->replyToName = $newsletter['reply_to_name'];
|
||||
$mailer->replyToEmail = $newsletter['reply_to_address'];
|
||||
$mailer->replyToNameEmail = sprintf(
|
||||
'%s <%s>',
|
||||
$mailer->replyToName,
|
||||
$mailer->replyToEmail
|
||||
);
|
||||
}
|
||||
$result = $mailer->send($data['newsletter'], $subscriber);
|
||||
$result = $mailer->send($data['newsletter'], $data['subscriber']);
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => ($result) ? true : false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildMailer($mailer = false, $fromName = false, $fromEmail = false, $fromNameEmail = false) {
|
||||
if(!$mailer) $mailer = $this->mailer;
|
||||
if(!$fromName) $fromName = $this->fromName;
|
||||
if(!$fromEmail) $fromEmail = $this->fromEmail;
|
||||
if(!$fromNameEmail) $fromNameEmail = $this->fromNameEmail;
|
||||
switch($mailer['method']) {
|
||||
case 'AmazonSES':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['region'],
|
||||
$mailer['access_key'],
|
||||
$mailer['secret_key'],
|
||||
$fromNameEmail
|
||||
);
|
||||
break;
|
||||
case 'ElasticEmail':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['api_key'],
|
||||
$fromEmail, $fromName
|
||||
);
|
||||
break;
|
||||
case 'MailGun':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['domain'],
|
||||
$mailer['api_key'],
|
||||
$fromNameEmail
|
||||
);
|
||||
break;
|
||||
case 'MailPoet':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['mailpoet_api_key'],
|
||||
$fromEmail,
|
||||
$fromName
|
||||
);
|
||||
break;
|
||||
case 'Mandrill':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['api_key'],
|
||||
$fromEmail, $fromName
|
||||
);
|
||||
break;
|
||||
case 'SendGrid':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['api_key'],
|
||||
$fromEmail,
|
||||
$fromName
|
||||
);
|
||||
break;
|
||||
case 'WPMail':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$fromEmail,
|
||||
$fromName
|
||||
);
|
||||
break;
|
||||
case 'SMTP':
|
||||
$mailerInstance = new $mailer['class'](
|
||||
$mailer['host'],
|
||||
$mailer['port'],
|
||||
$mailer['authentication'],
|
||||
$mailer['login'],
|
||||
$mailer['password'],
|
||||
$mailer['encryption'],
|
||||
$fromEmail,
|
||||
$fromName
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Mailing method does not exist.');
|
||||
break;
|
||||
}
|
||||
return $mailerInstance;
|
||||
}
|
||||
|
||||
function transformSubscriber($subscriber) {
|
||||
if(!is_array($subscriber)) return $subscriber;
|
||||
if(isset($subscriber['address'])) $subscriber['email'] = $subscriber['address'];
|
||||
$first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : '';
|
||||
$last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : '';
|
||||
if(!$first_name && !$last_name) return $subscriber['email'];
|
||||
$subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']);
|
||||
$subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber));
|
||||
return $subscriber;
|
||||
}
|
||||
|
||||
function getSetting($setting) {
|
||||
switch($setting) {
|
||||
case 'mailer':
|
||||
$mailer = Setting::getValue('mta', null);
|
||||
if(!$mailer || !isset($mailer['method'])) throw new \Exception('Mailing method is not configured.');
|
||||
$mailer['class'] = 'MailPoet\\Mailer\\' .
|
||||
(($this->mailerType[$mailer['method']]) ?
|
||||
$this->mailerType[$mailer['method']] . '\\' . $mailer['method'] :
|
||||
$mailer['method']
|
||||
);
|
||||
return $mailer;
|
||||
break;
|
||||
case 'sender':
|
||||
$sender = Setting::getValue($setting, null);
|
||||
if(!$sender) throw new \Exception('Sender name and email are not configured.');
|
||||
return array(
|
||||
$sender['name'],
|
||||
$sender['address'],
|
||||
sprintf('%s <%s>', $sender['name'], $sender['address'])
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return Setting::getValue($setting, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -188,12 +188,12 @@ class Newsletters {
|
||||
));
|
||||
}
|
||||
|
||||
// TO REMOVE once we add the columns from/reply_to
|
||||
// TODO: TO REMOVE once we add the columns from/reply_to
|
||||
$newsletter = array_merge($newsletter, $data['newsletter']);
|
||||
// END - TO REMOVE
|
||||
|
||||
$renderer = new Renderer(json_decode($newsletter['body'], true));
|
||||
$newsletter['body']['html'] = $renderer->renderAll();
|
||||
$newsletter['body']['html'] = $renderer->render();
|
||||
$newsletter['body']['text'] = '';
|
||||
|
||||
$subscribers = Subscriber::find_array();
|
||||
@ -217,8 +217,8 @@ class Newsletters {
|
||||
if(!isset($data['body'])) {
|
||||
wp_send_json(false);
|
||||
}
|
||||
$renderer = new Renderer(json_decode($data['body'], true));
|
||||
wp_send_json(array('rendered_body' => $renderer->renderAll()));
|
||||
$renderer = new Renderer($data);
|
||||
wp_send_json(array('rendered_body' => $renderer->render()));
|
||||
}
|
||||
|
||||
function listing($data = array()) {
|
||||
|
@ -1,196 +0,0 @@
|
||||
<?php
|
||||
namespace MailPoet\Router;
|
||||
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Queue {
|
||||
function controlDaemon($data) {
|
||||
switch($data['action']) {
|
||||
case 'start':
|
||||
$supervisor = new Supervisor($forceStart = true);
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => $supervisor->checkDaemon() ?
|
||||
true :
|
||||
false
|
||||
)
|
||||
);
|
||||
break;
|
||||
case 'stop':
|
||||
$status = 'stopped';
|
||||
break;
|
||||
default:
|
||||
$status = 'paused';
|
||||
break;
|
||||
}
|
||||
$daemon = new Daemon();
|
||||
if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') {
|
||||
$result = false;
|
||||
} else {
|
||||
$daemon->daemonData['status'] = $status;
|
||||
$daemon->daemon->value = json_encode($daemon->daemonData);
|
||||
$result = $daemon->daemon->save();
|
||||
}
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => $result
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getDaemonStatus() {
|
||||
$daemon = new \MailPoet\Cron\BootStrapMenu();
|
||||
wp_send_json($daemon->bootStrap());
|
||||
}
|
||||
|
||||
function addQueue($data) {
|
||||
$queue = SendingQueue::where('newsletter_id', $data['newsletter_id'])
|
||||
->whereNull('status')
|
||||
->findArray();
|
||||
|
||||
!d($queue);
|
||||
exit;
|
||||
$queue = SendingQueue::create();
|
||||
|
||||
$queue->newsletter_id = $data['newsletter_id'];
|
||||
|
||||
|
||||
$subscriber_ids = array();
|
||||
$segments = Segment::whereIn('id', $data['segments'])
|
||||
->findMany();
|
||||
foreach($segments as $segment) {
|
||||
$subscriber_ids = array_merge($subscriber_ids, Helpers::arrayColumn(
|
||||
$segment->subscribers()
|
||||
->findArray(),
|
||||
'id'
|
||||
));
|
||||
}
|
||||
|
||||
$subscriber_ids = array_unique($subscriber_ids);
|
||||
$queue->subscribers = json_encode(
|
||||
array(
|
||||
'to_process' => $subscriber_ids
|
||||
)
|
||||
);
|
||||
|
||||
$queue->count_total = $queue->count_to_process = count($subscriber_ids);
|
||||
$queue->save();
|
||||
wp_send_json(
|
||||
!$queue->save() ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => 'Queue could not be created.'
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => array($queue->id)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function addQueues($data) {
|
||||
$result = array_map(function ($queueData) {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $queueData['newsletter_id'];
|
||||
$queue->subscribers = json_encode(
|
||||
array(
|
||||
'to_process' => $queueData['subscribers']
|
||||
)
|
||||
);
|
||||
$queue->count_total = $queue->count_to_process = count($queueData['subscribers']);
|
||||
$queue->save();
|
||||
return array(
|
||||
'newsletter_id' => $queue->newsletter_id,
|
||||
'queue_id' => $queue->id
|
||||
);
|
||||
}, $data);
|
||||
$result = Helpers::arrayColumn($result, 'queue_id', 'newsletter_id');
|
||||
wp_send_json(
|
||||
count($data) != count($result) ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Some queues could not be created.'),
|
||||
'data' => $result
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $result
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function deleteQueue($data) {
|
||||
$queue = SendingQueue::whereNull('deleted_at')
|
||||
->findOne($data['queue_id']);
|
||||
if(!$queue) {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
)
|
||||
);
|
||||
}
|
||||
$queue->deleted_at = 'Y-m-d H:i:s';
|
||||
$queue->save();
|
||||
wp_send_json(array('result' => true));
|
||||
}
|
||||
|
||||
function deleteQueues($data) {
|
||||
$queues = SendingQueue::whereNull('deleted_at')
|
||||
->whereIn('id', $data['queue_ids'])
|
||||
->findResultSet();
|
||||
if(!$queues->count()) {
|
||||
wp_send_json(
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queues not found.')
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach($queues as $queue) {
|
||||
$queue->deleted_at = 'Y-m-d H:i:s';
|
||||
$queue->save();
|
||||
}
|
||||
wp_send_json(array('result' => true));
|
||||
}
|
||||
|
||||
function getQueueStatus($data) {
|
||||
$queue = SendingQueue::whereNull('deleted_at')
|
||||
->findOne($data['queue_id'])
|
||||
->asArray();
|
||||
wp_send_json(
|
||||
!$queue ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $queue
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getQueuesStatus($data) {
|
||||
$queues = SendingQueue::whereNull('deleted_at')
|
||||
->whereIn('id', $data['queue_ids'])
|
||||
->findArray();
|
||||
wp_send_json(
|
||||
!$queues ?
|
||||
array(
|
||||
'result' => false,
|
||||
'error' => __('Queue not found.')
|
||||
) :
|
||||
array(
|
||||
'result' => true,
|
||||
'data' => $queues
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ class SendingQueue {
|
||||
'errors' => array($e->getMessage())
|
||||
)
|
||||
);
|
||||
exit;
|
||||
}
|
||||
|
||||
$queue = \MailPoet\Models\SendingQueue::where('newsletter_id', $data['newsletter_id'])
|
||||
|
@ -6,15 +6,17 @@ use MailPoet\Models\Segment;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
class BootStrapMenu {
|
||||
public $action;
|
||||
|
||||
function __construct($action = null) {
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
function getSegments($withConfirmedSubscribers = false) {
|
||||
function getSegments($with_confirmed_subscribers = false) {
|
||||
$segments = ($this->action === 'import') ?
|
||||
Segment::getSegmentsWithSubscriberCount() :
|
||||
Segment::getSegmentsForExport($withConfirmedSubscribers);
|
||||
return array_map(function ($segment) {
|
||||
Segment::getSegmentsForExport($with_confirmed_subscribers);
|
||||
return array_map(function($segment) {
|
||||
return array(
|
||||
'id' => $segment['id'],
|
||||
'name' => $segment['name'],
|
||||
@ -29,6 +31,7 @@ class BootStrapMenu {
|
||||
'first_name' => __('First name'),
|
||||
'last_name' => __('Last name'),
|
||||
'status' => __('Status')
|
||||
// TODO: add additional fiels from MP2
|
||||
/*
|
||||
'confirmed_ip' => __('IP address')
|
||||
'confirmed_at' => __('Subscription date')
|
||||
@ -36,35 +39,35 @@ class BootStrapMenu {
|
||||
);
|
||||
}
|
||||
|
||||
function formatSubscriberFields($subscriberFields) {
|
||||
return array_map(function ($fieldId, $fieldName) {
|
||||
function formatSubscriberFields($subscriber_fields) {
|
||||
return array_map(function($field_id, $field_name) {
|
||||
return array(
|
||||
'id' => $fieldId,
|
||||
'name' => $fieldName,
|
||||
'type' => ($fieldId === 'confirmed_at') ? 'date' : null,
|
||||
'id' => $field_id,
|
||||
'name' => $field_name,
|
||||
'type' => ($field_id === 'confirmed_at') ? 'date' : null,
|
||||
'custom' => false
|
||||
);
|
||||
}, array_keys($subscriberFields), $subscriberFields);
|
||||
}, array_keys($subscriber_fields), $subscriber_fields);
|
||||
}
|
||||
|
||||
function getSubscriberCustomFields() {
|
||||
return CustomField::findArray();
|
||||
}
|
||||
|
||||
function formatSubscriberCustomFields($subscriberCustomFields) {
|
||||
return array_map(function ($field) {
|
||||
function formatSubscriberCustomFields($subscriber_custom_fields) {
|
||||
return array_map(function($field) {
|
||||
return array(
|
||||
'id' => $field['id'],
|
||||
'name' => $field['name'],
|
||||
'type' => $field['type'],
|
||||
'custom' => true
|
||||
);
|
||||
}, $subscriberCustomFields);
|
||||
}, $subscriber_custom_fields);
|
||||
}
|
||||
|
||||
function formatFieldsForSelect2(
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields) {
|
||||
$subscriber_fields,
|
||||
$subscriber_custom_fields) {
|
||||
$actions = ($this->action === 'import') ?
|
||||
array(
|
||||
array(
|
||||
@ -93,14 +96,14 @@ class BootStrapMenu {
|
||||
),
|
||||
array(
|
||||
'name' => __('System columns'),
|
||||
'children' => $this->formatSubscriberFields($subscriberFields)
|
||||
'children' => $this->formatSubscriberFields($subscriber_fields)
|
||||
)
|
||||
);
|
||||
if($subscriberCustomFields) {
|
||||
if($subscriber_custom_fields) {
|
||||
array_push($select2Fields, array(
|
||||
'name' => __('User columns'),
|
||||
'children' => $this->formatSubscriberCustomFields(
|
||||
$subscriberCustomFields
|
||||
$subscriber_custom_fields
|
||||
)
|
||||
));
|
||||
}
|
||||
@ -108,28 +111,28 @@ class BootStrapMenu {
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
$subscriberFields = $this->getSubscriberFields();
|
||||
$subscriberCustomFields = $this->getSubscriberCustomFields();
|
||||
$subscriber_fields = $this->getSubscriberFields();
|
||||
$subscriber_custom_fields = $this->getSubscriberCustomFields();
|
||||
$data['segments'] = json_encode($this->getSegments());
|
||||
$data['subscriberFieldsSelect2'] = json_encode(
|
||||
$this->formatFieldsForSelect2(
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
$subscriber_fields,
|
||||
$subscriber_custom_fields
|
||||
)
|
||||
);
|
||||
if($this->action === 'import') {
|
||||
$data['subscriberFields'] = json_encode(
|
||||
array_merge(
|
||||
$this->formatSubscriberFields($subscriberFields),
|
||||
$this->formatSubscriberCustomFields($subscriberCustomFields)
|
||||
$this->formatSubscriberFields($subscriber_fields),
|
||||
$this->formatSubscriberCustomFields($subscriber_custom_fields)
|
||||
)
|
||||
);
|
||||
$data['maxPostSizeBytes'] = Helpers::getMaxPostSize('bytes');
|
||||
$data['maxPostSize'] = Helpers::getMaxPostSize();
|
||||
} else {
|
||||
$data['segmentsWithConfirmedSubscribers'] =
|
||||
json_encode($this->getSegments($withConfirmedSubscribers = true));
|
||||
json_encode($this->getSegments($with_confirmed_subscribers = true));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
@ -11,106 +11,110 @@ use MailPoet\Util\Helpers;
|
||||
use MailPoet\Util\XLSXWriter;
|
||||
|
||||
class Export {
|
||||
public $export_confirmed_option;
|
||||
public $export_format_option;
|
||||
public $group_by_segment_option;
|
||||
public $segments;
|
||||
public $subscribers_without_segment;
|
||||
public $subscriber_fields;
|
||||
public $export_file;
|
||||
public $export_file_URL;
|
||||
public $profiler_start;
|
||||
|
||||
public function __construct($data) {
|
||||
$this->exportConfirmedOption = $data['exportConfirmedOption'];
|
||||
$this->exportFormatOption = $data['exportFormatOption'];
|
||||
$this->groupBySegmentOption = $data['groupBySegmentOption'];
|
||||
$this->export_confirmed_option = $data['export_confirmed_option'];
|
||||
$this->export_format_option = $data['export_format_option'];
|
||||
$this->group_by_segment_option = $data['group_by_segment_option'];
|
||||
$this->segments = $data['segments'];
|
||||
$this->subscribersWithoutSegment = array_search(0, $this->segments);
|
||||
$this->subscriberFields = $data['subscriberFields'];
|
||||
$this->exportFile = $this->getExportFile($this->exportFormatOption);
|
||||
$this->exportFileURL = $this->getExportFileURL($this->exportFile);
|
||||
$this->profilerStart = microtime(true);
|
||||
$this->subscribers_without_segment = array_search(0, $this->segments);
|
||||
$this->subscriber_fields = $data['subscriber_fields'];
|
||||
$this->export_file = $this->getExportFile($this->export_format_option);
|
||||
$this->export_file_URL = $this->getExportFileURL($this->export_file);
|
||||
$this->profiler_start = microtime(true);
|
||||
}
|
||||
|
||||
function process() {
|
||||
$subscribers = $this->getSubscribers();
|
||||
$subscriberCustomFields = $this->getSubscriberCustomFields();
|
||||
$formattedSubscriberFields = $this->formatSubscriberFields(
|
||||
$this->subscriberFields,
|
||||
$subscriberCustomFields
|
||||
$subscriber_custom_fields = $this->getSubscriberCustomFields();
|
||||
$formatted_subscriber_fields = $this->formatSubscriberFields(
|
||||
$this->subscriber_fields,
|
||||
$subscriber_custom_fields
|
||||
);
|
||||
try {
|
||||
if($this->exportFormatOption === 'csv') {
|
||||
$CSVFile = fopen($this->exportFile, 'w');
|
||||
$formatCSV = function ($row) {
|
||||
if($this->export_format_option === 'csv') {
|
||||
$CSV_file = fopen($this->export_file, 'w');
|
||||
$format_CSV = function($row) {
|
||||
return '"' . str_replace('"', '\"', $row) . '"';
|
||||
};
|
||||
// add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for
|
||||
// Excel to automatically recognize the encoding
|
||||
fwrite($CSVFile, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
||||
if($this->groupBySegmentOption) {
|
||||
$formattedSubscriberFields[] = __('List');
|
||||
fwrite($CSV_file, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
||||
if($this->group_by_segment_option) {
|
||||
$formatted_subscriber_fields[] = __('Segment');
|
||||
}
|
||||
fwrite(
|
||||
$CSVFile,
|
||||
$CSV_file,
|
||||
implode(
|
||||
',',
|
||||
array_map(
|
||||
$formatCSV,
|
||||
$formattedSubscriberFields
|
||||
$format_CSV,
|
||||
$formatted_subscriber_fields
|
||||
)
|
||||
) . "\n"
|
||||
);
|
||||
foreach ($subscribers as $subscriber) {
|
||||
$row = $this->formatSubscriberData(
|
||||
$subscriber,
|
||||
$formattedSubscriberFields
|
||||
);
|
||||
if($this->groupBySegmentOption) {
|
||||
foreach($subscribers as $subscriber) {
|
||||
$row = $this->formatSubscriberData($subscriber);
|
||||
if($this->group_by_segment_option) {
|
||||
$row[] = ucwords($subscriber['segment_name']);
|
||||
}
|
||||
fwrite($CSVFile, implode(',', array_map($formatCSV, $row)) . "\n");
|
||||
fwrite($CSV_file, implode(',', array_map($format_CSV, $row)) . "\n");
|
||||
}
|
||||
fclose($CSVFile);
|
||||
fclose($CSV_file);
|
||||
} else {
|
||||
$writer = new XLSXWriter();
|
||||
$writer->setAuthor('MailPoet (www.mailpoet.com)');
|
||||
$headerRow = array($formattedSubscriberFields);
|
||||
$lastSegment = false;
|
||||
$header_row = array($formatted_subscriber_fields);
|
||||
$last_segment = false;
|
||||
$rows = array();
|
||||
foreach ($subscribers as $subscriber) {
|
||||
if($lastSegment && $lastSegment !== $subscriber['segment_name'] &&
|
||||
$this->groupBySegmentOption
|
||||
foreach($subscribers as $subscriber) {
|
||||
if($last_segment && $last_segment !== $subscriber['segment_name'] &&
|
||||
$this->group_by_segment_option
|
||||
) {
|
||||
$writer->writeSheet(
|
||||
array_merge($headerRow, $rows), ucwords($lastSegment)
|
||||
array_merge($header_row, $rows), ucwords($last_segment)
|
||||
);
|
||||
$rows = array();
|
||||
}
|
||||
// detect RTL language and set Excel to properly display the sheet
|
||||
$RTLRegex = '/\p{Arabic}|\p{Hebrew}/u';
|
||||
$RTL_regex = '/\p{Arabic}|\p{Hebrew}/u';
|
||||
if(!$writer->rtl && (
|
||||
preg_grep($RTLRegex, $subscriber) ||
|
||||
preg_grep($RTLRegex, $formattedSubscriberFields))
|
||||
preg_grep($RTL_regex, $subscriber) ||
|
||||
preg_grep($RTL_regex, $formatted_subscriber_fields))
|
||||
) {
|
||||
$writer->rtl = true;
|
||||
}
|
||||
$rows[] = $this->formatSubscriberData(
|
||||
$subscriber,
|
||||
$formattedSubscriberFields
|
||||
);
|
||||
$lastSegment = $subscriber['segment_name'];
|
||||
$rows[] = $this->formatSubscriberData($subscriber);
|
||||
$last_segment = $subscriber['segment_name'];
|
||||
}
|
||||
$writer->writeSheet(
|
||||
array_merge($headerRow, $rows),
|
||||
($this->groupBySegmentOption) ?
|
||||
array_merge($header_row, $rows),
|
||||
($this->group_by_segment_option) ?
|
||||
ucwords($subscriber['segment_name']) :
|
||||
'MailPoet'
|
||||
__('All Segments')
|
||||
);
|
||||
$writer->writeToFile($this->exportFile);
|
||||
$writer->writeToFile($this->export_file);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
} catch(Exception $e) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'error' => $e->getMessage()
|
||||
'errors' => array($e->getMessage())
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'totalExported' => count($subscribers),
|
||||
'exportFileURL' => $this->exportFileURL
|
||||
'exportFileURL' => $this->export_file_URL
|
||||
),
|
||||
'profiler' => $this->timeExecution()
|
||||
);
|
||||
@ -134,11 +138,11 @@ class Export {
|
||||
))
|
||||
->orderByAsc('segment_name')
|
||||
->filter('filterWithCustomFieldsForExport');
|
||||
if($this->subscribersWithoutSegment !== false) {
|
||||
if($this->subscribers_without_segment !== false) {
|
||||
$subscribers = $subscribers
|
||||
->selectExpr('CASE WHEN ' . Segment::$_table . '.name IS NOT NULL ' .
|
||||
'THEN ' . Segment::$_table . '.name ' .
|
||||
'ELSE "' . __('Not In List') . '" END as segment_name'
|
||||
'ELSE "' . __('Not In Segment') . '" END as segment_name'
|
||||
)
|
||||
->whereRaw(
|
||||
SubscriberSegment::$_table . '.segment_id IN (' .
|
||||
@ -151,11 +155,11 @@ class Export {
|
||||
->select(Segment::$_table . '.name', 'segment_name')
|
||||
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments);
|
||||
}
|
||||
if(!$this->groupBySegmentOption) {
|
||||
if(!$this->group_by_segment_option) {
|
||||
$subscribers =
|
||||
$subscribers->groupBy(Subscriber::$_table . '.id');
|
||||
}
|
||||
if($this->exportConfirmedOption) {
|
||||
if($this->export_confirmed_option) {
|
||||
$subscribers =
|
||||
$subscribers->where(Subscriber::$_table . '.status', 'subscribed');
|
||||
}
|
||||
@ -166,9 +170,8 @@ class Export {
|
||||
|
||||
function getExportFileURL($file) {
|
||||
return sprintf(
|
||||
'%s/%s/%s',
|
||||
Env::$plugin_url,
|
||||
Env::$temp_name,
|
||||
'%s/%s',
|
||||
Env::$temp_URL,
|
||||
basename($file)
|
||||
);
|
||||
}
|
||||
@ -189,32 +192,28 @@ class Export {
|
||||
);
|
||||
}
|
||||
|
||||
function formatSubscriberFields($subscriberFields, $subscriberCustomFields) {
|
||||
$bootStrapMenu = new BootStrapMenu();
|
||||
$translatedFields = $bootStrapMenu->getSubscriberFields();
|
||||
return array_map(function ($field) use (
|
||||
$translatedFields, $subscriberCustomFields
|
||||
function formatSubscriberFields($subscriber_fields, $subscriber_custom_fields) {
|
||||
$bootstrap_menu = new BootStrapMenu();
|
||||
$translated_fields = $bootstrap_menu->getSubscriberFields();
|
||||
return array_map(function($field) use (
|
||||
$translated_fields, $subscriber_custom_fields
|
||||
) {
|
||||
$field = (isset($translatedFields[$field])) ?
|
||||
ucfirst($translatedFields[$field]) :
|
||||
$field = (isset($translated_fields[$field])) ?
|
||||
ucfirst($translated_fields[$field]) :
|
||||
ucfirst($field);
|
||||
return (isset($subscriberCustomFields[$field])) ?
|
||||
$subscriberCustomFields[$field] : $field;
|
||||
}, $subscriberFields);
|
||||
return (isset($subscriber_custom_fields[$field])) ?
|
||||
ucfirst($subscriber_custom_fields[$field]) : $field;
|
||||
}, $subscriber_fields);
|
||||
}
|
||||
|
||||
function formatSubscriberData($subscriber, $subscriberCustomFields) {
|
||||
return array_map(function ($field) use (
|
||||
$subscriber, $subscriberCustomFields
|
||||
) {
|
||||
return (isset($subscriberCustomFields[$field])) ?
|
||||
$subscriberCustomFields[$field] :
|
||||
$subscriber[$field];
|
||||
}, $this->subscriberFields);
|
||||
function formatSubscriberData($subscriber) {
|
||||
return array_map(function($field) use ($subscriber) {
|
||||
return $subscriber[$field];
|
||||
}, $this->subscriber_fields);
|
||||
}
|
||||
|
||||
function timeExecution() {
|
||||
$profilerEnd = microtime(true);
|
||||
return ($profilerEnd - $this->profilerStart) / 60;
|
||||
$profiler_end = microtime(true);
|
||||
return ($profiler_end - $this->profiler_start) / 60;
|
||||
}
|
||||
}
|
@ -8,192 +8,201 @@ use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
class Import {
|
||||
public $subscribers_data;
|
||||
public $segments;
|
||||
public $update_subscribers;
|
||||
public $subscriber_fields;
|
||||
public $subscriber_custom_fields;
|
||||
public $subscribers_count;
|
||||
public $import_time;
|
||||
public $profiler_start;
|
||||
|
||||
public function __construct($data) {
|
||||
$this->subscribersData = $data['subscribers'];
|
||||
$this->subscribers_data = $data['subscribers'];
|
||||
$this->segments = $data['segments'];
|
||||
$this->updateSubscribers = $data['updateSubscribers'];
|
||||
$this->subscriberFields = $this->getSubscriberFields(
|
||||
array_keys($this->subscribersData)
|
||||
$this->update_subscribers = $data['updateSubscribers'];
|
||||
$this->subscriber_fields = $this->getSubscriberFields(
|
||||
array_keys($this->subscribers_data)
|
||||
);
|
||||
$this->subscriberCustomFields = $this->getCustomSubscriberFields(
|
||||
array_keys($this->subscribersData)
|
||||
$this->subscriber_custom_fields = $this->getCustomSubscriberFields(
|
||||
array_keys($this->subscribers_data)
|
||||
);
|
||||
$this->subscribersCount = count(reset($this->subscribersData));
|
||||
$this->currentTime = date('Y-m-d H:i:s');
|
||||
$this->profilerStart = microtime(true);
|
||||
$this->subscribers_count = count(reset($this->subscribers_data));
|
||||
$this->import_time = date('Y-m-d H:i:s');
|
||||
$this->profiler_start = microtime(true);
|
||||
}
|
||||
|
||||
|
||||
function process() {
|
||||
$subscriberFields = $this->subscriberFields;
|
||||
$subscriberCustomFields = $this->subscriberCustomFields;
|
||||
$subscribersData = $this->subscribersData;
|
||||
list ($subscribersData, $subscriberFields) =
|
||||
$this->filterSubscriberStatus($subscribersData, $subscriberFields);
|
||||
$this->deleteExistingTrashedSubscribers($subscribersData);
|
||||
list($subscribersData, $subscriberFields) = $this->extendSubscribersAndFields(
|
||||
$subscribersData, $subscriberFields
|
||||
$subscriber_fields = $this->subscriber_fields;
|
||||
$subscriber_custom_fields = $this->subscriber_custom_fields;
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
list ($subscribers_data, $subscriber_fields) =
|
||||
$this->filterSubscriberStatus($subscribers_data, $subscriber_fields);
|
||||
$this->deleteExistingTrashedSubscribers($subscribers_data);
|
||||
list($subscribers_data, $subscriber_fields) = $this->extendSubscribersAndFields(
|
||||
$subscribers_data, $subscriber_fields
|
||||
);
|
||||
list($existingSubscribers, $newSubscribers) =
|
||||
$this->filterExistingAndNewSubscribers($subscribersData);
|
||||
$createdSubscribers = $updatedSubscribers = array();
|
||||
list($existing_subscribers, $new_subscribers) =
|
||||
$this->filterExistingAndNewSubscribers($subscribers_data);
|
||||
$created_subscribers = $updated_subscribers = array();
|
||||
try {
|
||||
if($newSubscribers) {
|
||||
$createdSubscribers =
|
||||
if($new_subscribers) {
|
||||
$created_subscribers =
|
||||
$this->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$newSubscribers,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
$new_subscribers,
|
||||
$subscriber_fields,
|
||||
$subscriber_custom_fields
|
||||
);
|
||||
}
|
||||
if($existingSubscribers && $this->updateSubscribers) {
|
||||
$updatedSubscribers =
|
||||
if($existing_subscribers && $this->update_subscribers) {
|
||||
$updated_subscribers =
|
||||
$this->createOrUpdateSubscribers(
|
||||
'update',
|
||||
$existingSubscribers,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
$existing_subscribers,
|
||||
$subscriber_fields,
|
||||
$subscriber_custom_fields
|
||||
);
|
||||
if($createdSubscribers) {
|
||||
if($created_subscribers) {
|
||||
// subtract added from updated subscribers when DB operation takes <1s
|
||||
$updatedSubscribers = array_diff_key(
|
||||
$updatedSubscribers,
|
||||
$createdSubscribers,
|
||||
$subscriberCustomFields
|
||||
$updated_subscribers = array_diff_key(
|
||||
$updated_subscribers,
|
||||
$created_subscribers,
|
||||
$subscriber_custom_fields
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch(\PDOException $e) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'error' => $e->getMessage()
|
||||
'errors' => array($e->getMessage())
|
||||
);
|
||||
}
|
||||
$segments = new BootStrapMenu('import');
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'created' => count($createdSubscribers),
|
||||
'updated' => count($updatedSubscribers),
|
||||
'created' => count($created_subscribers),
|
||||
'updated' => count($updated_subscribers),
|
||||
'segments' => $segments->getSegments()
|
||||
),
|
||||
'profiler' => $this->timeExecution()
|
||||
);
|
||||
}
|
||||
|
||||
function filterExistingAndNewSubscribers($subscribersData) {
|
||||
$existingRecords = array_filter(
|
||||
array_map(function ($subscriberEmails) {
|
||||
|
||||
function filterExistingAndNewSubscribers($subscribers_data) {
|
||||
$existing_records = array_filter(
|
||||
array_map(function($subscriber_emails) {
|
||||
return Subscriber::selectMany(array('email'))
|
||||
->whereIn('email', $subscriberEmails)
|
||||
->whereIn('email', $subscriber_emails)
|
||||
->whereNull('deleted_at')
|
||||
->findArray();
|
||||
}, array_chunk($subscribersData['email'], 200))
|
||||
}, array_chunk($subscribers_data['email'], 200))
|
||||
);
|
||||
if(!$existingRecords) {
|
||||
if(!$existing_records) {
|
||||
return array(
|
||||
false,
|
||||
$subscribersData
|
||||
$subscribers_data
|
||||
);
|
||||
}
|
||||
$existingRecords = Helpers::flattenArray($existingRecords);
|
||||
$newRecords = array_keys(
|
||||
$existing_records = Helpers::flattenArray($existing_records);
|
||||
$new_records = array_keys(
|
||||
array_diff(
|
||||
$subscribersData['email'],
|
||||
$existingRecords
|
||||
$subscribers_data['email'],
|
||||
$existing_records
|
||||
)
|
||||
);
|
||||
if(!$newRecords) {
|
||||
if(!$new_records) {
|
||||
return array(
|
||||
$subscribersData,
|
||||
$subscribers_data,
|
||||
false
|
||||
);
|
||||
}
|
||||
$newSubscribers =
|
||||
$new_subscribers =
|
||||
array_filter(
|
||||
array_map(function ($subscriber) use ($newRecords) {
|
||||
return array_map(function ($index) use ($subscriber) {
|
||||
array_map(function($subscriber) use ($new_records) {
|
||||
return array_map(function($index) use ($subscriber) {
|
||||
return $subscriber[$index];
|
||||
}, $newRecords);
|
||||
}, $subscribersData)
|
||||
}, $new_records);
|
||||
}, $subscribers_data)
|
||||
);
|
||||
|
||||
$existingSubscribers =
|
||||
array_map(function ($subscriber) use ($newRecords) {
|
||||
|
||||
$existing_subscribers =
|
||||
array_map(function($subscriber) use ($new_records) {
|
||||
return array_values( // reindex array
|
||||
array_filter( // remove NULL entries
|
||||
array_map(function ($index, $data) use ($newRecords) {
|
||||
if(!in_array($index, $newRecords)) return $data;
|
||||
array_map(function($index, $data) use ($new_records) {
|
||||
if(!in_array($index, $new_records)) return $data;
|
||||
}, array_keys($subscriber), $subscriber)
|
||||
)
|
||||
);
|
||||
}, $subscribersData);
|
||||
}, $subscribers_data);
|
||||
return array(
|
||||
$existingSubscribers,
|
||||
$newSubscribers
|
||||
$existing_subscribers,
|
||||
$new_subscribers
|
||||
);
|
||||
}
|
||||
|
||||
function deleteExistingTrashedSubscribers($subscribersData) {
|
||||
$existingTrashedRecords = array_filter(
|
||||
array_map(function ($subscriberEmails) {
|
||||
|
||||
function deleteExistingTrashedSubscribers($subscribers_data) {
|
||||
$existing_trashed_records = array_filter(
|
||||
array_map(function($subscriber_emails) {
|
||||
return Subscriber::selectMany(array('id'))
|
||||
->whereIn('email', $subscriberEmails)
|
||||
->whereIn('email', $subscriber_emails)
|
||||
->whereNotNull('deleted_at')
|
||||
->findArray();
|
||||
}, array_chunk($subscribersData['email'], 200))
|
||||
}, array_chunk($subscribers_data['email'], 200))
|
||||
);
|
||||
if(!$existingTrashedRecords) return;
|
||||
$existingTrashedRecords = Helpers::flattenArray($existingTrashedRecords);
|
||||
foreach(array_chunk($existingTrashedRecords, 200) as $subscriberIds) {
|
||||
Subscriber::whereIn('id', $subscriberIds)
|
||||
if(!$existing_trashed_records) return;
|
||||
$existing_trashed_records = Helpers::flattenArray($existing_trashed_records);
|
||||
foreach(array_chunk($existing_trashed_records, 200) as $subscriber_ids) {
|
||||
Subscriber::whereIn('id', $subscriber_ids)
|
||||
->deleteMany();
|
||||
SubscriberSegment::whereIn('subscriber_id', $subscriberIds)
|
||||
SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)
|
||||
->deleteMany();
|
||||
}
|
||||
}
|
||||
|
||||
function extendSubscribersAndFields($subscribersData, $subscriberFields) {
|
||||
$subscribersData['created_at'] = $this->filterSubscriberCreatedAtDate();
|
||||
$subscriberFields[] = 'created_at';
|
||||
|
||||
function extendSubscribersAndFields($subscribers_data, $subscriber_fields) {
|
||||
$subscribers_data['created_at'] = $this->filterSubscriberCreatedAtDate();
|
||||
$subscriber_fields[] = 'created_at';
|
||||
return array(
|
||||
$subscribersData,
|
||||
$subscriberFields
|
||||
$subscribers_data,
|
||||
$subscriber_fields
|
||||
);
|
||||
}
|
||||
|
||||
function getSubscriberFields($subscriberFields) {
|
||||
|
||||
function getSubscriberFields($subscriber_fields) {
|
||||
return array_values(
|
||||
array_filter(
|
||||
array_map(function ($field) {
|
||||
array_map(function($field) {
|
||||
if(!is_int($field)) return $field;
|
||||
}, $subscriberFields)
|
||||
}, $subscriber_fields)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getCustomSubscriberFields($subscriberFields) {
|
||||
|
||||
function getCustomSubscriberFields($subscriber_fields) {
|
||||
return array_values(
|
||||
array_filter(
|
||||
array_map(function ($field) {
|
||||
array_map(function($field) {
|
||||
if(is_int($field)) return $field;
|
||||
}, $subscriberFields)
|
||||
}, $subscriber_fields)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function filterSubscriberCreatedAtDate() {
|
||||
return array_fill(0, $this->subscribersCount, $this->currentTime);
|
||||
return array_fill(0, $this->subscribers_count, $this->import_time);
|
||||
}
|
||||
|
||||
function filterSubscriberStatus($subscribersData, $subscriberFields) {
|
||||
if(!in_array('status', $subscriberFields)) {
|
||||
$subscribersData['status'] =
|
||||
array_fill(0, count($subscribersData['email']), 'subscribed');
|
||||
$subscriberFields[] = 'status';
|
||||
|
||||
function filterSubscriberStatus($subscribers_data, $subscriber_fields) {
|
||||
if(!in_array('status', $subscriber_fields)) {
|
||||
$subscribers_data['status'] =
|
||||
array_fill(0, count($subscribers_data['email']), 'subscribed');
|
||||
$subscriber_fields[] = 'status';
|
||||
return array(
|
||||
$subscribersData,
|
||||
$subscriberFields
|
||||
$subscribers_data,
|
||||
$subscriber_fields
|
||||
);
|
||||
}
|
||||
$statuses = array(
|
||||
@ -216,7 +225,7 @@ class Import {
|
||||
'false'
|
||||
)
|
||||
);
|
||||
$subscribersData['status'] = array_map(function ($state) use ($statuses) {
|
||||
$subscribers_data['status'] = array_map(function($state) use ($statuses) {
|
||||
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
||||
return 'subscribed';
|
||||
}
|
||||
@ -227,38 +236,38 @@ class Import {
|
||||
return 'unconfirmed';
|
||||
}
|
||||
return 'subscribed'; // make "subscribed" a default status
|
||||
}, $subscribersData['status']);
|
||||
}, $subscribers_data['status']);
|
||||
return array(
|
||||
$subscribersData,
|
||||
$subscriberFields
|
||||
$subscribers_data,
|
||||
$subscriber_fields
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function createOrUpdateSubscribers(
|
||||
$action,
|
||||
$subscribersData,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
$subscribers_data,
|
||||
$subscriber_fields,
|
||||
$subscriber_custom_fields
|
||||
) {
|
||||
$subscribersCount = count(reset($subscribersData)) - 1;
|
||||
$subscribers = array_map(function ($index) use ($subscribersData, $subscriberFields) {
|
||||
return array_map(function ($field) use ($index, $subscribersData) {
|
||||
return $subscribersData[$field][$index];
|
||||
}, $subscriberFields);
|
||||
}, range(0, $subscribersCount));
|
||||
$currentTime = ($action === 'update') ? date('Y-m-d H:i:s') : $this->currentTime;
|
||||
$subscribers_count = count(reset($subscribers_data)) - 1;
|
||||
$subscribers = array_map(function($index) use ($subscribers_data, $subscriber_fields) {
|
||||
return array_map(function($field) use ($index, $subscribers_data) {
|
||||
return $subscribers_data[$field][$index];
|
||||
}, $subscriber_fields);
|
||||
}, range(0, $subscribers_count));
|
||||
$import_time = ($action === 'update') ? date('Y-m-d H:i:s') : $this->import_time;
|
||||
foreach(array_chunk($subscribers, 100) as $data) {
|
||||
if($action == 'create') {
|
||||
Subscriber::createMultiple(
|
||||
$subscriberFields,
|
||||
$subscriber_fields,
|
||||
$data
|
||||
);
|
||||
}
|
||||
if($action == 'update') {
|
||||
Subscriber::updateMultiple(
|
||||
$subscriberFields,
|
||||
$subscriber_fields,
|
||||
$data,
|
||||
$currentTime
|
||||
$import_time
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -268,16 +277,16 @@ class Import {
|
||||
'id',
|
||||
'email'
|
||||
))
|
||||
->where(($action === 'create') ? 'created_at' : 'updated_at', $currentTime)
|
||||
->where(($action === 'create') ? 'created_at' : 'updated_at', $import_time)
|
||||
->findArray(),
|
||||
'email', 'id'
|
||||
);
|
||||
if($subscriberCustomFields) {
|
||||
if($subscriber_custom_fields) {
|
||||
$this->createOrUpdateCustomFields(
|
||||
($action === 'create') ? 'create' : 'update',
|
||||
$result,
|
||||
$subscribersData,
|
||||
$subscriberCustomFields
|
||||
$subscribers_data,
|
||||
$subscriber_custom_fields
|
||||
);
|
||||
}
|
||||
$this->addSubscribersToSegments(
|
||||
@ -286,30 +295,30 @@ class Import {
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
function createOrUpdateCustomFields(
|
||||
$action,
|
||||
$dbSubscribers,
|
||||
$subscribersData,
|
||||
$subscriberCustomFields
|
||||
$db_subscribers,
|
||||
$subscribers_data,
|
||||
$subscriber_custom_fields
|
||||
) {
|
||||
$subscribers = array_map(
|
||||
function ($column) use ($dbSubscribers, $subscribersData) {
|
||||
$count = range(0, count($subscribersData[$column]) - 1);
|
||||
function($column) use ($db_subscribers, $subscribers_data) {
|
||||
$count = range(0, count($subscribers_data[$column]) - 1);
|
||||
return array_map(
|
||||
function ($index, $value)
|
||||
use ($dbSubscribers, $subscribersData, $column) {
|
||||
$subscriberId = array_search(
|
||||
$subscribersData['email'][$index],
|
||||
$dbSubscribers
|
||||
function($index, $value)
|
||||
use ($db_subscribers, $subscribers_data, $column) {
|
||||
$subscriber_id = array_search(
|
||||
$subscribers_data['email'][$index],
|
||||
$db_subscribers
|
||||
);
|
||||
return array(
|
||||
$column,
|
||||
$subscriberId,
|
||||
$subscriber_id,
|
||||
$value
|
||||
);
|
||||
}, $count, $subscribersData[$column]);
|
||||
}, $subscriberCustomFields)[0];
|
||||
}, $count, $subscribers_data[$column]);
|
||||
}, $subscriber_custom_fields)[0];
|
||||
foreach(array_chunk($subscribers, 200) as $data) {
|
||||
if($action === 'create') {
|
||||
SubscriberCustomField::createMultiple(
|
||||
@ -323,15 +332,15 @@ class Import {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addSubscribersToSegments($subscribers, $segments) {
|
||||
foreach(array_chunk($subscribers, 200) as $data) {
|
||||
SubscriberSegment::createMultiple($segments, $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function timeExecution() {
|
||||
$profilerEnd = microtime(true);
|
||||
return ($profilerEnd - $this->profilerStart) / 60;
|
||||
$profiler_end = microtime(true);
|
||||
return ($profiler_end - $this->profiler_start) / 60;
|
||||
}
|
||||
}
|
@ -365,9 +365,6 @@ class CSS {
|
||||
// And put the CSS back as a string!
|
||||
$node->style = self::arrayToStyle($style);
|
||||
|
||||
// remove all !important tags (inlined styles take precedent over others anyway)
|
||||
$node->style = str_replace("!important", "", $node->style);
|
||||
|
||||
// I'm leaving this for debug purposes, it has proved useful.
|
||||
/*
|
||||
if($rule['selector'] === 'table.table-recap td')
|
||||
|
@ -5,7 +5,7 @@ if (!defined('ABSPATH')) exit;
|
||||
|
||||
/*
|
||||
* Plugin Name: MailPoet
|
||||
* Version: 0.0.8
|
||||
* Version: 0.0.10
|
||||
* Plugin URI: http://www.mailpoet.com
|
||||
* Description: MailPoet Newsletters.
|
||||
* Author: MailPoet
|
||||
@ -23,7 +23,7 @@ if (!defined('ABSPATH')) exit;
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
define('MAILPOET_VERSION', '0.0.8');
|
||||
define('MAILPOET_VERSION', '0.0.10');
|
||||
|
||||
$initializer = new Initializer(array(
|
||||
'file' => __FILE__,
|
||||
|
@ -5,8 +5,7 @@
|
||||
},
|
||||
"napa": {
|
||||
"blob": "eligrey/Blob.js.git",
|
||||
"filesaver": "eligrey/FileSaver.js.git",
|
||||
"sticky-kit": "leafo/sticky-kit.git"
|
||||
"filesaver": "eligrey/FileSaver.js.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"backbone": "1.2.3",
|
||||
@ -35,7 +34,8 @@
|
||||
"select2": "^4.0.0",
|
||||
"spectrum-colorpicker": "^1.6.2",
|
||||
"tinymce": "4.1.10",
|
||||
"underscore": "1.8.3"
|
||||
"underscore": "1.8.3",
|
||||
"velocity-animate": "1.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expose-loader": "latest",
|
||||
|
100
tests/unit/Mailer/MailerCest.php
Normal file
100
tests/unit/Mailer/MailerCest.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
use MailPoet\Mailer\Mailer;
|
||||
|
||||
class MailerCest {
|
||||
function _before() {
|
||||
$this->sender = array(
|
||||
'name' => 'Sender',
|
||||
'address' => 'staff@mailinator.com'
|
||||
);
|
||||
$this->reply_to = array(
|
||||
'name' => 'Reply To',
|
||||
'address' => 'staff@mailinator.com'
|
||||
);
|
||||
$this->mailer = array(
|
||||
'method' => 'MailPoet',
|
||||
'mailpoet_api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing Mailer',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itRequiresMailerMethod() {
|
||||
try {
|
||||
$mailer = new Mailer();
|
||||
} catch (Exception $e) {
|
||||
expect($e->getMessage())->equals('Mailer is not configured.');
|
||||
}
|
||||
}
|
||||
|
||||
function itRequiresSender() {
|
||||
try {
|
||||
$mailer = new Mailer($mailer = $this->mailer);
|
||||
} catch (Exception $e) {
|
||||
expect($e->getMessage())->equals('Sender name and email are not configured.');
|
||||
}
|
||||
}
|
||||
|
||||
function itCanConstruct() {
|
||||
$mailer = new Mailer($this->mailer, $this->sender, $this->reply_to);
|
||||
expect($mailer->sender['from_name'])->equals($this->sender['name']);
|
||||
expect($mailer->sender['from_email'])->equals($this->sender['address']);
|
||||
expect($mailer->reply_to['reply_to_name'])->equals($this->reply_to['name']);
|
||||
expect($mailer->reply_to['reply_to_email'])->equals($this->reply_to['address']);
|
||||
}
|
||||
|
||||
function itCanBuildMailerInstance() {
|
||||
$mailer = new Mailer($this->mailer, $this->sender);
|
||||
expect(get_class($mailer->mailer_instance))
|
||||
->equals('MailPoet\Mailer\Methods\MailPoet');
|
||||
}
|
||||
|
||||
function itCanAbortWhenMethodDoesNotExist() {
|
||||
try {
|
||||
$mailer = new Mailer(array('method' => 'test'), $this->sender);
|
||||
} catch (Exception $e) {
|
||||
expect($e->getMessage())->equals('Mailing method does not exist.');
|
||||
}
|
||||
}
|
||||
|
||||
function itCanTransformSubscriber() {
|
||||
$mailer = new Mailer($this->mailer, $this->sender, $this->reply_to);
|
||||
expect($mailer->transformSubscriber('test@email.com'))
|
||||
->equals('test@email.com');
|
||||
expect($mailer->transformSubscriber(
|
||||
array(
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('test@email.com');
|
||||
expect($mailer->transformSubscriber(
|
||||
array(
|
||||
'first_name' => 'First',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('First <test@email.com>');
|
||||
expect($mailer->transformSubscriber(
|
||||
array(
|
||||
'last_name' => 'Last',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('Last <test@email.com>');
|
||||
expect($mailer->transformSubscriber(
|
||||
array(
|
||||
'first_name' => 'First',
|
||||
'last_name' => 'Last',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('First Last <test@email.com>');
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$mailer = new Mailer($this->mailer, $this->sender, $this->reply_to);
|
||||
expect($mailer->send($this->newsletter, $this->subscriber))->true();
|
||||
}
|
||||
}
|
@ -1,155 +1,155 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\API\AmazonSES;
|
||||
|
||||
class AmazonSESCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'AmazonSES',
|
||||
'type' => 'API',
|
||||
'access_key' => 'AKIAJM6Y5HMGXBLDNSRA',
|
||||
'secret_key' => 'P3EbTbVx7U0LXKQ9nTm2eIrP+9aPiLyvaRDsFxXh',
|
||||
'region' => 'us-east-1',
|
||||
);
|
||||
$this->from = 'Sender <vlad@mailpoet.com>';
|
||||
$this->mailer = new AmazonSES(
|
||||
$this->settings['region'],
|
||||
$this->settings['access_key'],
|
||||
$this->settings['secret_key'],
|
||||
$this->from);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing AmazonSES',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itsConstructorWorks() {
|
||||
expect($this->mailer->awsEndpoint)
|
||||
->equals(
|
||||
sprintf('email.%s.amazonaws.com', $this->settings['region'])
|
||||
);
|
||||
expect($this->mailer->url) ->equals(
|
||||
sprintf('https://email.%s.amazonaws.com', $this->settings['region'])
|
||||
);
|
||||
expect(preg_match('!^\d{8}T\d{6}Z$!', $this->mailer->date))->equals(1);
|
||||
expect(preg_match('!^\d{8}$!', $this->mailer->dateWithoutTime))->equals(1);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['Action'])->equals('SendEmail');
|
||||
expect($body['Version'])->equals('2010-12-01');
|
||||
expect($body['Source'])->equals($this->from);
|
||||
expect($body['Destination.ToAddresses.member.1'])
|
||||
->contains($this->subscriber);
|
||||
expect($body['Message.Subject.Data'])
|
||||
->equals($this->newsletter['subject']);
|
||||
expect($body['Message.Body.Html.Data'])
|
||||
->equals($this->newsletter['body']['html']);
|
||||
expect($body['Message.Body.Text.Data'])
|
||||
->equals($this->newsletter['body']['text']);
|
||||
expect($body['ReturnPath'])->equals($this->from);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.1');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Host'])->equals($this->mailer->awsEndpoint);
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals($this->mailer->signRequest($body));
|
||||
expect($request['headers']['X-Amz-Date'])->equals($this->mailer->date);
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCanCreateCanonicalRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$canonicalRequest = explode(
|
||||
"\n",
|
||||
$this->mailer->getCanonicalRequest($body)
|
||||
);
|
||||
expect($canonicalRequest)
|
||||
->equals(
|
||||
array(
|
||||
'POST',
|
||||
'/',
|
||||
'',
|
||||
'host:' . $this->mailer->awsEndpoint,
|
||||
'x-amz-date:' . $this->mailer->date,
|
||||
'',
|
||||
'host;x-amz-date',
|
||||
hash($this->mailer->hashAlgorithm,
|
||||
urldecode(http_build_query($body))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanCreateCredentialScope() {
|
||||
$credentialScope = $this->mailer->getCredentialScope();
|
||||
expect($credentialScope)
|
||||
->equals(
|
||||
$this->mailer->dateWithoutTime . '/' .
|
||||
$this->mailer->awsRegion . '/' .
|
||||
$this->mailer->awsService . '/' .
|
||||
$this->mailer->awsTerminationString
|
||||
);
|
||||
}
|
||||
|
||||
function itCanCreateStringToSign() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$credentialScope = $this->mailer->getCredentialScope();
|
||||
$canonicalRequest = $this->mailer->getCanonicalRequest($body);
|
||||
$stringToSing = $this->mailer->createStringToSign(
|
||||
$credentialScope,
|
||||
$canonicalRequest
|
||||
);
|
||||
$stringToSing = explode("\n", $stringToSing);
|
||||
expect($stringToSing)
|
||||
->equals(
|
||||
array(
|
||||
$this->mailer->awsSigningAlgorithm,
|
||||
$this->mailer->date,
|
||||
$credentialScope,
|
||||
hash($this->mailer->hashAlgorithm, $canonicalRequest)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanSignRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$signedRequest = $this->mailer->signRequest($body);
|
||||
expect($signedRequest)
|
||||
->contains(
|
||||
$this->mailer->awsSigningAlgorithm . ' Credential=' .
|
||||
$this->mailer->awsAccessKey . '/' .
|
||||
$this->mailer->getCredentialScope() . ', ' .
|
||||
'SignedHeaders=host;x-amz-date, Signature='
|
||||
);
|
||||
expect(preg_match('!Signature=[A-Fa-f0-9]{64}$!', $signedRequest))
|
||||
->equals(1);
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAccessKey() {
|
||||
$this->mailer->awsAccessKey = 'somekey';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\AmazonSES;
|
||||
|
||||
class AmazonSESCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'AmazonSES',
|
||||
'access_key' => 'AKIAJM6Y5HMGXBLDNSRA',
|
||||
'secret_key' => 'P3EbTbVx7U0LXKQ9nTm2eIrP+9aPiLyvaRDsFxXh',
|
||||
'region' => 'us-east-1',
|
||||
);
|
||||
$this->from = 'Sender <vlad@mailpoet.com>';
|
||||
$this->mailer = new AmazonSES(
|
||||
$this->settings['region'],
|
||||
$this->settings['access_key'],
|
||||
$this->settings['secret_key'],
|
||||
$this->from);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing AmazonSES',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itsConstructorWorks() {
|
||||
expect($this->mailer->aws_endpoint)
|
||||
->equals(
|
||||
sprintf('email.%s.amazonaws.com', $this->settings['region'])
|
||||
);
|
||||
expect($this->mailer->url)
|
||||
->equals(
|
||||
sprintf('https://email.%s.amazonaws.com', $this->settings['region'])
|
||||
);
|
||||
expect(preg_match('!^\d{8}T\d{6}Z$!', $this->mailer->date))->equals(1);
|
||||
expect(preg_match('!^\d{8}$!', $this->mailer->date_without_time))->equals(1);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['Action'])->equals('SendEmail');
|
||||
expect($body['Version'])->equals('2010-12-01');
|
||||
expect($body['Source'])->equals($this->from);
|
||||
expect($body['Destination.ToAddresses.member.1'])
|
||||
->contains($this->subscriber);
|
||||
expect($body['Message.Subject.Data'])
|
||||
->equals($this->newsletter['subject']);
|
||||
expect($body['Message.Body.Html.Data'])
|
||||
->equals($this->newsletter['body']['html']);
|
||||
expect($body['Message.Body.Text.Data'])
|
||||
->equals($this->newsletter['body']['text']);
|
||||
expect($body['ReturnPath'])->equals($this->from);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.1');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Host'])->equals($this->mailer->aws_endpoint);
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals($this->mailer->signRequest($body));
|
||||
expect($request['headers']['X-Amz-Date'])->equals($this->mailer->date);
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCanCreateCanonicalRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$canonicalRequest = explode(
|
||||
"\n",
|
||||
$this->mailer->getCanonicalRequest($body)
|
||||
);
|
||||
expect($canonicalRequest)
|
||||
->equals(
|
||||
array(
|
||||
'POST',
|
||||
'/',
|
||||
'',
|
||||
'host:' . $this->mailer->aws_endpoint,
|
||||
'x-amz-date:' . $this->mailer->date,
|
||||
'',
|
||||
'host;x-amz-date',
|
||||
hash($this->mailer->hash_algorithm,
|
||||
urldecode(http_build_query($body))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanCreateCredentialScope() {
|
||||
$credentialScope = $this->mailer->getCredentialScope();
|
||||
expect($credentialScope)
|
||||
->equals(
|
||||
$this->mailer->date_without_time . '/' .
|
||||
$this->mailer->aws_region . '/' .
|
||||
$this->mailer->aws_service . '/' .
|
||||
$this->mailer->aws_termination_string
|
||||
);
|
||||
}
|
||||
|
||||
function itCanCreateStringToSign() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$credentialScope = $this->mailer->getCredentialScope();
|
||||
$canonicalRequest = $this->mailer->getCanonicalRequest($body);
|
||||
$stringToSing = $this->mailer->createStringToSign(
|
||||
$credentialScope,
|
||||
$canonicalRequest
|
||||
);
|
||||
$stringToSing = explode("\n", $stringToSing);
|
||||
expect($stringToSing)
|
||||
->equals(
|
||||
array(
|
||||
$this->mailer->aws_signing_algorithm,
|
||||
$this->mailer->date,
|
||||
$credentialScope,
|
||||
hash($this->mailer->hash_algorithm, $canonicalRequest)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanSignRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$signedRequest = $this->mailer->signRequest($body);
|
||||
expect($signedRequest)
|
||||
->contains(
|
||||
$this->mailer->aws_signing_algorithm . ' Credential=' .
|
||||
$this->mailer->aws_access_key . '/' .
|
||||
$this->mailer->getCredentialScope() . ', ' .
|
||||
'SignedHeaders=host;x-amz-date, Signature='
|
||||
);
|
||||
expect(preg_match('!Signature=[A-Fa-f0-9]{64}$!', $signedRequest))
|
||||
->equals(1);
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAccessKey() {
|
||||
$this->mailer->aws_access_key = 'somekey';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,65 +1,64 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\API\ElasticEmail;
|
||||
|
||||
class ElasticEmailCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'ElasticEmail',
|
||||
'type' => 'API',
|
||||
'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new ElasticEmail(
|
||||
$this->settings['api_key'],
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing ElasticEmail',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['api_key'])->equals($this->settings['api_key']);
|
||||
expect($body['from'])->equals($this->fromEmail);
|
||||
expect($body['from_name'])->equals($this->fromName);
|
||||
expect($body['to'])->contains($this->subscriber);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['body_html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['body_text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAPIKey() {
|
||||
$this->mailer->apiKey = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\ElasticEmail;
|
||||
|
||||
class ElasticEmailCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'ElasticEmail',
|
||||
'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new ElasticEmail(
|
||||
$this->settings['api_key'],
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing ElasticEmail',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['api_key'])->equals($this->settings['api_key']);
|
||||
expect($body['from'])->equals($this->from_email);
|
||||
expect($body['from_name'])->equals($this->from_name);
|
||||
expect($body['to'])->contains($this->subscriber);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['body_html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['body_text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperApiKey() {
|
||||
$this->mailer->api_key = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,82 +1,81 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\API\MailGun;
|
||||
|
||||
class MailGunCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'MailGun',
|
||||
'type' => 'API',
|
||||
'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2',
|
||||
'domain' => 'mrcasual.com'
|
||||
);
|
||||
$this->from = 'Sender <staff@mailpoet.com>';
|
||||
$this->mailer = new MailGun(
|
||||
$this->settings['domain'],
|
||||
$this->settings['api_key'],
|
||||
$this->from
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing MailGun',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['from'])->equals($this->from);
|
||||
expect($body['to'])->equals($this->subscriber);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])
|
||||
->equals('application/x-www-form-urlencoded');
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAPIKey() {
|
||||
$this->mailer->apiKey = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperDomain() {
|
||||
$this->mailer->url =
|
||||
str_replace($this->settings['domain'], 'somedomain', $this->mailer->url);
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\MailGun;
|
||||
|
||||
class MailGunCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'MailGun',
|
||||
'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2',
|
||||
'domain' => 'mrcasual.com'
|
||||
);
|
||||
$this->from = 'Sender <staff@mailpoet.com>';
|
||||
$this->mailer = new MailGun(
|
||||
$this->settings['domain'],
|
||||
$this->settings['api_key'],
|
||||
$this->from
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing MailGun',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['from'])->equals($this->from);
|
||||
expect($body['to'])->equals($this->subscriber);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])
|
||||
->equals('application/x-www-form-urlencoded');
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperApiKey() {
|
||||
$this->mailer->api_key = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperDomain() {
|
||||
$this->mailer->url =
|
||||
str_replace($this->settings['domain'], 'somedomain', $this->mailer->url);
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,95 +1,95 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\MailPoet;
|
||||
|
||||
class MailPoetCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'MailPoet',
|
||||
'api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new MailPoet(
|
||||
$this->settings['api_key'],
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing MailPoet',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
expect($body['to']['address'])->equals($subscriber['email']);
|
||||
expect($body['to']['name'])->equals($subscriber['name']);
|
||||
expect($body['from']['address'])->equals($this->fromEmail);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$subscriber = $this->mailer->processSubscriber(
|
||||
'Recipient <mailpoet-phoenix-test@mailinator.com>'
|
||||
);
|
||||
$body = array($this->mailer->getBody($this->newsletter, $subscriber));
|
||||
$request = $this->mailer->request($this->newsletter, $subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])->equals('application/json');
|
||||
expect($request['headers']['Authorization'])->equals($this->mailer->auth());
|
||||
expect($request['body'])->equals($body);
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => ''
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First'
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First Last'
|
||||
));
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAPIKey() {
|
||||
$this->mailer->apiKey = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\MailPoet;
|
||||
|
||||
class MailPoetCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'MailPoet',
|
||||
'api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new MailPoet(
|
||||
$this->settings['api_key'],
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing MailPoet',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
expect($body['to']['address'])->equals($subscriber['email']);
|
||||
expect($body['to']['name'])->equals($subscriber['name']);
|
||||
expect($body['from']['address'])->equals($this->from_email);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$subscriber = $this->mailer->processSubscriber(
|
||||
'Recipient <mailpoet-phoenix-test@mailinator.com>'
|
||||
);
|
||||
$body = array($this->mailer->getBody($this->newsletter, $subscriber));
|
||||
$request = $this->mailer->request($this->newsletter, $subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])->equals('application/json');
|
||||
expect($request['headers']['Authorization'])->equals($this->mailer->auth());
|
||||
expect($request['body'])->equals($body);
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => ''
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First'
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First Last'
|
||||
));
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperApiKey() {
|
||||
$this->mailer->api_key = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,90 +1,89 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\API\Mandrill;
|
||||
|
||||
class MandrillCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'Mandrill',
|
||||
'type' => 'API',
|
||||
'api_key' => '692ys1B7REEoZN7R-dYwNA'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new Mandrill(
|
||||
$this->settings['api_key'],
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing Mandrill',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
expect($body['key'])->equals($this->settings['api_key']);
|
||||
expect($body['message']['from_email'])->equals($this->fromEmail);
|
||||
expect($body['message']['from_name'])->equals($this->fromName);
|
||||
expect($body['message']['to'])->equals(array($subscriber));
|
||||
expect($body['message']['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['message']['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['message']['text'])->equals($this->newsletter['body']['text']);
|
||||
expect($body['async'])->false();
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
$request = $this->mailer->request($this->newsletter, $subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])->equals('application/json');
|
||||
expect($request['body'])->equals(json_encode($body));
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => ''
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First'
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First Last'
|
||||
));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAPIKey() {
|
||||
$this->mailer->apiKey = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\Mandrill;
|
||||
|
||||
class MandrillCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'Mandrill',
|
||||
'api_key' => '692ys1B7REEoZN7R-dYwNA'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new Mandrill(
|
||||
$this->settings['api_key'],
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing Mandrill',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
expect($body['key'])->equals($this->settings['api_key']);
|
||||
expect($body['message']['from_email'])->equals($this->from_email);
|
||||
expect($body['message']['from_name'])->equals($this->from_name);
|
||||
expect($body['message']['to'])->equals(array($subscriber));
|
||||
expect($body['message']['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['message']['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['message']['text'])->equals($this->newsletter['body']['text']);
|
||||
expect($body['async'])->false();
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$subscriber = $this->mailer->processSubscriber($this->subscriber);
|
||||
$body = $this->mailer->getBody($this->newsletter, $subscriber);
|
||||
$request = $this->mailer->request($this->newsletter, $subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.0');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Content-Type'])->equals('application/json');
|
||||
expect($request['body'])->equals(json_encode($body));
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => ''
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First'
|
||||
));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(
|
||||
array(
|
||||
'email' => 'test@test.com',
|
||||
'name' => 'First Last'
|
||||
));
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperApiKey() {
|
||||
$this->mailer->api_key = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,92 +1,92 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\SMTP;
|
||||
|
||||
class SMTPCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'SMTP',
|
||||
'host' => 'email-smtp.us-west-2.amazonaws.com',
|
||||
'port' => 587,
|
||||
'login' => 'AKIAIGPBLH6JWG5VCBQQ',
|
||||
'password' => 'AudVHXHaYkvr54veCzqiqOxDiMMyfQW3/V6F1tYzGXY3',
|
||||
'authentication' => '1',
|
||||
'encryption' => 'tls'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new SMTP(
|
||||
$this->settings['host'],
|
||||
$this->settings['port'],
|
||||
$this->settings['authentication'],
|
||||
$this->settings['login'],
|
||||
$this->settings['password'],
|
||||
$this->settings['encryption'],
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SMTP',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanBuildMailer() {
|
||||
$mailer = $this->mailer->buildMailer();
|
||||
expect($mailer->getTransport()->getHost())
|
||||
->equals($this->settings['host']);
|
||||
expect($mailer->getTransport()->getPort())
|
||||
->equals($this->settings['port']);
|
||||
expect($mailer->getTransport()->getUsername())
|
||||
->equals($this->settings['login']);
|
||||
expect($mailer->getTransport()->getPassword())
|
||||
->equals($this->settings['password']);
|
||||
expect($mailer->getTransport()->getEncryption())
|
||||
->equals($this->settings['encryption']);
|
||||
}
|
||||
|
||||
function itCanCreateMessage() {
|
||||
$message = $this->mailer->createMessage($this->newsletter, $this->subscriber);
|
||||
expect($message->getTo())
|
||||
->equals(array('mailpoet-phoenix-test@mailinator.com' => 'Recipient'));
|
||||
expect($message->getFrom())
|
||||
->equals(array($this->fromEmail => $this->fromName));
|
||||
expect($message->getSubject())
|
||||
->equals($this->newsletter['subject']);
|
||||
expect($message->getBody())
|
||||
->equals($this->newsletter['body']['html']);
|
||||
expect($message->getChildren()[0]->getContentType())
|
||||
->equals('text/plain');
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(array('test@test.com' => ''));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(array('test@test.com' => 'First'));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(array('test@test.com' => 'First Last'));
|
||||
}
|
||||
|
||||
function itCantSentWithoutProperAuthentication() {
|
||||
$this->mailer->login = 'someone';
|
||||
$this->mailer->mailer = $this->mailer->buildMailer();
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\SMTP;
|
||||
|
||||
class SMTPCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'SMTP',
|
||||
'host' => 'email-smtp.us-west-2.amazonaws.com',
|
||||
'port' => 587,
|
||||
'login' => 'AKIAIGPBLH6JWG5VCBQQ',
|
||||
'password' => 'AudVHXHaYkvr54veCzqiqOxDiMMyfQW3/V6F1tYzGXY3',
|
||||
'authentication' => '1',
|
||||
'encryption' => 'tls'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new SMTP(
|
||||
$this->settings['host'],
|
||||
$this->settings['port'],
|
||||
$this->settings['authentication'],
|
||||
$this->settings['login'],
|
||||
$this->settings['password'],
|
||||
$this->settings['encryption'],
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SMTP',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanBuildMailer() {
|
||||
$mailer = $this->mailer->buildMailer();
|
||||
expect($mailer->getTransport()->getHost())
|
||||
->equals($this->settings['host']);
|
||||
expect($mailer->getTransport()->getPort())
|
||||
->equals($this->settings['port']);
|
||||
expect($mailer->getTransport()->getUsername())
|
||||
->equals($this->settings['login']);
|
||||
expect($mailer->getTransport()->getPassword())
|
||||
->equals($this->settings['password']);
|
||||
expect($mailer->getTransport()->getEncryption())
|
||||
->equals($this->settings['encryption']);
|
||||
}
|
||||
|
||||
function itCanCreateMessage() {
|
||||
$message = $this->mailer->createMessage($this->newsletter, $this->subscriber);
|
||||
expect($message->getTo())
|
||||
->equals(array('mailpoet-phoenix-test@mailinator.com' => 'Recipient'));
|
||||
expect($message->getFrom())
|
||||
->equals(array($this->from_email => $this->from_name));
|
||||
expect($message->getSubject())
|
||||
->equals($this->newsletter['subject']);
|
||||
expect($message->getBody())
|
||||
->equals($this->newsletter['body']['html']);
|
||||
expect($message->getChildren()[0]->getContentType())
|
||||
->equals('text/plain');
|
||||
}
|
||||
|
||||
function itCanProcessSubscriber() {
|
||||
expect($this->mailer->processSubscriber('test@test.com'))
|
||||
->equals(array('test@test.com' => ''));
|
||||
expect($this->mailer->processSubscriber('First <test@test.com>'))
|
||||
->equals(array('test@test.com' => 'First'));
|
||||
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
|
||||
->equals(array('test@test.com' => 'First Last'));
|
||||
}
|
||||
|
||||
function itCantSentWithoutProperAuthentication() {
|
||||
$this->mailer->login = 'someone';
|
||||
$this->mailer->mailer = $this->mailer->buildMailer();
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,71 +1,70 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\API\SendGrid;
|
||||
|
||||
class SendGridCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'SendGrid',
|
||||
'type' => 'API',
|
||||
'api_key' => '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'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new SendGrid(
|
||||
$this->settings['api_key'],
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SendGrid',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['to'])->contains($this->subscriber);
|
||||
expect($body['from'])->equals($this->fromEmail);
|
||||
expect($body['fromname'])->equals($this->fromName);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.1');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals('Bearer ' . $this->settings['api_key']);
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Bearer ' . $this->settings['api_key']);
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperAPIKey() {
|
||||
$this->mailer->apiKey = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\SendGrid;
|
||||
|
||||
class SendGridCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'SendGrid',
|
||||
'api_key' => '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'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new SendGrid(
|
||||
$this->settings['api_key'],
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SendGrid',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanGenerateBody() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
expect($body['to'])->contains($this->subscriber);
|
||||
expect($body['from'])->equals($this->from_email);
|
||||
expect($body['from_name'])->equals($this->from_name);
|
||||
expect($body['subject'])->equals($this->newsletter['subject']);
|
||||
expect($body['html'])->equals($this->newsletter['body']['html']);
|
||||
expect($body['text'])->equals($this->newsletter['body']['text']);
|
||||
}
|
||||
|
||||
function itCanCreateRequest() {
|
||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
expect($request['timeout'])->equals(10);
|
||||
expect($request['httpversion'])->equals('1.1');
|
||||
expect($request['method'])->equals('POST');
|
||||
expect($request['headers']['Authorization'])
|
||||
->equals('Bearer ' . $this->settings['api_key']);
|
||||
expect($request['body'])->equals(urldecode(http_build_query($body)));
|
||||
}
|
||||
|
||||
function itCanDoBasicAuth() {
|
||||
expect($this->mailer->auth())
|
||||
->equals('Bearer ' . $this->settings['api_key']);
|
||||
}
|
||||
|
||||
function itCannotSendWithoutProperApiKey() {
|
||||
$this->mailer->api_key = 'someapi';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
expect($result)->true();
|
||||
}
|
||||
}
|
@ -1,70 +1,70 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\WPMail;
|
||||
|
||||
class WPMailCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'WPMail'
|
||||
);
|
||||
$this->fromEmail = 'staff@mailpoet.com';
|
||||
$this->fromName = 'Sender';
|
||||
$this->mailer = new WPMail(
|
||||
$this->fromEmail,
|
||||
$this->fromName
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SMTP',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanAddFilters() {
|
||||
$this->mailer->addFilters();
|
||||
expect(has_filter('wp_mail_from_name', array(
|
||||
$this->mailer,
|
||||
'setFromName'
|
||||
)))->notEmpty();
|
||||
expect(has_filter('wp_mail_from', array(
|
||||
$this->mailer,
|
||||
'setFromEmail'
|
||||
)))->notEmpty();
|
||||
expect(has_filter('wp_mail_content_type', array(
|
||||
$this->mailer,
|
||||
'setContentType'
|
||||
)))->notEmpty();
|
||||
}
|
||||
|
||||
function itCanRemoveFilters() {
|
||||
$this->mailer->addFilters();
|
||||
$this->mailer->removeFilters();
|
||||
expect(has_filter('wp_mail_from_name'))->false();
|
||||
expect(has_filter('wp_mail_from'))->false();
|
||||
expect(has_filter('wp_mail_content_type'))->false();
|
||||
}
|
||||
|
||||
function itCanSetFromName() {
|
||||
expect($this->mailer->setFromName())->equals($this->fromName);
|
||||
}
|
||||
|
||||
function itCanSetFromEmail() {
|
||||
expect($this->mailer->setFromName())->equals($this->fromName);
|
||||
}
|
||||
|
||||
function itCanSetContentType() {
|
||||
expect($this->mailer->setContentType())->equals('text/html');
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$_SERVER['SERVER_NAME'] = 'localhost';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
//expect($result)->true();
|
||||
}
|
||||
<?php
|
||||
|
||||
use MailPoet\Mailer\Methods\WPMail;
|
||||
|
||||
class WPMailCest {
|
||||
function _before() {
|
||||
$this->settings = array(
|
||||
'method' => 'WPMail'
|
||||
);
|
||||
$this->from_email = 'staff@mailpoet.com';
|
||||
$this->from_name = 'Sender';
|
||||
$this->mailer = new WPMail(
|
||||
$this->from_email,
|
||||
$this->from_name
|
||||
);
|
||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||
$this->newsletter = array(
|
||||
'subject' => 'testing SMTP',
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function itCanAddFilters() {
|
||||
$this->mailer->addFilters();
|
||||
expect(has_filter('wp_mail_from_name', array(
|
||||
$this->mailer,
|
||||
'setFromName'
|
||||
)))->notEmpty();
|
||||
expect(has_filter('wp_mail_from', array(
|
||||
$this->mailer,
|
||||
'setFromEmail'
|
||||
)))->notEmpty();
|
||||
expect(has_filter('wp_mail_content_type', array(
|
||||
$this->mailer,
|
||||
'setContentType'
|
||||
)))->notEmpty();
|
||||
}
|
||||
|
||||
function itCanRemoveFilters() {
|
||||
$this->mailer->addFilters();
|
||||
$this->mailer->removeFilters();
|
||||
expect(has_filter('wp_mail_from_name'))->false();
|
||||
expect(has_filter('wp_mail_from'))->false();
|
||||
expect(has_filter('wp_mail_content_type'))->false();
|
||||
}
|
||||
|
||||
function itCanSetFromName() {
|
||||
expect($this->mailer->setFromName())->equals($this->from_name);
|
||||
}
|
||||
|
||||
function itCanSetFromEmail() {
|
||||
expect($this->mailer->setFromEmail())->equals($this->from_email);
|
||||
}
|
||||
|
||||
function itCanSetContentType() {
|
||||
expect($this->mailer->setContentType())->equals('text/html');
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
$_SERVER['SERVER_NAME'] = 'localhost';
|
||||
$result = $this->mailer->send(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
);
|
||||
//expect($result)->true();
|
||||
}
|
||||
}
|
@ -13,118 +13,260 @@ use MailPoet\Newsletter\Renderer\Renderer;
|
||||
|
||||
class NewsletterRendererCest {
|
||||
function __construct() {
|
||||
$this->newsletterData = json_decode(file_get_contents(dirname(__FILE__) . '/RendererTestData.json'), true);
|
||||
$this->renderer = new Renderer($this->newsletterData);
|
||||
$this->columnRenderer = new ColumnRenderer();
|
||||
$this->queryDOM = new \pQuery();
|
||||
$this->newsletter = array(
|
||||
'body' => file_get_contents(dirname(__FILE__) . '/RendererTestData.json'),
|
||||
'subject' => 'Some subject',
|
||||
'preheader' => 'Some preheader'
|
||||
);
|
||||
$this->renderer = new Renderer($this->newsletter);
|
||||
$this->column_renderer = new ColumnRenderer();
|
||||
$this->DOM_parser = new \pQuery();
|
||||
}
|
||||
|
||||
function itRendersCompleteNewsletter() {
|
||||
$template = $this->renderer->renderAll();
|
||||
$DOM = $this->queryDOM->parseStr($template);
|
||||
|
||||
// we expect to have 4 column containers and 7 columns (1x1, 1x2, 1x3, 1x1)
|
||||
expect(count($DOM('.mailpoet_cols-wrapper')))->equals(4);
|
||||
expect(count($DOM('.mailpoet_force-row')))->equals(7);
|
||||
$template = $this->renderer->render();
|
||||
$DOM = $this->DOM_parser->parseStr($template);
|
||||
// we expect to have 7 columns:
|
||||
// 1x column including header
|
||||
// 2x column
|
||||
// 3x column
|
||||
// 1x footer
|
||||
expect(count($DOM('.mailpoet_cols-one')))->equals(2);
|
||||
expect(count($DOM('.mailpoet_cols-two')))->equals(2);
|
||||
expect(count($DOM('.mailpoet_cols-three')))->equals(3);
|
||||
}
|
||||
|
||||
function itRendersColumns() {
|
||||
$columnContent = array(
|
||||
function itRendersOneColumn() {
|
||||
$column_content = array(
|
||||
'one'
|
||||
);
|
||||
$column_styles = array(
|
||||
'block' => array(
|
||||
'backgroundColor' => "#999999"
|
||||
)
|
||||
);
|
||||
$DOM = $this->DOM_parser->parseStr(
|
||||
$this->column_renderer->render(
|
||||
$column_styles,
|
||||
count($column_content),
|
||||
$column_content)
|
||||
);
|
||||
foreach($DOM('table.mailpoet_cols-one > tbody') as $column) {
|
||||
$rendered_column_content[] = trim($column->text());
|
||||
};
|
||||
expect($rendered_column_content)->equals($column_content);
|
||||
}
|
||||
|
||||
function itRendersTwoColumns() {
|
||||
$column_content = array(
|
||||
'one',
|
||||
'two'
|
||||
);
|
||||
$column_styles = array(
|
||||
'block' => array(
|
||||
'backgroundColor' => "#999999"
|
||||
)
|
||||
);
|
||||
$DOM = $this->DOM_parser->parseStr(
|
||||
$this->column_renderer->render(
|
||||
$column_styles,
|
||||
count($column_content),
|
||||
$column_content)
|
||||
);
|
||||
foreach($DOM('table.mailpoet_cols-two > tbody') as $column) {
|
||||
$rendered_column_content[] = trim($column->text());
|
||||
};
|
||||
expect($rendered_column_content)->equals($column_content);
|
||||
}
|
||||
|
||||
function itRendersThreeColumns() {
|
||||
$column_content = array(
|
||||
'one',
|
||||
'two',
|
||||
'three'
|
||||
);
|
||||
$DOM = $this->queryDOM->parseStr($this->columnRenderer->render(count($columnContent), $columnContent));
|
||||
|
||||
// rendered object should cocntain three columns
|
||||
foreach ($DOM('.mailpoet_force-row > tbody') as $column) {
|
||||
$renderedColumnContent[] = trim($column->text());
|
||||
$column_styles = array(
|
||||
'block' => array(
|
||||
'backgroundColor' => "#999999"
|
||||
)
|
||||
);
|
||||
$DOM = $this->DOM_parser->parseStr(
|
||||
$this->column_renderer->render(
|
||||
$column_styles,
|
||||
count($column_content),
|
||||
$column_content)
|
||||
);
|
||||
foreach($DOM('table.mailpoet_cols-three > tbody') as $column) {
|
||||
$rendered_column_content[] = trim($column->text());
|
||||
};
|
||||
expect(count(array_diff($renderedColumnContent, $columnContent)))->equals(0);
|
||||
expect($rendered_column_content)->equals($column_content);
|
||||
}
|
||||
|
||||
function itRendersHeader() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][0];
|
||||
$DOM = $this->queryDOM->parseStr(Header::render($template));
|
||||
|
||||
// element should be proplerly nested, and styles should be applied to <td>, <a> and <p> elements
|
||||
expect(is_object($DOM('tr > td > p', 0)))->true();
|
||||
expect(is_object($DOM('tr > td > p > a', 0)))->true();
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][0];
|
||||
$DOM = $this->DOM_parser->parseStr(Header::render($template));
|
||||
// element should be proplerly nested, and styles should be applied
|
||||
expect(!empty($DOM('tr > td.mailpoet_header', 0)->html()))->true();
|
||||
expect(!empty($DOM('tr > td > a', 0)->html()))->true();
|
||||
expect($DOM('a', 0)->attr('style'))->notEmpty();
|
||||
expect($DOM('p', 0)->attr('style'))->notEmpty();
|
||||
expect($DOM('td', 0)->attr('style'))->notEmpty();
|
||||
}
|
||||
|
||||
function itRendersImage() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][1];
|
||||
$DOM = $this->queryDOM->parseStr(Image::render($template));
|
||||
|
||||
// element should be properly nested, it's width set and style applied to <td>
|
||||
expect(is_object($DOM('tr > td > img', 0)))->true();
|
||||
expect($DOM('tr > td > img', 0)->attr('width'))->equals(560);
|
||||
expect($DOM('tr > td', 0)->attr('style'))->notEmpty();
|
||||
function itRendersImage() {
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][1];
|
||||
$DOM = $this->DOM_parser->parseStr(Image::render($template, $columnCount = 1));
|
||||
// element should be properly nested, it's width set and style applied
|
||||
expect($DOM('tr > td > img', 0)->attr('width'))->equals(620);
|
||||
expect($DOM('tr > td > img', 0)->attr('style'))->notEmpty();
|
||||
}
|
||||
|
||||
function itAdjustImageSizeBasedOnColumnWidth() {
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][1];
|
||||
$template['width'] = '800px';
|
||||
$DOM = $this->DOM_parser->parseStr(Image::render($template, $columnCount = 2));
|
||||
// 800px resized to 330px (2-column layout) and 40px padding applied
|
||||
expect($DOM('tr > td > img', 0)->attr('width'))->equals(290);
|
||||
$template['width'] = '280px';
|
||||
$DOM = $this->DOM_parser->parseStr(Image::render($template, $columnCount = 2));
|
||||
// 280px image should not be resized and padding should not be applied
|
||||
expect($DOM('tr > td > img', 0)->attr('width'))->equals(280);
|
||||
}
|
||||
|
||||
function itRendersText() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][2];
|
||||
$DOM = $this->queryDOM->parseStr(Text::render($template));
|
||||
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][2];
|
||||
$DOM = $this->DOM_parser->parseStr(Text::render($template));
|
||||
// blockquotes and paragraphs should be converted to spans and placed inside a table
|
||||
expect(is_object($DOM('tr > td.mailpoet_text > table > tr > td > span.paragraph', 0)))->true();
|
||||
expect(is_object($DOM('tr > td.mailpoet_text > table.mailpoet_blockquote > tbody > tr > td > table > tr > td > span.paragraph', 0)))->true();
|
||||
expect(
|
||||
!empty($DOM('tr > td > table > tr > td.mailpoet_paragraph', 0)->html())
|
||||
)->true();
|
||||
expect(
|
||||
!empty($DOM('tr > td > table > tr > td.mailpoet_blockquote', 0)->html()
|
||||
))->true();
|
||||
// ul/ol/li should have mailpoet_paragraph class added & styles applied
|
||||
expect(
|
||||
!empty(
|
||||
$DOM('tr > td > ul.mailpoet_paragraph > li.mailpoet_paragraph', 0)->html()
|
||||
)
|
||||
)->true();
|
||||
expect(
|
||||
!empty(
|
||||
$DOM('tr > td > ol.mailpoet_paragraph > li.mailpoet_paragraph', 0)->html()
|
||||
)
|
||||
)->true();
|
||||
expect($DOM('tr > td.mailpoet_text > ul.mailpoet_paragraph', 0)->attr('style'))
|
||||
->contains('padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;');
|
||||
// headings should be styled
|
||||
expect($DOM('tr > td.mailpoet_text > h1', 0)->attr('style'))
|
||||
->contains('margin:0;font-style:normal;font-weight:normal;');
|
||||
|
||||
}
|
||||
|
||||
function itRendersDivider() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][3];
|
||||
$DOM = $this->queryDOM->parseStr(Divider::render($template));
|
||||
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][3];
|
||||
$DOM = $this->DOM_parser->parseStr(Divider::render($template));
|
||||
// element should be properly nested and its border-top-width set
|
||||
expect(is_object($DOM('tr > td.mailpoet_divider > table > tr > td', 0)))->true();
|
||||
expect(preg_match('/border-top-width: 3px/', $DOM('tr > td.mailpoet_divider > table > tr > td', 0)->attr('style')))->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'/border-top-width: 3px/',
|
||||
$DOM('tr > td.mailpoet_divider > table > tr > td.mailpoet_divider-cell', 0)->attr('style')
|
||||
))->equals(1);
|
||||
}
|
||||
|
||||
function itRendersSpacer() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][4];
|
||||
$DOM = $this->queryDOM->parseStr(Spacer::render($template));
|
||||
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][4];
|
||||
$DOM = $this->DOM_parser->parseStr(Spacer::render($template));
|
||||
// element should be properly nested and its height set
|
||||
expect(is_object($DOM('tr > td.mailpoet_spacer', 0)))->true();
|
||||
expect(preg_match('/height: 50px/', $DOM('tr > td.mailpoet_spacer', 0)->attr('style')))->equals(1);
|
||||
expect($DOM('tr > td.mailpoet_spacer', 0)->attr('height'))->equals(50);
|
||||
}
|
||||
|
||||
function itRendersButton() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][5];
|
||||
$DOM = $this->queryDOM->parseStr(Button::render($template));
|
||||
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][5];
|
||||
$DOM = $this->DOM_parser->parseStr(Button::render($template));
|
||||
// element should be properly nested with arcsize/styles/fillcolor set
|
||||
expect(is_object($DOM('tr > td.mailpoet_button > div > table > tr > td > a.mailpoet_button', 0)))->true();
|
||||
expect(preg_match('/line-height: 30px/', $DOM('a.mailpoet_button', 0)->attr('style')))->equals(1);
|
||||
expect(preg_match('/arcsize="' . round(20 / 30 * 100) . '%"/', $DOM('tr > td.mailpoet_button > div > table > tr > td', 0)->text()))->equals(1);
|
||||
expect(preg_match('/style="height:30px.*?width:100px/', $DOM('tr > td.mailpoet_button > div > table > tr > td', 0)->text()))->equals(1);
|
||||
expect(preg_match('/style="color:#ffffff.*?font-family:Arial.*?font-size:13px/', $DOM('tr > td.mailpoet_button > div > table > tr > td', 0)->text()))->equals(1);
|
||||
expect(preg_match('/fillcolor="#666666/', $DOM('tr > td.mailpoet_button > div > table > tr > td', 0)->text()))->equals(1);
|
||||
expect(
|
||||
!empty($DOM('tr > td > div > table > tr > td > a.mailpoet_button', 0)->html())
|
||||
)->true();
|
||||
expect(
|
||||
preg_match(
|
||||
'/line-height: 30px/',
|
||||
$DOM('a.mailpoet_button', 0)->attr('style'))
|
||||
)->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'/arcsize="' . round(20 / 30 * 100) . '%"/',
|
||||
$DOM('tr > td > div > table > tr > td', 0)->text())
|
||||
)->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'/style="height:30px.*?width:100px/',
|
||||
$DOM('tr > td > div > table > tr > td', 0)->text())
|
||||
)->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'/style="color:#ffffff.*?font-family:Arial.*?font-size:14px/',
|
||||
$DOM('tr > td > div > table > tr > td', 0)->text())
|
||||
)->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'/fillcolor="#666666/',
|
||||
$DOM('tr > td > div > table > tr > td', 0)->text())
|
||||
)->equals(1);
|
||||
}
|
||||
|
||||
function itRendersSocialIcons() {
|
||||
$template = $this->newsletterData['content']['blocks'][0]['blocks'][0]['blocks'][6];
|
||||
$DOM = $this->queryDOM->parseStr(Social::render($template));
|
||||
|
||||
// element should be properly nested, contain social icons and image source/link href/alt should be properly set
|
||||
expect(is_object($DOM('tr > td.mailpoet_social > div', 0)))->true();
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][0]['blocks'][0]['blocks'][6];
|
||||
$DOM = $this->DOM_parser->parseStr(Social::render($template));
|
||||
// element should be properly nested, contain social icons and
|
||||
// image source/link href/alt should be properly set
|
||||
expect(!empty($DOM('tr > td', 0)->html()))->true();
|
||||
expect($DOM('a', 0)->attr('href'))->equals('http://example.com');
|
||||
expect($DOM('td > a:nth-of-type(10) > img')->attr('src'))->contains('custom.png');
|
||||
expect($DOM('td > a:nth-of-type(10) > img')->attr('alt'))->equals('custom');
|
||||
// there should be 10 icons
|
||||
expect(count($DOM('a > img')))->equals(10);
|
||||
expect($DOM('a', 0)->attr('href'))->equals('http://example.org');
|
||||
expect($DOM('a > img', 0)->attr('src'))->equals('http://mp3.mailpoet.net/various/social-icons/custom.png');
|
||||
expect($DOM('a > img', 0)->attr('alt'))->equals('custom');
|
||||
}
|
||||
|
||||
function itRendersFooter() {
|
||||
$template = $this->newsletterData['content']['blocks'][3]['blocks'][0]['blocks'][0];
|
||||
$DOM = $this->queryDOM->parseStr(Footer::render($template));
|
||||
|
||||
// element should be proplerly nested, and styles should be applied to <td>, <a> and <p> elements
|
||||
expect(is_object($DOM('tr > td.mailpoet_footer > div', 0)))->true();
|
||||
expect(is_object($DOM('tr > td.mailpoet_footer > div > a > p', 0)))->true();
|
||||
expect($DOM('tr > td.mailpoet_footer', 0)->attr('style'))->notEmpty();
|
||||
$newsletter = json_decode($this->newsletter['body'], true);
|
||||
$template = $newsletter['content']['blocks'][3]['blocks'][0]['blocks'][0];
|
||||
$DOM = $this->DOM_parser->parseStr(Footer::render($template));
|
||||
// element should be properly nested, and styles should be applied
|
||||
expect(!empty($DOM('tr > td.mailpoet_footer', 0)->html()))->true();
|
||||
expect(!empty($DOM('tr > td > a', 0)->html()))->true();
|
||||
expect($DOM('a', 0)->attr('style'))->notEmpty();
|
||||
expect($DOM('p', 0)->attr('style'))->notEmpty();
|
||||
expect($DOM('td', 0)->attr('style'))->notEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
function itSetsSubject() {
|
||||
$template = $this->renderer->render();
|
||||
$DOM = $this->DOM_parser->parseStr($template);
|
||||
$subject = trim($DOM('title')->text());
|
||||
expect($subject)->equals($this->newsletter['subject']);
|
||||
}
|
||||
|
||||
function itSetsPreheader() {
|
||||
$template = $this->renderer->render();
|
||||
$DOM = $this->DOM_parser->parseStr($template);
|
||||
$preheader = trim($DOM('td.mailpoet_preheader')->text());
|
||||
expect($preheader)->equals($this->newsletter['preheader']);
|
||||
}
|
||||
|
||||
function itPostProcessesTemplate() {
|
||||
$template = $this->renderer->render();
|
||||
// !important should be stripped from everywhere except from
|
||||
// with the <style> tag
|
||||
expect(preg_match('/<style.*?important/s', $template))
|
||||
->equals(1);
|
||||
expect(preg_match('/mailpoet_template.*?important/s', $template))
|
||||
->equals(0);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
use MailPoet\Router\Mailer;
|
||||
|
||||
class MailerCest {
|
||||
function __construct() {
|
||||
$this->router = new Mailer();
|
||||
}
|
||||
|
||||
function itCanConstruct() {
|
||||
// TOFIX: "from" property doesn't exist on $this->router
|
||||
// the sender should be explicitely defined in this unit test.
|
||||
//expect($this->router->from)->equals('Sender <staff@mailpoet.com>');
|
||||
}
|
||||
|
||||
function itCanTransformSubscriber() {
|
||||
expect($this->router->transformSubscriber('test@email.com'))
|
||||
->equals('test@email.com');
|
||||
expect($this->router->transformSubscriber(
|
||||
array(
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('test@email.com');
|
||||
expect($this->router->transformSubscriber(
|
||||
array(
|
||||
'first_name' => 'First',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('First <test@email.com>');
|
||||
expect($this->router->transformSubscriber(
|
||||
array(
|
||||
'last_name' => 'Last',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('Last <test@email.com>');
|
||||
expect($this->router->transformSubscriber(
|
||||
array(
|
||||
'first_name' => 'First',
|
||||
'last_name' => 'Last',
|
||||
'email' => 'test@email.com'
|
||||
))
|
||||
)->equals('First Last <test@email.com>');
|
||||
}
|
||||
|
||||
function itCanConfigureMailer() {
|
||||
// TOFIX: This fails because $this->router->mailer is not set
|
||||
/*$mailer = $this->router->buildMailer();
|
||||
$class = 'Mailpoet\\Mailer\\' .
|
||||
((isset($this->router->mailer['type'])) ?
|
||||
$this->router->mailer['type'] . '\\' . $this->router->mailer['method'] :
|
||||
$this->router->mailer['method']
|
||||
);
|
||||
expect($mailer instanceof $class)->true();
|
||||
expect(method_exists($mailer, 'send'))->true();*/
|
||||
}
|
||||
|
||||
function itCanSend() {
|
||||
// TOFIX: This fails because $this->router->mailer is not set
|
||||
/*$newsletter = array(
|
||||
'subject' => 'testing Mailer router with ' . $this->router->mailer['method'],
|
||||
'body' => array(
|
||||
'html' => 'HTML body',
|
||||
'text' => 'TEXT body'
|
||||
)
|
||||
);
|
||||
$subscriber = array(
|
||||
'first_name' => 'First',
|
||||
'last_name' => 'Last',
|
||||
'email' => 'mailpoet-phoenix-test@mailinator.com'
|
||||
);
|
||||
expect($this->router->send($newsletter, $subscriber))->true();*/
|
||||
}
|
||||
}
|
@ -10,15 +10,15 @@ use MailPoet\Subscribers\ImportExport\Export\Export;
|
||||
|
||||
class ExportCest {
|
||||
function _before() {
|
||||
$this->JSONdata = json_decode(file_get_contents(dirname(__FILE__) . '/ExportTestData.json'), true);
|
||||
$this->subscriberFields = array(
|
||||
$this->JSON_data = json_decode(file_get_contents(dirname(__FILE__) . '/ExportTestData.json'), true);
|
||||
$this->subscriber_fields = array(
|
||||
'first_name' => 'First name',
|
||||
'last_name' => 'Last name',
|
||||
'email' => 'Email',
|
||||
1 => 'Country'
|
||||
);
|
||||
|
||||
$this->subscribersData = array(
|
||||
$this->subscribers_data = array(
|
||||
array(
|
||||
'first_name' => 'Adam',
|
||||
'last_name' => 'Smith',
|
||||
@ -42,13 +42,13 @@ class ExportCest {
|
||||
'email' => 'paul@newman.com'
|
||||
)
|
||||
);
|
||||
$this->customFieldsData = array(
|
||||
$this->custom_fields_data = array(
|
||||
array(
|
||||
'name' => 'Country',
|
||||
'type' => 'text'
|
||||
)
|
||||
);
|
||||
$this->segmentsData = array(
|
||||
$this->segments_data = array(
|
||||
array(
|
||||
'name' => 'Newspapers'
|
||||
),
|
||||
@ -56,7 +56,7 @@ class ExportCest {
|
||||
'name' => 'Journals'
|
||||
)
|
||||
);
|
||||
foreach ($this->subscribersData as $subscriber) {
|
||||
foreach($this->subscribers_data as $subscriber) {
|
||||
if(isset($subscriber[1])) {
|
||||
unset($subscriber[1]);
|
||||
}
|
||||
@ -64,20 +64,20 @@ class ExportCest {
|
||||
$entity->hydrate($subscriber);
|
||||
$entity->save();
|
||||
}
|
||||
foreach ($this->segmentsData as $customField) {
|
||||
foreach($this->segments_data as $custom_field) {
|
||||
$entity = Segment::create();
|
||||
$entity->hydrate($customField);
|
||||
$entity->hydrate($custom_field);
|
||||
$entity->save();
|
||||
}
|
||||
foreach ($this->customFieldsData as $customField) {
|
||||
foreach($this->custom_fields_data as $custom_field) {
|
||||
$entity = CustomField::create();
|
||||
$entity->hydrate($customField);
|
||||
$entity->hydrate($custom_field);
|
||||
$entity->save();
|
||||
}
|
||||
$entity = SubscriberCustomField::create();
|
||||
$entity->subscriber_id = 2;
|
||||
$entity->custom_field_id = 1;
|
||||
$entity->value = $this->subscribersData[1][1];
|
||||
$entity->value = $this->subscribers_data[1][1];
|
||||
$entity->save();
|
||||
$entity = SubscriberSegment::create();
|
||||
$entity->subscriber_id = 1;
|
||||
@ -95,15 +95,15 @@ class ExportCest {
|
||||
$entity->subscriber_id = 3;
|
||||
$entity->segment_id = 2;
|
||||
$entity->save();
|
||||
$this->export = new Export($this->JSONdata);
|
||||
$this->export = new Export($this->JSON_data);
|
||||
}
|
||||
|
||||
function itCanConstruct() {
|
||||
expect($this->export->exportConfirmedOption)
|
||||
expect($this->export->export_confirmed_option)
|
||||
->equals(false);
|
||||
expect($this->export->exportFormatOption)
|
||||
expect($this->export->export_format_option)
|
||||
->equals('csv');
|
||||
expect($this->export->groupBySegmentOption)
|
||||
expect($this->export->group_by_segment_option)
|
||||
->equals(false);
|
||||
expect($this->export->segments)
|
||||
->equals(
|
||||
@ -112,9 +112,9 @@ class ExportCest {
|
||||
2
|
||||
)
|
||||
);
|
||||
expect($this->export->subscribersWithoutSegment)
|
||||
expect($this->export->subscribers_without_segment)
|
||||
->equals(0);
|
||||
expect($this->export->subscriberFields)
|
||||
expect($this->export->subscriber_fields)
|
||||
->equals(
|
||||
array(
|
||||
'email',
|
||||
@ -126,42 +126,41 @@ class ExportCest {
|
||||
preg_match(
|
||||
'|' .
|
||||
Env::$temp_path . '/MailPoet_export_[a-f0-9]{4}.' .
|
||||
$this->export->exportFormatOption .
|
||||
'|', $this->export->exportFile)
|
||||
$this->export->export_format_option .
|
||||
'|', $this->export->export_file)
|
||||
)->equals(1);
|
||||
expect(
|
||||
preg_match(
|
||||
'|' .
|
||||
Env::$plugin_url . '/' .
|
||||
Env::$temp_name . '/' .
|
||||
basename($this->export->exportFile) .
|
||||
Env::$temp_URL . '/' .
|
||||
basename($this->export->export_file) .
|
||||
'|'
|
||||
, $this->export->exportFileURL)
|
||||
, $this->export->export_file_URL)
|
||||
)->equals(1);
|
||||
}
|
||||
|
||||
function itCanGetSubscriberCustomFields() {
|
||||
$source = CustomField::where('name', $this->customFieldsData[0]['name'])
|
||||
$source = CustomField::where('name', $this->custom_fields_data[0]['name'])
|
||||
->findOne();
|
||||
$target = $this->export->getSubscriberCustomFields();
|
||||
expect($target)->equals(array($source->id => $source->name));
|
||||
}
|
||||
|
||||
function itCanFormatSubscriberFields() {
|
||||
$formattedSubscriberFields = $this->export->formatSubscriberFields(
|
||||
array_keys($this->subscriberFields),
|
||||
function itCanFormatsubscriber_fields() {
|
||||
$formatted_subscriber_fields = $this->export->formatSubscriberFields(
|
||||
array_keys($this->subscriber_fields),
|
||||
$this->export->getSubscriberCustomFields()
|
||||
);
|
||||
expect($formattedSubscriberFields)
|
||||
->equals(array_values($this->subscriberFields));
|
||||
expect($formatted_subscriber_fields)
|
||||
->equals(array_values($this->subscriber_fields));
|
||||
}
|
||||
|
||||
function itProperlyReturnsSubscriberCustomFields() {
|
||||
$subscribers = $this->export->getSubscribers();
|
||||
foreach ($subscribers as $subscriber) {
|
||||
if($subscriber['email'] === $this->subscribersData[1]) {
|
||||
foreach($subscribers as $subscriber) {
|
||||
if($subscriber['email'] === $this->subscribers_data[1]) {
|
||||
expect($subscriber['Country'])
|
||||
->equals($this->subscribersData[1][1]);
|
||||
->equals($this->subscribers_data[1][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,26 +181,26 @@ class ExportCest {
|
||||
}
|
||||
|
||||
function itCanGroupSubscribersBySegments() {
|
||||
$this->export->groupBySegmentOption = true;
|
||||
$this->export->subscribersWithoutSegment = true;
|
||||
$this->export->group_by_segment_option = true;
|
||||
$this->export->subscribers_without_segment = true;
|
||||
$subscribers = $this->export->getSubscribers();
|
||||
expect(count($subscribers))->equals(5);
|
||||
}
|
||||
|
||||
function itCanGetSubscribersOnlyWithoutSegments() {
|
||||
$this->export->segments = array(0);
|
||||
$this->export->subscribersWithoutSegment = true;
|
||||
$this->export->subscribers_without_segment = true;
|
||||
$subscribers = $this->export->getSubscribers();
|
||||
expect(count($subscribers))->equals(1);
|
||||
expect($subscribers[0]['segment_name'])->equals('Not In List');
|
||||
expect($subscribers[0]['segment_name'])->equals('Not In Segment');
|
||||
}
|
||||
|
||||
function itCanGetOnlyConfirmedSubscribers() {
|
||||
$this->export->exportConfirmedOption = true;
|
||||
$this->export->export_confirmed_option = true;
|
||||
$subscribers = $this->export->getSubscribers();
|
||||
expect(count($subscribers))->equals(1);
|
||||
expect($subscribers[0]['email'])
|
||||
->equals($this->subscribersData[1]['email']);
|
||||
->equals($this->subscribers_data[1]['email']);
|
||||
}
|
||||
|
||||
function itCanGetSubscribersOnlyInSegments() {
|
||||
@ -213,18 +212,17 @@ class ExportCest {
|
||||
}
|
||||
|
||||
function itCanProcess() {
|
||||
$this->export->exportFile = $this->export->getExportFile('csv');
|
||||
$this->export->exportFormatOption = 'csv';
|
||||
$this->export->export_file = $this->export->getExportFile('csv');
|
||||
$this->export->export_format_option = 'csv';
|
||||
$this->export->process();
|
||||
$CSVFileSize = filesize($this->export->exportFile);
|
||||
$this->export->exportFile = $this->export->getExportFile('xls');
|
||||
$this->export->exportFormatOption = 'xls';
|
||||
$CSV_file_size = filesize($this->export->export_file);
|
||||
$this->export->export_file = $this->export->getExportFile('xls');
|
||||
$this->export->export_format_option = 'xls';
|
||||
$this->export->process();
|
||||
$XLSFileSize = filesize($this->export->exportFile);
|
||||
expect($CSVFileSize)->greaterThan(0);
|
||||
expect($XLSFileSize)->greaterThan(0);
|
||||
expect($XLSFileSize)->greaterThan($CSVFileSize);
|
||||
|
||||
$XLS_file_size = filesize($this->export->export_file);
|
||||
expect($CSV_file_size)->greaterThan(0);
|
||||
expect($XLS_file_size)->greaterThan(0);
|
||||
expect($XLS_file_size)->greaterThan($CSV_file_size);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
@ -234,4 +232,4 @@ class ExportCest {
|
||||
ORM::raw_execute('TRUNCATE ' . CustomField::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"exportConfirmedOption": false,
|
||||
"exportFormatOption": "csv",
|
||||
"groupBySegmentOption": false,
|
||||
"export_confirmed_option": false,
|
||||
"export_format_option": "csv",
|
||||
"group_by_segment_option": false,
|
||||
"segments": [
|
||||
"1",
|
||||
"2"
|
||||
],
|
||||
"subscriberFields": [
|
||||
"subscriber_fields": [
|
||||
"email",
|
||||
"first_name",
|
||||
"1"
|
||||
|
@ -8,8 +8,8 @@ use MailPoet\Util\Helpers;
|
||||
|
||||
class ImportCest {
|
||||
function __construct() {
|
||||
$this->JSONdata = json_decode(file_get_contents(dirname(__FILE__) . '/ImportTestData.json'), true);
|
||||
$this->subscribersData = array(
|
||||
$this->JSON_data = json_decode(file_get_contents(dirname(__FILE__) . '/ImportTestData.json'), true);
|
||||
$this->subscribers_data = array(
|
||||
'first_name' => array(
|
||||
'Adam',
|
||||
'Mary'
|
||||
@ -27,28 +27,28 @@ class ImportCest {
|
||||
'Brazil'
|
||||
)
|
||||
);
|
||||
$this->subscriberFields = array(
|
||||
$this->subscriber_fields = array(
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email'
|
||||
);
|
||||
$this->segments = range(0, 1);
|
||||
$this->subscriberCustomFields = array(777);
|
||||
$this->import = new Import($this->JSONdata);
|
||||
$this->subscriber_custom_fields = array(777);
|
||||
$this->import = new Import($this->JSON_data);
|
||||
}
|
||||
|
||||
function itCanConstruct() {
|
||||
expect($this->import->subscribersData)->equals($this->JSONdata['subscribers']);
|
||||
expect($this->import->segments)->equals($this->JSONdata['segments']);
|
||||
expect(is_array($this->import->subscriberFields))->true();
|
||||
expect(is_array($this->import->subscriberCustomFields))->true();
|
||||
expect($this->import->subscribersCount)->equals(
|
||||
count($this->JSONdata['subscribers']['email'])
|
||||
expect($this->import->subscribers_data)->equals($this->JSON_data['subscribers']);
|
||||
expect($this->import->segments)->equals($this->JSON_data['segments']);
|
||||
expect(is_array($this->import->subscriber_fields))->true();
|
||||
expect(is_array($this->import->subscriber_custom_fields))->true();
|
||||
expect($this->import->subscribers_count)->equals(
|
||||
count($this->JSON_data['subscribers']['email'])
|
||||
);
|
||||
expect(
|
||||
preg_match(
|
||||
'/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/',
|
||||
$this->import->currentTime)
|
||||
$this->import->import_time)
|
||||
)->equals(1);
|
||||
}
|
||||
|
||||
@ -62,23 +62,23 @@ class ImportCest {
|
||||
));
|
||||
$subscriber->save();
|
||||
list($existing, $new) = $this->import->filterExistingAndNewSubscribers(
|
||||
$this->subscribersData
|
||||
$this->subscribers_data
|
||||
);
|
||||
expect($existing['email'][0])->equals($this->subscribersData['email'][0]);
|
||||
expect($new['email'][0])->equals($this->subscribersData['email'][1]);
|
||||
expect($existing['email'][0])->equals($this->subscribers_data['email'][0]);
|
||||
expect($new['email'][0])->equals($this->subscribers_data['email'][1]);
|
||||
}
|
||||
|
||||
function itCanExtendSubscribersAndFields() {
|
||||
expect(in_array('created_at', $this->import->subscriberFields))->false();
|
||||
expect(isset($this->import->subscriberFields['created_at']))->false();
|
||||
expect(in_array('created_at', $this->import->subscriber_fields))->false();
|
||||
expect(isset($this->import->subscriber_fields['created_at']))->false();
|
||||
list($subscribers, $fields) = $this->import->extendSubscribersAndFields(
|
||||
$this->import->subscribersData,
|
||||
$this->import->subscriberFields
|
||||
$this->import->subscribers_data,
|
||||
$this->import->subscriber_fields
|
||||
);
|
||||
expect(in_array('created_at', $fields))->true();
|
||||
expect(isset($this->import->subscriberFields['created_at']))->false();
|
||||
expect(isset($this->import->subscriber_fields['created_at']))->false();
|
||||
expect(count($subscribers['created_at']))
|
||||
->equals($this->import->subscribersCount);
|
||||
->equals($this->import->subscribers_count);
|
||||
}
|
||||
|
||||
function itCanGetSubscriberFields() {
|
||||
@ -106,17 +106,17 @@ class ImportCest {
|
||||
}
|
||||
|
||||
function itCanFilterSubscriberStatus() {
|
||||
$subscibersData = $this->subscribersData;
|
||||
$subscriberFields = $this->subscriberFields;
|
||||
list($subscibersData, $subsciberFields) =
|
||||
$this->import->filterSubscriberStatus($subscibersData, $subscriberFields);
|
||||
$subscibers_data = $this->subscribers_data;
|
||||
$subscriber_fields = $this->subscriber_fields;
|
||||
list($subscibers_data, $subsciber_fields) =
|
||||
$this->import->filterSubscriberStatus($subscibers_data, $subscriber_fields);
|
||||
// subscribers' status was set to "subscribed" & status column was added
|
||||
// to subscribers fields
|
||||
expect(array_pop($subsciberFields))->equals('status');
|
||||
expect($subscibersData['status'][0])->equals('subscribed');
|
||||
expect(count($subscibersData['status']))->equals(2);
|
||||
$subscriberFields[] = 'status';
|
||||
$subscibersData = array(
|
||||
expect(array_pop($subsciber_fields))->equals('status');
|
||||
expect($subscibers_data['status'][0])->equals('subscribed');
|
||||
expect(count($subscibers_data['status']))->equals(2);
|
||||
$subscriber_fields[] = 'status';
|
||||
$subscibers_data = array(
|
||||
'status' => array(
|
||||
#subscribed
|
||||
'subscribed',
|
||||
@ -135,9 +135,9 @@ class ImportCest {
|
||||
'false'
|
||||
),
|
||||
);
|
||||
list($subscibersData, $subsciberFields) =
|
||||
$this->import->filterSubscriberStatus($subscibersData, $subscriberFields);
|
||||
expect($subscibersData)->equals(
|
||||
list($subscibers_data, $subsciber_fields) =
|
||||
$this->import->filterSubscriberStatus($subscibers_data, $subscriber_fields);
|
||||
expect($subscibers_data)->equals(
|
||||
array(
|
||||
'status' => array(
|
||||
'subscribed',
|
||||
@ -158,73 +158,73 @@ class ImportCest {
|
||||
}
|
||||
|
||||
function itCanAddOrUpdateSubscribers() {
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$subscribersData,
|
||||
$this->subscriberFields,
|
||||
$subscribers_data,
|
||||
$this->subscriber_fields,
|
||||
false
|
||||
);
|
||||
$subscribers = Subscriber::findArray();
|
||||
expect(count($subscribers))->equals(2);
|
||||
expect($subscribers[0]['email'])
|
||||
->equals($subscribersData['email'][0]);
|
||||
->equals($subscribers_data['email'][0]);
|
||||
$data['first_name'][1] = 'MaryJane';
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'update',
|
||||
$subscribersData,
|
||||
$this->subscriberFields,
|
||||
$subscribers_data,
|
||||
$this->subscriber_fields,
|
||||
false
|
||||
);
|
||||
$subscribers = Subscriber::findArray();
|
||||
expect($subscribers[1]['first_name'])
|
||||
->equals($subscribersData['first_name'][1]);
|
||||
->equals($subscribers_data['first_name'][1]);
|
||||
}
|
||||
|
||||
function itCanDeleteTrashedSubscribers() {
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscriberFields = $this->subscriberFields;
|
||||
$subscribersData['deleted_at'] = array(
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$subscriber_fields = $this->subscriber_fields;
|
||||
$subscribers_data['deleted_at'] = array(
|
||||
null,
|
||||
date('Y-m-d H:i:s')
|
||||
);
|
||||
$subscriberFields[] = 'deleted_at';
|
||||
$subscriber_fields[] = 'deleted_at';
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$subscribersData,
|
||||
$subscriberFields,
|
||||
$subscribers_data,
|
||||
$subscriber_fields,
|
||||
false
|
||||
);
|
||||
$dbSubscribers = Helpers::arrayColumn(
|
||||
$db_subscribers = Helpers::arrayColumn(
|
||||
Subscriber::select('id')
|
||||
->findArray(),
|
||||
'id'
|
||||
);
|
||||
expect(count($dbSubscribers))->equals(2);
|
||||
expect(count($db_subscribers))->equals(2);
|
||||
$this->import->addSubscribersToSegments(
|
||||
$dbSubscribers,
|
||||
$db_subscribers,
|
||||
$this->segments
|
||||
);
|
||||
$subscribersSegments = SubscriberSegment::findArray();
|
||||
expect(count($subscribersSegments))->equals(4);
|
||||
$subscribers_segments = SubscriberSegment::findArray();
|
||||
expect(count($subscribers_segments))->equals(4);
|
||||
$this->import->deleteExistingTrashedSubscribers(
|
||||
$subscribersData
|
||||
$subscribers_data
|
||||
);
|
||||
$subscribersSegments = SubscriberSegment::findArray();
|
||||
$dbSubscribers = Subscriber::findArray();
|
||||
expect(count($subscribersSegments))->equals(2);
|
||||
expect(count($dbSubscribers))->equals(1);
|
||||
$subscribers_segments = SubscriberSegment::findArray();
|
||||
$db_subscribers = Subscriber::findArray();
|
||||
expect(count($subscribers_segments))->equals(2);
|
||||
expect(count($db_subscribers))->equals(1);
|
||||
}
|
||||
|
||||
function itCanCreateOrUpdateCustomFields() {
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$subscribersData,
|
||||
$this->subscriberFields,
|
||||
$subscribers_data,
|
||||
$this->subscriber_fields,
|
||||
false
|
||||
);
|
||||
$dbSubscribers = Helpers::arrayColumn(
|
||||
$db_subscribers = Helpers::arrayColumn(
|
||||
Subscriber::selectMany(
|
||||
array(
|
||||
'id',
|
||||
@ -235,60 +235,60 @@ class ImportCest {
|
||||
);
|
||||
$this->import->createOrUpdateCustomFields(
|
||||
'create',
|
||||
$dbSubscribers,
|
||||
$subscribersData,
|
||||
$this->subscriberCustomFields
|
||||
$db_subscribers,
|
||||
$subscribers_data,
|
||||
$this->subscriber_custom_fields
|
||||
);
|
||||
$subscriberCustomFields = SubscriberCustomField::findArray();
|
||||
expect(count($subscriberCustomFields))->equals(2);
|
||||
expect($subscriberCustomFields[0]['value'])
|
||||
->equals($subscribersData[777][0]);
|
||||
$subscribersData[777][1] = 'Rio';
|
||||
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
||||
expect(count($subscriber_custom_fields))->equals(2);
|
||||
expect($subscriber_custom_fields[0]['value'])
|
||||
->equals($subscribers_data[777][0]);
|
||||
$subscribers_data[777][1] = 'Rio';
|
||||
$this->import->createOrUpdateCustomFields(
|
||||
'update',
|
||||
$dbSubscribers,
|
||||
$subscribersData,
|
||||
$this->subscriberCustomFields
|
||||
$db_subscribers,
|
||||
$subscribers_data,
|
||||
$this->subscriber_custom_fields
|
||||
);
|
||||
$subscriberCustomFields = SubscriberCustomField::findArray();
|
||||
expect($subscriberCustomFields[1]['value'])
|
||||
->equals($subscribersData[777][1]);
|
||||
$subscriber_custom_fields = SubscriberCustomField::findArray();
|
||||
expect($subscriber_custom_fields[1]['value'])
|
||||
->equals($subscribers_data[777][1]);
|
||||
}
|
||||
|
||||
function itCanaddSubscribersToSegments() {
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$subscribersData,
|
||||
$this->subscriberFields,
|
||||
$subscribers_data,
|
||||
$this->subscriber_fields,
|
||||
false
|
||||
);
|
||||
$dbSubscribers = Helpers::arrayColumn(
|
||||
$db_subscribers = Helpers::arrayColumn(
|
||||
Subscriber::select('id')
|
||||
->findArray(),
|
||||
'id'
|
||||
);
|
||||
$this->import->addSubscribersToSegments(
|
||||
$dbSubscribers,
|
||||
$db_subscribers,
|
||||
$this->segments
|
||||
);
|
||||
$subscribersSegments = SubscriberSegment::findArray();
|
||||
$subscribers_segments = SubscriberSegment::findArray();
|
||||
// 2 subscribers * 2 segments
|
||||
expect(count($subscribersSegments))->equals(4);
|
||||
expect(count($subscribers_segments))->equals(4);
|
||||
}
|
||||
|
||||
function itCanDeleteExistingTrashedSubscribers() {
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscriberFields = $this->subscriberFields;
|
||||
$subscriberFields[] = 'deleted_at';
|
||||
$subscribersData['deleted_at'] = array(
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$subscriber_fields = $this->subscriber_fields;
|
||||
$subscriber_fields[] = 'deleted_at';
|
||||
$subscribers_data['deleted_at'] = array(
|
||||
null,
|
||||
date('Y-m-d H:i:s')
|
||||
);
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$subscribersData,
|
||||
$subscriberFields,
|
||||
$subscribers_data,
|
||||
$subscriber_fields,
|
||||
false
|
||||
);
|
||||
}
|
||||
@ -304,11 +304,12 @@ class ImportCest {
|
||||
Subscriber::where('email', 'mbanks4@blinklist.com')
|
||||
->findOne()
|
||||
->delete();
|
||||
$import->currentTime = date('Y-m-d 12:i:s');
|
||||
// TODO: find a more elegant way to test this
|
||||
$import->import_time = date('Y-m-d 12:i:s');
|
||||
$result = $import->process();
|
||||
expect($result['data']['created'])->equals(1);
|
||||
expect($result['data']['updated'])->equals(996);
|
||||
$import->updateSubscribers = false;
|
||||
$import->update_subscribers = false;
|
||||
$result = $import->process();
|
||||
expect($result['data']['created'])->equals(0);
|
||||
expect($result['data']['updated'])->equals(0);
|
||||
|
@ -4,4 +4,4 @@
|
||||
<%= source('newsletter/templates/svg/block-tools/settings.svg') %>
|
||||
</a>{{/if}}{{#if tools.delete}}<div class="mailpoet_delete_block"><a href="javascript:;" class="mailpoet_tool mailpoet_delete_block_activate" title="<%= __('Delete') %>"><%= source('newsletter/templates/svg/block-tools/trash.svg') %></a><a href="javascript:;" class="mailpoet_delete_block_confirm" title="<%= __('Confirm deletion') %>"><%= __('Delete') %></a><a href="javascript:;" class="mailpoet_delete_block_cancel" title="<%= __('Cancel deletion') %>"><%= __('Cancel') %></a></div>{{/if}}{{#if tools.move}}<a href="javascript:;" class="mailpoet_tool mailpoet_move_block" title="<%= __('Drag to move') %>">
|
||||
<%= source('newsletter/templates/svg/block-tools/move.svg') %>
|
||||
</a>{{/if}}<div class="clearfix"></div>
|
||||
</a>{{/if}}
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div class="handlediv" title="Click to toggle"><br></div>
|
||||
<h3><%= __('Content') %></h3>
|
||||
<div class="mailpoet_region_content">
|
||||
<div class="mailpoet_region_content clearfix">
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div class="handlediv" title="Click to toggle"><br></div>
|
||||
<h3><%= __('Layout') %></h3>
|
||||
<div class="mailpoet_region_content">
|
||||
<div class="mailpoet_region_content clearfix">
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
|
@ -79,6 +79,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<a href="javascript:;" id="return_to_step1"
|
||||
class="button-primary wysija button"><%= __('Previous step') %> </a>
|
||||
|
||||
<a href="javascript:;" id="step2_process"
|
||||
class="button-primary wysija button-disabled"><%= __('Next step') %> </a>
|
||||
</th>
|
||||
@ -95,7 +98,7 @@
|
||||
{{#show_and_match_columns .}}
|
||||
{{#.}}
|
||||
<th>
|
||||
<select class="mailpoet_subscribers_column_data_match" data-column-id="{{column_id}}" id="column_{{@index}}">
|
||||
<select class="mailpoet_subscribers_column_data_match" id="{{column_id}}" data-column-id="{{column_id}}" id="column_{{@index}}">
|
||||
</th>
|
||||
{{/.}}
|
||||
{{/show_and_match_columns}}
|
||||
|
@ -23,7 +23,7 @@ baseConfig = {
|
||||
'handlebars': 'handlebars/dist/handlebars.js',
|
||||
'backbone.marionette': 'backbone.marionette/lib/backbone.marionette',
|
||||
'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js',
|
||||
'sticky-kit': 'vendor_static/jquery.sticky-kit.js',
|
||||
'sticky-kit': 'vendor/jquery.sticky-kit.js',
|
||||
'interact$': 'interact.js/interact.js',
|
||||
'spectrum$': 'spectrum-colorpicker/spectrum.js',
|
||||
'blob$': 'blob/Blob.js',
|
||||
@ -77,7 +77,11 @@ baseConfig = {
|
||||
{
|
||||
include: /html2canvas.js$/,
|
||||
loader: 'expose-loader?html2canvas',
|
||||
}
|
||||
},
|
||||
{
|
||||
include: require.resolve('velocity-animate'),
|
||||
loader: 'imports-loader?jQuery=jquery',
|
||||
},
|
||||
]
|
||||
}
|
||||
};
|
||||
@ -123,6 +127,7 @@ config.push(_.extend({}, baseConfig, {
|
||||
'sticky-kit',
|
||||
'blob',
|
||||
'filesaver',
|
||||
'velocity-animate',
|
||||
|
||||
'newsletter_editor/communicationsFix.js',
|
||||
'newsletter_editor/App',
|
||||
@ -193,6 +198,8 @@ config.push(_.extend({}, baseConfig, {
|
||||
'select2',
|
||||
'blob',
|
||||
'filesaver',
|
||||
'velocity-animate',
|
||||
|
||||
'newsletter_editor/communicationsFix.js',
|
||||
'newsletter_editor/App',
|
||||
'newsletter_editor/components/config.js',
|
||||
@ -253,7 +260,7 @@ config.push(_.extend({}, baseConfig, {
|
||||
'tests/javascript/newsletter_editor'
|
||||
],
|
||||
alias: {
|
||||
'sticky-kit': 'sticky-kit/jquery.sticky-kit',
|
||||
'sticky-kit': 'vendor/jquery.sticky-kit.js',
|
||||
'backbone.marionette': 'backbone.marionette/lib/backbone.marionette',
|
||||
'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js',
|
||||
'blob$': 'blob/Blob.js',
|
||||
|
Reference in New Issue
Block a user