Compare commits
94 Commits
0.0.50
...
3.0.0-beta
Author | SHA1 | Date | |
---|---|---|---|
fbeddb8af2 | |||
8c3525589c | |||
58f97ea43d | |||
8e4c3ea7ea | |||
3865a8e8cd | |||
02221f6833 | |||
b63ef8cca0 | |||
aabe71d473 | |||
1405249712 | |||
16ee5e934a | |||
74276b45c5 | |||
b046c9ea4b | |||
8bd7f5f169 | |||
ee119215c0 | |||
c22d3c8957 | |||
0dd7a3990f | |||
1a6b032943 | |||
1220f47d87 | |||
583b34a5c1 | |||
b36d13a087 | |||
1a3aa7a4e4 | |||
70a13a4774 | |||
6ce13df2f3 | |||
4eb85c5d7e | |||
6eb6636e8b | |||
9635fb5365 | |||
d4b39cb1f4 | |||
af36e7a0d9 | |||
1db8626e35 | |||
61c255564f | |||
7e5047d98f | |||
4698d5a4db | |||
864c9cbe95 | |||
011b6f9b3c | |||
e45fc0c0a0 | |||
6bebdd6e95 | |||
8df4da768a | |||
67f4c21aa8 | |||
5eba0e2731 | |||
3efa429a1b | |||
3a78441a83 | |||
c05be7d987 | |||
b8cb1da777 | |||
ac8d1d808f | |||
9cd7b1a204 | |||
0d32c09df3 | |||
9f288ae11a | |||
e87ccd6b92 | |||
8a2b6ac69b | |||
43bd2d4413 | |||
9fdb99a06b | |||
f3c69c8353 | |||
29a32d3da9 | |||
8412cc852d | |||
b4e4320508 | |||
dbd6e6f310 | |||
bdcb7f0e58 | |||
85c9b121f5 | |||
069bc95297 | |||
0b711e6341 | |||
2a961cca01 | |||
e855fdbbaf | |||
288464e8cb | |||
1331ed70f1 | |||
411188c345 | |||
ee275532b1 | |||
b2eef93516 | |||
40ca54c447 | |||
b65db1afbf | |||
c258b1c3a2 | |||
7a5a726400 | |||
e553922eca | |||
04e9e8a45d | |||
f037e1271d | |||
f4563e18cd | |||
feaac5eb54 | |||
a6059d5bc3 | |||
f2104ef30f | |||
e7f760328e | |||
c09bcd51ad | |||
01af4d3401 | |||
2ba9d95a2e | |||
b2d4bfc760 | |||
57f5f16bb6 | |||
7d2e13b9a3 | |||
6d39f9fa78 | |||
a4395f2350 | |||
411969b3eb | |||
1868ca3155 | |||
e765471f5d | |||
bdce7c5e5a | |||
773be9f5c8 | |||
6ae46b05e5 | |||
217894745d |
45
RoboFile.php
@ -3,14 +3,21 @@
|
||||
class RoboFile extends \Robo\Tasks {
|
||||
|
||||
function install() {
|
||||
$this->_exec('./composer.phar install');
|
||||
$this->_exec('npm install');
|
||||
return $this->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('./composer.phar install')
|
||||
->exec('npm install')
|
||||
->run();
|
||||
}
|
||||
|
||||
function update() {
|
||||
$this->say(getenv('WP_TEST_URL'));
|
||||
$this->_exec('./composer.phar update');
|
||||
$this->_exec('npm update');
|
||||
|
||||
return $this->taskExecStack()
|
||||
->stopOnFail()
|
||||
->exec('./composer.phar update')
|
||||
->exec('npm update')
|
||||
->run();
|
||||
}
|
||||
|
||||
protected function rsearch($folder, $extensions = array()) {
|
||||
@ -61,12 +68,14 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
|
||||
function compileAll() {
|
||||
$this->compileJs();
|
||||
$this->compileCss();
|
||||
$collection = $this->collection();
|
||||
$collection->add(array($this, 'compileJs'));
|
||||
$collection->add(array($this, 'compileCss'));
|
||||
return $collection->run();
|
||||
}
|
||||
|
||||
function compileJs() {
|
||||
$this->_exec('./node_modules/webpack/bin/webpack.js');
|
||||
return $this->_exec('./node_modules/webpack/bin/webpack.js --bail');
|
||||
}
|
||||
|
||||
function compileCss() {
|
||||
@ -78,7 +87,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
'assets/css/src/importExport.styl'
|
||||
);
|
||||
|
||||
$this->_exec(join(' ', array(
|
||||
return $this->_exec(join(' ', array(
|
||||
'./node_modules/stylus/bin/stylus',
|
||||
'--include ./node_modules',
|
||||
'--include-css',
|
||||
@ -89,14 +98,14 @@ class RoboFile extends \Robo\Tasks {
|
||||
}
|
||||
|
||||
function makepot() {
|
||||
$this->_exec('./node_modules/.bin/grunt makepot'.
|
||||
return $this->_exec('./node_modules/.bin/grunt makepot'.
|
||||
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
||||
' --base_path '.__DIR__
|
||||
);
|
||||
}
|
||||
|
||||
function pushpot() {
|
||||
$this->_exec('./node_modules/.bin/grunt pushpot'.
|
||||
return $this->_exec('./node_modules/.bin/grunt pushpot'.
|
||||
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
||||
' --base_path '.__DIR__
|
||||
);
|
||||
@ -152,22 +161,26 @@ class RoboFile extends \Robo\Tasks {
|
||||
function testDebug() {
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
$this->loadEnv();
|
||||
$this->_exec('vendor/bin/codecept run unit --debug');
|
||||
return $this->_exec('vendor/bin/codecept run unit --debug');
|
||||
}
|
||||
|
||||
function testFailed() {
|
||||
$this->loadEnv();
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
$this->_exec('vendor/bin/codecept run -g failed');
|
||||
return $this->_exec('vendor/bin/codecept run -g failed');
|
||||
}
|
||||
|
||||
function qa() {
|
||||
$this->qaLint();
|
||||
$this->qaCodeSniffer('all');
|
||||
$collection = $this->collection();
|
||||
$collection->add(array($this, 'qaLint'));
|
||||
$collection->add(function() {
|
||||
return $this->qaCodeSniffer('all');
|
||||
});
|
||||
return $collection->run();
|
||||
}
|
||||
|
||||
function qaLint() {
|
||||
$this->_exec('./tasks/php_lint.sh lib/ tests/ mailpoet.php');
|
||||
return $this->_exec('./tasks/php_lint.sh lib/ tests/ mailpoet.php');
|
||||
}
|
||||
|
||||
function qaCodeSniffer($severity='errors') {
|
||||
@ -176,7 +189,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
} else {
|
||||
$severityFlag = '-n';
|
||||
}
|
||||
$this->_exec(
|
||||
return $this->_exec(
|
||||
'./vendor/bin/phpcs '.
|
||||
'--standard=./tasks/code_sniffer/MailPoet '.
|
||||
'--ignore=./lib/Util/Sudzy/*,./lib/Util/CSS.php,./lib/Util/XLSXWriter.php,'.
|
||||
|
@ -1,3 +1,15 @@
|
||||
$box-width = 425px
|
||||
$box-height = 150px
|
||||
$thumbnail-width = $box-height
|
||||
$thumbnail-height = $thumbnail-width
|
||||
$box-description-space-between-heading-and-paragraph = 5px
|
||||
$box-description-height = 110px
|
||||
$box-description-text-height = $box-description-height - $box-description-space-between-heading-and-paragraph
|
||||
$box-heading-line-height = $box-description-text-height / 4
|
||||
$box-heading-font-size = $box-heading-line-height * 5/7
|
||||
$box-description-line-height = $box-heading-line-height / 2
|
||||
$box-description-font-size = $box-description-line-height
|
||||
|
||||
.mailpoet_boxes.mailpoet_boxes_loading
|
||||
opacity: 0.2
|
||||
|
||||
@ -6,8 +18,8 @@
|
||||
position: relative
|
||||
padding: 15px
|
||||
margin: 15px 25px 0 0
|
||||
width: 425px
|
||||
height: 150px
|
||||
width: $box-width
|
||||
height: $box-height
|
||||
border: 1px solid #dedede
|
||||
background-color: #fff
|
||||
|
||||
@ -18,15 +30,15 @@
|
||||
background-position: center
|
||||
color: #222
|
||||
border: 1px solid #ccc
|
||||
width: 150px
|
||||
height: 150px
|
||||
width: $thumbnail-height
|
||||
height: $thumbnail-width
|
||||
margin-right: 15px
|
||||
float: left
|
||||
overflow: hidden
|
||||
position: relative
|
||||
|
||||
img
|
||||
min-width: 150px
|
||||
min-width: $thumbnail-width
|
||||
height: auto
|
||||
width: 110%
|
||||
position: relative
|
||||
@ -60,20 +72,21 @@
|
||||
.mailpoet_boxes .mailpoet_description
|
||||
float:left
|
||||
width: 245px
|
||||
max-height: calc(115px - 2em)
|
||||
padding-bottom: 2em
|
||||
max-height: $box-description-height
|
||||
padding-bottom: 0
|
||||
overflow: hidden
|
||||
|
||||
h3
|
||||
margin: 0 0 0.7em 0
|
||||
margin: 0 0 $box-description-space-between-heading-and-paragraph 0
|
||||
overflow: hidden
|
||||
max-width: 210px
|
||||
line-height: 1.4em
|
||||
line-height: $box-heading-line-height
|
||||
font-size: $box-heading-font-size
|
||||
|
||||
p
|
||||
font-size: 13px
|
||||
line-height: 1.5
|
||||
margin: 1em 0
|
||||
font-size: $box-description-font-size
|
||||
line-height: $box-description-line-height
|
||||
margin: 0
|
||||
|
||||
.mailpoet_boxes .mailpoet_actions
|
||||
position: absolute
|
||||
|
@ -1,3 +1,3 @@
|
||||
define([], function() {
|
||||
!function(e,o,n){window.HSCW=o,window.HS=n,n.beacon=n.beacon||{};var t=n.beacon;t.userConfig={},t.readyQueue=[],t.config=function(e){this.userConfig=e},t.ready=function(e){this.readyQueue.push(e)},o.config={docs:{enabled:!1,baseUrl:""},contact:{enabled:!0,formId:"e5c408c7-895e-11e5-9e75-0a7d6919297d"}};var r=e.getElementsByTagName("script")[0],c=e.createElement("script");c.type="text/javascript",c.async=!0,c.src="https://djtflbt20bdde.cloudfront.net/",r.parentNode.insertBefore(c,r)}(document,window.HSCW||{},window.HS||{});
|
||||
!function(e,o,n){window.HSCW=o,window.HS=n,n.beacon=n.beacon||{};var t=n.beacon;t.userConfig={},t.readyQueue=[],t.config=function(e){this.userConfig=e},t.ready=function(e){this.readyQueue.push(e)},o.config={docs:{enabled:!0,baseUrl:"//mailpoet3.helpscoutdocs.com/"},contact:{enabled:!0,formId:"aa21ca80-a4f5-11e6-91aa-0a5fecc78a4d"}};var r=e.getElementsByTagName("script")[0],c=e.createElement("script");c.type="text/javascript",c.async=!0,c.src="https://djtflbt20bdde.cloudfront.net/",r.parentNode.insertBefore(c,r)}(document,window.HSCW||{},window.HS||{});
|
||||
});
|
||||
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Text Editor Behavior
|
||||
*
|
||||
* Adds TinyMCE text editing capabilities to a view
|
||||
*/
|
||||
define([
|
||||
'backbone.marionette',
|
||||
'underscore',
|
||||
'newsletter_editor/behaviors/BehaviorsLookup'
|
||||
], function(Marionette, _, BehaviorsLookup) {
|
||||
|
||||
BehaviorsLookup.TextEditorBehavior = Marionette.Behavior.extend({
|
||||
defaults: {
|
||||
selector: '.mailpoet_content',
|
||||
toolbar1: "bold italic link unlink forecolor mailpoet_shortcodes",
|
||||
toolbar2: "",
|
||||
validElements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
|
||||
invalidElements: "script",
|
||||
blockFormats: 'Paragraph=p',
|
||||
plugins: "link textcolor colorpicker mailpoet_shortcodes",
|
||||
configurationFilter: function(originalConfig) { return originalConfig; },
|
||||
},
|
||||
onDomRefresh: function() {
|
||||
var that = this;
|
||||
if (this.view.disableTextEditor === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$(this.options.selector).tinymce(this.options.configurationFilter({
|
||||
inline: true,
|
||||
|
||||
menubar: false,
|
||||
toolbar1: this.options.toolbar1,
|
||||
toolbar2: this.options.toolbar2,
|
||||
|
||||
valid_elements: this.options.validElements,
|
||||
invalid_elements: this.options.invalidElements,
|
||||
block_formats: this.options.blockFormats,
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
convert_urls: true,
|
||||
urlconverter_callback: function(url, node, on_save, name) {
|
||||
if (url.match(/\[.+\]/g)) {
|
||||
// Do not convert URLs with shortcodes
|
||||
return url;
|
||||
}
|
||||
|
||||
return this.documentBaseURI.toAbsolute(
|
||||
url,
|
||||
this.settings.remove_script_host
|
||||
);
|
||||
},
|
||||
|
||||
plugins: this.options.plugins,
|
||||
|
||||
setup: function(editor) {
|
||||
editor.on('change', function(e) {
|
||||
that.view.triggerMethod('text:editor:change', editor.getContent());
|
||||
});
|
||||
|
||||
editor.on('click', function(e) {
|
||||
editor.focus();
|
||||
});
|
||||
|
||||
editor.on('focus', function(e) {
|
||||
that.view.triggerMethod('text:editor:focus');
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
that.view.triggerMethod('text:editor:blur');
|
||||
});
|
||||
},
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
@ -42,53 +42,31 @@ define([
|
||||
modelEvents: _.extend({
|
||||
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
|
||||
}, _.omit(base.BlockView.prototype.modelEvents, 'change')),
|
||||
behaviors: _.extend({}, base.BlockView.prototype.behaviors, {
|
||||
TextEditorBehavior: {
|
||||
configurationFilter: function(originalSettings) {
|
||||
return _.extend({}, originalSettings, {
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
onDragSubstituteBy: function() { return Module.FooterWidgetView; },
|
||||
onRender: function() {
|
||||
this.toolsView = new Module.FooterBlockToolsView({ model: this.model });
|
||||
this.toolsRegion.show(this.toolsView);
|
||||
},
|
||||
onDomRefresh: function() {
|
||||
this.attachTextEditor();
|
||||
onTextEditorChange: function(newContent) {
|
||||
this.model.set('text', newContent);
|
||||
},
|
||||
attachTextEditor: function() {
|
||||
var that = this;
|
||||
this.$('.mailpoet_content').tinymce({
|
||||
inline: true,
|
||||
|
||||
menubar: false,
|
||||
toolbar: "bold italic link unlink forecolor mailpoet_shortcodes",
|
||||
|
||||
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
|
||||
invalid_elements: "script",
|
||||
block_formats: 'Paragraph=p',
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
|
||||
plugins: "link textcolor colorpicker mailpoet_shortcodes",
|
||||
|
||||
setup: function(editor) {
|
||||
editor.on('change', function(e) {
|
||||
that.model.set('text', editor.getContent());
|
||||
});
|
||||
|
||||
editor.on('click', function(e) {
|
||||
editor.focus();
|
||||
});
|
||||
|
||||
editor.on('focus', function(e) {
|
||||
that.disableDragging();
|
||||
that.disableShowingTools();
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
that.enableDragging();
|
||||
that.enableShowingTools();
|
||||
});
|
||||
},
|
||||
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
onTextEditorFocus: function() {
|
||||
this.disableDragging();
|
||||
this.disableShowingTools();
|
||||
},
|
||||
onTextEditorBlur: function() {
|
||||
this.enableDragging();
|
||||
this.enableShowingTools();
|
||||
},
|
||||
disableDragging: function() {
|
||||
this.$('.mailpoet_content').addClass('mailpoet_ignore_drag');
|
||||
|
@ -42,53 +42,31 @@ define([
|
||||
modelEvents: _.extend({
|
||||
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
|
||||
}, _.omit(base.BlockView.prototype.modelEvents, 'change')),
|
||||
behaviors: _.extend({}, base.BlockView.prototype.behaviors, {
|
||||
TextEditorBehavior: {
|
||||
configurationFilter: function(originalSettings) {
|
||||
return _.extend({}, originalSettings, {
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
onDragSubstituteBy: function() { return Module.HeaderWidgetView; },
|
||||
onRender: function() {
|
||||
this.toolsView = new Module.HeaderBlockToolsView({ model: this.model });
|
||||
this.toolsRegion.show(this.toolsView);
|
||||
},
|
||||
onDomRefresh: function() {
|
||||
this.attachTextEditor();
|
||||
onTextEditorChange: function(newContent) {
|
||||
this.model.set('text', newContent);
|
||||
},
|
||||
attachTextEditor: function() {
|
||||
var that = this;
|
||||
this.$('.mailpoet_content').tinymce({
|
||||
inline: true,
|
||||
|
||||
menubar: false,
|
||||
toolbar: "bold italic link unlink forecolor mailpoet_shortcodes",
|
||||
|
||||
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
|
||||
invalid_elements: "script",
|
||||
block_formats: 'Paragraph=p',
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
|
||||
plugins: "link textcolor colorpicker mailpoet_shortcodes",
|
||||
|
||||
setup: function(editor) {
|
||||
editor.on('change', function(e) {
|
||||
that.model.set('text', editor.getContent());
|
||||
});
|
||||
|
||||
editor.on('click', function(e) {
|
||||
editor.focus();
|
||||
});
|
||||
|
||||
editor.on('focus', function(e) {
|
||||
that.disableDragging();
|
||||
that.disableShowingTools();
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
that.enableDragging();
|
||||
that.enableShowingTools();
|
||||
});
|
||||
},
|
||||
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
onTextEditorFocus: function() {
|
||||
this.disableDragging();
|
||||
this.disableShowingTools();
|
||||
},
|
||||
onTextEditorBlur: function() {
|
||||
this.enableDragging();
|
||||
this.enableShowingTools();
|
||||
},
|
||||
disableDragging: function() {
|
||||
this.$('.mailpoet_content').addClass('mailpoet_ignore_drag');
|
||||
|
@ -25,12 +25,30 @@ define([
|
||||
className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block",
|
||||
getTemplate: function() { return templates.textBlock; },
|
||||
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing
|
||||
behaviors: _.extend({}, base.BlockView.prototype.behaviors, {
|
||||
TextEditorBehavior: {
|
||||
toolbar1: "formatselect bold italic forecolor | link unlink",
|
||||
toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_shortcodes",
|
||||
validElements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]",
|
||||
invalidElements: "script",
|
||||
blockFormats: 'Heading 1=h1;Heading 2=h2;Heading 3=h3;Paragraph=p',
|
||||
plugins: "link code textcolor colorpicker mailpoet_shortcodes",
|
||||
configurationFilter: function(originalSettings) {
|
||||
return _.extend({}, originalSettings, {
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
initialize: function(options) {
|
||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||
|
||||
this.renderOptions = _.defaults(options.renderOptions || {}, {
|
||||
disableTextEditor: false,
|
||||
});
|
||||
|
||||
this.disableTextEditor = this.renderOptions.disableTextEditor;
|
||||
},
|
||||
onDragSubstituteBy: function() { return Module.TextWidgetView; },
|
||||
onRender: function() {
|
||||
@ -42,53 +60,18 @@ define([
|
||||
});
|
||||
this.toolsRegion.show(this.toolsView);
|
||||
},
|
||||
onDomRefresh: function() {
|
||||
this.attachTextEditor();
|
||||
onTextEditorChange: function(newContent) {
|
||||
this.model.set('text', newContent);
|
||||
},
|
||||
attachTextEditor: function() {
|
||||
var that = this;
|
||||
if (!this.renderOptions.disableTextEditor) {
|
||||
this.$('.mailpoet_content').tinymce({
|
||||
inline: true,
|
||||
|
||||
menubar: false,
|
||||
toolbar1: "formatselect bold italic forecolor | link unlink",
|
||||
toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_shortcodes",
|
||||
|
||||
//forced_root_block: 'p',
|
||||
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]",
|
||||
invalid_elements: "script",
|
||||
block_formats: 'Heading 1=h1;Heading 2=h2;Heading 3=h3;Paragraph=p',
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
|
||||
plugins: "link code textcolor colorpicker mailpoet_shortcodes",
|
||||
|
||||
setup: function(editor) {
|
||||
editor.on('change', function(e) {
|
||||
that.model.set('text', editor.getContent());
|
||||
});
|
||||
|
||||
editor.on('click', function(e) {
|
||||
editor.focus();
|
||||
});
|
||||
|
||||
editor.on('focus', function(e) {
|
||||
that.disableDragging();
|
||||
that.disableShowingTools();
|
||||
});
|
||||
|
||||
editor.on('blur', function(e) {
|
||||
that.enableDragging();
|
||||
that.enableShowingTools();
|
||||
});
|
||||
},
|
||||
|
||||
mailpoet_shortcodes: App.getConfig().get('shortcodes').toJSON(),
|
||||
mailpoet_shortcodes_window_title: MailPoet.I18n.t('shortcodesWindowTitle'),
|
||||
});
|
||||
}
|
||||
onTextEditorFocus: function() {
|
||||
this.disableDragging();
|
||||
this.disableShowingTools();
|
||||
},
|
||||
onTextEditorBlur: function() {
|
||||
this.enableDragging();
|
||||
this.enableShowingTools();
|
||||
},
|
||||
|
||||
disableDragging: function() {
|
||||
this.$('.mailpoet_content').addClass('mailpoet_ignore_drag');
|
||||
},
|
||||
|
@ -61,7 +61,7 @@ const _QueueMixin = {
|
||||
);
|
||||
|
||||
// calculate percentage done
|
||||
const percentage = Math.round(
|
||||
let percentage = Math.round(
|
||||
(newsletter.queue.count_processed * 100) / (newsletter.queue.count_total)
|
||||
);
|
||||
|
||||
@ -108,15 +108,24 @@ const _QueueMixin = {
|
||||
);
|
||||
}
|
||||
|
||||
let progress_bar_width = 0;
|
||||
|
||||
if (isNaN(percentage)) {
|
||||
percentage = MailPoet.I18n.t('noSubscribers');
|
||||
} else {
|
||||
progress_bar_width = percentage;
|
||||
percentage += "%";
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ progressClasses }>
|
||||
<span
|
||||
className="mailpoet_progress_bar"
|
||||
style={ { width: percentage + "%"} }
|
||||
style={ { width: progress_bar_width + "%"} }
|
||||
></span>
|
||||
<span className="mailpoet_progress_label">
|
||||
{ percentage + "%" }
|
||||
{ percentage }
|
||||
</span>
|
||||
</div>
|
||||
<p style={{ textAlign:'center' }}>
|
||||
|
@ -68,7 +68,7 @@ const NewsletterListNotificationHistory = React.createClass({
|
||||
<a
|
||||
href={ newsletter.preview_url }
|
||||
target="_blank"
|
||||
>{ newsletter.subject }</a>
|
||||
>{ newsletter.queue.newsletter_rendered_subject }</a>
|
||||
</strong>
|
||||
{ actions }
|
||||
</td>
|
||||
|
@ -62,7 +62,7 @@ const _monthDayValues = _.object(
|
||||
} else {
|
||||
label = MailPoet.I18n.t('nth').replace("%$1d", day + 1);
|
||||
}
|
||||
return [day, label];
|
||||
return [day + 1, label];
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import _ from 'underscore'
|
||||
import React from 'react'
|
||||
import MailPoet from 'mailpoet'
|
||||
import Select from 'form/fields/select.jsx'
|
||||
import {
|
||||
intervalValues,
|
||||
|
@ -871,7 +871,7 @@ define(
|
||||
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||
+ MailPoet.I18n.t('emptyFirstRowDate')
|
||||
+ '</span>';
|
||||
+ '</span> ';
|
||||
preventNextStep = true;
|
||||
}
|
||||
else {
|
||||
@ -901,7 +901,7 @@ define(
|
||||
+ '<span class="mailpoet_data_match" title="'
|
||||
+ MailPoet.I18n.t('verifyDateMatch') + '">'
|
||||
+ MailPoet.Date.format(date)
|
||||
+ '</span>'
|
||||
+ '</span> '
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -910,7 +910,7 @@ define(
|
||||
+ '<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||
+ (new Handlebars.SafeString(MailPoet.I18n.t('dateMatchError')))
|
||||
+ '</span>'
|
||||
+ '</span> '
|
||||
);
|
||||
preventNextStep = true;
|
||||
};
|
||||
|
27
build.sh
@ -1,25 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Translations (npm install & composer install need to be run before)
|
||||
echo '[BUILD] Generating translations'
|
||||
./do makepot
|
||||
|
||||
plugin_name='mailpoet'
|
||||
|
||||
# Remove previous build.
|
||||
echo '[BUILD] Removing previous build'
|
||||
rm $plugin_name.zip
|
||||
|
||||
# Create temp dir.
|
||||
echo '[BUILD] Creating temporary directory'
|
||||
mkdir $plugin_name
|
||||
|
||||
# Production assets.
|
||||
echo '[BUILD] Generating production CSS and JS assets'
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
./do compile:all
|
||||
|
||||
# Production libraries.
|
||||
./composer.phar install --no-dev --prefer-dist --optimize-autoloader
|
||||
echo '[BUILD] Fetching production libraries'
|
||||
rm -rf vendor
|
||||
./composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-scripts
|
||||
|
||||
# Copy release folders.
|
||||
echo '[BUILD] Copying release folders'
|
||||
cp -Rf lang $plugin_name
|
||||
cp -RfL assets $plugin_name
|
||||
cp -Rf lib $plugin_name
|
||||
@ -29,12 +36,13 @@ rm -Rf $plugin_name/assets/css/src
|
||||
rm -Rf $plugin_name/assets/js/src
|
||||
|
||||
# Remove extra files (docs, examples,...) from 3rd party extensions
|
||||
echo '[BUILD] Removing obsolete files from vendor libraries'
|
||||
find $plugin_name/vendor -type f -regextype posix-egrep -iregex ".*\/*\.(markdown|md|txt)" -print0 | xargs -0 rm -f
|
||||
find $plugin_name/vendor -type f -regextype posix-egrep -iregex ".*\/(readme|license|version|changes|changelog)" -print0 | xargs -0 rm -f
|
||||
find $plugin_name/vendor -type d -regextype posix-egrep -iregex ".*\/(docs?|examples?|\.git)" -print0 | xargs -0 rm -rf
|
||||
|
||||
# Remove unit tests from 3rd party extensions
|
||||
rm $plugin_name/vendor/j4mie/idiorm/demo.php
|
||||
echo '[BUILD] Removing unit tests from vendor libraries'
|
||||
rm -rf $plugin_name/vendor/twig/twig/test
|
||||
rm -rf $plugin_name/vendor/symfony/translation/Tests
|
||||
rm -rf $plugin_name/vendor/phpmailer/phpmailer/test
|
||||
@ -43,18 +51,33 @@ rm -rf $plugin_name/vendor/mtdowling/cron-expression/tests
|
||||
rm -rf $plugin_name/vendor/swiftmailer/swiftmailer/tests
|
||||
rm -rf $plugin_name/vendor/cerdic/css-tidy/testing
|
||||
|
||||
# Remove risky files from 3rd party extensions
|
||||
echo '[BUILD] Removing risky and demo files from vendor libraries'
|
||||
rm -f $plugin_name/vendor/j4mie/idiorm/demo.php
|
||||
rm -f $plugin_name/vendor/cerdic/css-tidy/css_optimiser.php
|
||||
|
||||
# Copy release files.
|
||||
echo '[BUILD] Copying release files'
|
||||
cp license.txt $plugin_name
|
||||
cp index.php $plugin_name
|
||||
cp $plugin_name.php $plugin_name
|
||||
cp readme.txt $plugin_name
|
||||
cp uninstall.php $plugin_name
|
||||
|
||||
# Add index files if they don't exist to all folders
|
||||
echo '[BUILD] Adding index files to all project folders'
|
||||
find $plugin_name -type d -exec touch {}/index.php \;
|
||||
|
||||
# Zip final release.
|
||||
echo '[BUILD] Creating final release zip'
|
||||
zip -r $plugin_name.zip $plugin_name
|
||||
|
||||
# Remove temp dir.
|
||||
echo '[BUILD] Removing temp directory'
|
||||
rm -rf $plugin_name
|
||||
|
||||
# Reinstall dev dependencies.
|
||||
echo '[BUILD] Reinstalling dev dependencies'
|
||||
./composer.phar install
|
||||
|
||||
echo '[BUILD] Build finished!'
|
||||
|
@ -17,7 +17,8 @@ dependencies:
|
||||
- sudo a2enmod rewrite
|
||||
- sudo service apache2 restart
|
||||
# install Phoenix dependencies
|
||||
- composer install
|
||||
- curl -sS https://getcomposer.org/installer | php
|
||||
- ./composer.phar install
|
||||
- ./do install
|
||||
# Set up Wordpress
|
||||
# No password is required for the MySQL user `ubuntu`
|
||||
@ -46,6 +47,10 @@ dependencies:
|
||||
## tests override
|
||||
test:
|
||||
override:
|
||||
# Add default timezone to PHP's configuration (required for PHP >=5.4)
|
||||
- echo "date.timezone = UTC" > /opt/circleci/php/$(phpenv global)/etc/conf.d/date.ini
|
||||
# Run QA scripts
|
||||
- ./do qa
|
||||
# Run JS tests
|
||||
- mkdir $CIRCLE_TEST_REPORTS/mocha
|
||||
- ./do t:j $CIRCLE_TEST_REPORTS/mocha/junit.xml
|
||||
|
@ -27,6 +27,7 @@ coverage:
|
||||
include:
|
||||
- lib/*
|
||||
exclude:
|
||||
- lib/Config/PopulatorData/*
|
||||
- lib/Util/Sudzy/*
|
||||
- lib/Util/CSS.php
|
||||
- lib/Util/Helpers.php
|
||||
|
@ -8,13 +8,10 @@
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"twig/twig": "1.*",
|
||||
"phpmailer/phpmailer": "~5.2",
|
||||
"cerdic/css-tidy": "*",
|
||||
"sunra/php-simple-html-dom-parser": "*",
|
||||
"tburry/pquery": "*",
|
||||
"j4mie/paris": "1.5.4",
|
||||
"swiftmailer/swiftmailer": "^5.4",
|
||||
"phpseclib/phpseclib": "*",
|
||||
"mtdowling/cron-expression": "^1.1",
|
||||
"nesbot/carbon": "^1.21",
|
||||
"soundasleep/html2text": "dev-master"
|
||||
@ -26,12 +23,18 @@
|
||||
"vlucas/phpdotenv": "*",
|
||||
"umpirsky/twig-gettext-extractor": "1.1.*",
|
||||
"raveren/kint": "^1.0",
|
||||
"squizlabs/php_codesniffer": "2.*"
|
||||
"squizlabs/php_codesniffer": "*",
|
||||
"wimg/php-compatibility": "*",
|
||||
"simplyadmire/composer-plugins" : "@dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MailPoet\\": "lib/",
|
||||
"Sudzy\\": "lib/Util/Sudzy"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-update-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility",
|
||||
"post-install-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility"
|
||||
}
|
||||
}
|
||||
}
|
841
composer.lock
generated
@ -73,7 +73,7 @@ class Subscribers extends APIEndpoint {
|
||||
|
||||
if(empty($segment_ids)) {
|
||||
return $this->badRequest(array(
|
||||
APIError::BAD_REQUEST => __('Please select a list', 'mailpoet')
|
||||
APIError::BAD_REQUEST => __('Please select a list.', 'mailpoet')
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ class Env {
|
||||
static $db_password;
|
||||
static $db_charset;
|
||||
static $db_timezone_offset;
|
||||
static $subscribers_limit = 2000;
|
||||
|
||||
static function init($file, $version) {
|
||||
global $wpdb;
|
||||
@ -39,11 +38,11 @@ class Env {
|
||||
self::$assets_path = self::$path . '/assets';
|
||||
self::$assets_url = plugins_url('/assets', $file);
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
self::$temp_path = $wp_upload_dir['basedir'].'/'.self::$plugin_name;
|
||||
self::$temp_path = $wp_upload_dir['basedir'] . '/' . self::$plugin_name;
|
||||
if(!is_dir(self::$temp_path)) {
|
||||
mkdir(self::$temp_path);
|
||||
}
|
||||
self::$temp_url = $wp_upload_dir['baseurl'].'/'.self::$plugin_name;
|
||||
self::$temp_url = $wp_upload_dir['baseurl'] . '/' . self::$plugin_name;
|
||||
self::$languages_path = self::$path . '/lang';
|
||||
self::$lib_path = self::$path . '/lib';
|
||||
self::$plugin_prefix = 'mailpoet_';
|
||||
|
@ -4,6 +4,7 @@ namespace MailPoet\Config;
|
||||
use MailPoet\Cron\CronTrigger;
|
||||
use MailPoet\Router;
|
||||
use MailPoet\API;
|
||||
use MailPoet\Util\License\License as License;
|
||||
use MailPoet\WP\Notice as WPNotice;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -116,6 +117,7 @@ class Initializer {
|
||||
|
||||
function onInit() {
|
||||
if(!$this->plugin_initialized) {
|
||||
define('MAILPOET_INITIALIZED', false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,6 +128,8 @@ class Initializer {
|
||||
} catch(\Exception $e) {
|
||||
$this->handleFailedInitialization($e);
|
||||
}
|
||||
|
||||
define('MAILPOET_INITIALIZED', true);
|
||||
}
|
||||
|
||||
function setupWidget() {
|
||||
@ -142,8 +146,9 @@ class Initializer {
|
||||
}
|
||||
|
||||
function setupRenderer() {
|
||||
$renderer = new Renderer();
|
||||
$this->renderer = $renderer->init();
|
||||
$caching = !WP_DEBUG;
|
||||
$debugging = WP_DEBUG;
|
||||
$this->renderer = new Renderer($caching, $debugging);
|
||||
}
|
||||
|
||||
function setupLocalizer() {
|
||||
|
@ -14,7 +14,9 @@ use MailPoet\Settings\Hosts;
|
||||
use MailPoet\Settings\Pages;
|
||||
use MailPoet\Subscribers\ImportExport\ImportExportFactory;
|
||||
use MailPoet\Listing;
|
||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||
use MailPoet\WP\DateTime;
|
||||
use MailPoet\WP\Notice as WPNotice;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -22,6 +24,8 @@ class Menu {
|
||||
function __construct($renderer, $assets_url) {
|
||||
$this->renderer = $renderer;
|
||||
$this->assets_url = $assets_url;
|
||||
$subscribers_feature = new SubscribersFeature();
|
||||
$this->subscribers_over_limit = $subscribers_feature->check();
|
||||
}
|
||||
|
||||
function init() {
|
||||
@ -34,16 +38,6 @@ class Menu {
|
||||
);
|
||||
}
|
||||
|
||||
function checkSubscribersLimit() {
|
||||
$subscribers_count = Subscriber::getTotalSubscribers();
|
||||
if($subscribers_count > Env::$subscribers_limit) {
|
||||
echo $this->renderer->render('limit.html', array(
|
||||
'limit' => Env::$subscribers_limit
|
||||
));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function setup() {
|
||||
$main_page_slug = 'mailpoet-newsletters';
|
||||
|
||||
@ -59,8 +53,8 @@ class Menu {
|
||||
|
||||
$newsletters_page = add_submenu_page(
|
||||
$main_page_slug,
|
||||
$this->setPageTitle(__('Newsletters', 'mailpoet')),
|
||||
__('Newsletters', 'mailpoet'),
|
||||
$this->setPageTitle(__('Emails', 'mailpoet')),
|
||||
__('Emails', 'mailpoet'),
|
||||
'manage_options',
|
||||
$main_page_slug,
|
||||
array($this, 'newsletters')
|
||||
@ -222,7 +216,7 @@ class Menu {
|
||||
'redirect_url' => $redirect_url,
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
);
|
||||
echo $this->renderer->render('welcome.html', $data);
|
||||
$this->displayPage('welcome.html', $data);
|
||||
}
|
||||
|
||||
function update() {
|
||||
@ -248,11 +242,11 @@ class Menu {
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
);
|
||||
|
||||
echo $this->renderer->render('update.html', $data);
|
||||
$this->displayPage('update.html', $data);
|
||||
}
|
||||
|
||||
function settings() {
|
||||
$this->checkSubscribersLimit();
|
||||
if ($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
|
||||
|
||||
$settings = Setting::getAll();
|
||||
$flags = $this->_getFlags();
|
||||
@ -270,7 +264,7 @@ class Menu {
|
||||
)
|
||||
);
|
||||
|
||||
echo $this->renderer->render('settings.html', $data);
|
||||
$this->displayPage('settings.html', $data);
|
||||
}
|
||||
|
||||
private function _getFlags() {
|
||||
@ -322,30 +316,30 @@ class Menu {
|
||||
$data['date_formats'] = Block\Date::getDateFormats();
|
||||
$data['month_names'] = Block\Date::getMonthNames();
|
||||
|
||||
echo $this->renderer->render('subscribers/subscribers.html', $data);
|
||||
$this->displayPage('subscribers/subscribers.html', $data);
|
||||
}
|
||||
|
||||
function segments() {
|
||||
$this->checkSubscribersLimit();
|
||||
if ($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
|
||||
|
||||
$data = array();
|
||||
$data['items_per_page'] = $this->getLimitPerPage('segments');
|
||||
echo $this->renderer->render('segments.html', $data);
|
||||
$this->displayPage('segments.html', $data);
|
||||
}
|
||||
|
||||
function forms() {
|
||||
$this->checkSubscribersLimit();
|
||||
if ($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
|
||||
|
||||
$data = array();
|
||||
|
||||
$data['items_per_page'] = $this->getLimitPerPage('forms');
|
||||
$data['segments'] = Segment::findArray();
|
||||
|
||||
echo $this->renderer->render('forms.html', $data);
|
||||
$this->displayPage('forms.html', $data);
|
||||
}
|
||||
|
||||
function newsletters() {
|
||||
$this->checkSubscribersLimit();
|
||||
if ($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
|
||||
|
||||
global $wp_roles;
|
||||
|
||||
@ -371,7 +365,7 @@ class Menu {
|
||||
wp_enqueue_script('jquery-ui');
|
||||
wp_enqueue_script('jquery-ui-datepicker');
|
||||
|
||||
echo $this->renderer->render('newsletters.html', $data);
|
||||
$this->displayPage('newsletters.html', $data);
|
||||
}
|
||||
|
||||
function newletterEditor() {
|
||||
@ -384,7 +378,7 @@ class Menu {
|
||||
wp_enqueue_media();
|
||||
wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
|
||||
wp_enqueue_style('editor', includes_url('css/editor.css'));
|
||||
echo $this->renderer->render('newsletter/editor.html', $data);
|
||||
$this->displayPage('newsletter/editor.html', $data);
|
||||
}
|
||||
|
||||
function import() {
|
||||
@ -396,14 +390,14 @@ class Menu {
|
||||
'month_names' => Block\Date::getMonthNames(),
|
||||
'sub_menu' => 'mailpoet-subscribers'
|
||||
));
|
||||
echo $this->renderer->render('subscribers/importExport/import.html', $data);
|
||||
$this->displayPage('subscribers/importExport/import.html', $data);
|
||||
}
|
||||
|
||||
function export() {
|
||||
$export = new ImportExportFactory('export');
|
||||
$data = $export->bootstrap();
|
||||
$data['sub_menu'] = 'mailpoet-subscribers';
|
||||
echo $this->renderer->render('subscribers/importExport/export.html', $data);
|
||||
$this->displayPage('subscribers/importExport/export.html', $data);
|
||||
}
|
||||
|
||||
function formEditor() {
|
||||
@ -424,7 +418,7 @@ class Menu {
|
||||
'sub_menu' => 'mailpoet-forms'
|
||||
);
|
||||
|
||||
echo $this->renderer->render('form/editor.html', $data);
|
||||
$this->displayPage('form/editor.html', $data);
|
||||
}
|
||||
|
||||
function setPageTitle($title) {
|
||||
@ -435,6 +429,13 @@ class Menu {
|
||||
);
|
||||
}
|
||||
|
||||
function displaySubscriberLimitExceededTemplate() {
|
||||
$this->displayPage('limit.html', array(
|
||||
'limit' => SubscribersFeature::SUBSCRIBERS_LIMIT
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
private function getLimitPerPage($model = null) {
|
||||
if($model === null) {
|
||||
return Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
|
||||
@ -447,4 +448,13 @@ class Menu {
|
||||
? (int)$listing_per_page
|
||||
: Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
|
||||
}
|
||||
|
||||
private function displayPage($template, $data) {
|
||||
try {
|
||||
echo $this->renderer->render($template, $data);
|
||||
} catch (\Exception $e) {
|
||||
$notice = new WPNotice(WPNotice::TYPE_ERROR, $e->getMessage());
|
||||
$notice->displayWPNotice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,9 @@ class Migrator {
|
||||
function down() {
|
||||
global $wpdb;
|
||||
|
||||
$drop_table = function($model) use($wpdb) {
|
||||
$table = $this->prefix . $model;
|
||||
$_this = $this;
|
||||
$drop_table = function($model) use($wpdb, $_this) {
|
||||
$table = $_this->prefix . $model;
|
||||
$wpdb->query("DROP TABLE {$table}");
|
||||
};
|
||||
|
||||
@ -133,6 +134,9 @@ class Migrator {
|
||||
'last_name tinytext NOT NULL DEFAULT "",',
|
||||
'email varchar(150) NOT NULL,',
|
||||
'status varchar(12) NOT NULL DEFAULT "' . Subscriber::STATUS_UNCONFIRMED . '",',
|
||||
'subscribed_ip varchar(32) NULL,',
|
||||
'confirmed_ip varchar(32) NULL,',
|
||||
'confirmed_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
|
@ -211,13 +211,12 @@ class Populator {
|
||||
$modelMethod = Helpers::underscoreToCamelCase($model);
|
||||
$rows = $this->$modelMethod();
|
||||
$table = $this->prefix . $model;
|
||||
$_this = $this;
|
||||
|
||||
array_map(function($row) use ($_this, $table) {
|
||||
if(!$_this->rowExists($table, $row)) {
|
||||
$_this->insertRow($table, $row);
|
||||
foreach($rows as $row) {
|
||||
if(!$this->rowExists($table, $row)) {
|
||||
$this->insertRow($table, $row);
|
||||
}
|
||||
}, $rows);
|
||||
}
|
||||
}
|
||||
|
||||
private function rowExists($table, $columns) {
|
||||
|
@ -88,7 +88,7 @@ class FranksRoastHouseTemplate {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>Hi there [subscriber:firstname | default:coffee drinker]</p>\n<p></p>\n<p>Sit back and enjoy your favorite roast as you read this week's newsletter. </p>", 'mailpoet')
|
||||
"text" => __("<p>Hi there [subscriber:firstname | default:coffee drinker]</p>\n<p></p>\n<p>Sit back and enjoy your favorite roast as you read this week's newsletter. </p>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "image",
|
||||
@ -106,7 +106,7 @@ class FranksRoastHouseTemplate {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\">--- Guest Coffee Roaster: <em>Brew Bros. ---</em></h1>\n<p><em></em></p>\n<p>Visit our Center Avenue store to try the latest guest coffee from Brew Bros, a local coffee roaster. This young duo started only two years ago, but have quickly gained popularity through pop-up shops, local events, and collaborations with food trucks.</p>\n<p></p>\n<blockquote>\n<p><span style=\"color: #ff6600;\"><em>Tasting notes: A rich, caramel flavor with subtle hints of molasses. The perfect wake-up morning espresso!</em></span></p>\n</blockquote>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\">--- Guest Coffee Roaster: <em>Brew Bros. ---</em></h1>\n<p><em></em></p>\n<p>Visit our Center Avenue store to try the latest guest coffee from Brew Bros, a local coffee roaster. This young duo started only two years ago, but have quickly gained popularity through pop-up shops, local events, and collaborations with food trucks.</p>\n<p></p>\n<blockquote>\n<p><span style=\"color: #ff6600;\"><em>Tasting notes: A rich, caramel flavor with subtle hints of molasses. The perfect wake-up morning espresso!</em></span></p>\n</blockquote>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -250,7 +250,7 @@ class FranksRoastHouseTemplate {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>Watch out Broad Street, we're coming to you very soon! </p>\n<p></p>\n<p>Keep an eye on your inbox, as we'll have some special offers for our email subscribers plus an exclusive launch party invite!<br /><br /></p>", 'mailpoet')
|
||||
"text" => __("<p>Watch out Broad Street, we're coming to you very soon! </p>\n<p></p>\n<p>Keep an eye on your inbox, as we'll have some special offers for our email subscribers plus an exclusive launch party invite!<br /><br /></p>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
|
@ -52,7 +52,7 @@ class NewsletterBlank121Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class NewsletterBlank121Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started!</strong></h1>\n<p>It's time to design your newsletter! On the right sidebar, you'll find four menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started!</strong></h1>\n<p>It's time to design your newsletter! On the right sidebar, you'll find four menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "divider",
|
||||
@ -158,7 +158,7 @@ class NewsletterBlank121Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>In the right sidebar, you can add layout blocks to your email:</p>\n<ul>\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
"text" => __("<p>In the right sidebar, you can add layout blocks to your email:</p>\n<ul>\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
),
|
||||
@ -177,7 +177,7 @@ class NewsletterBlank121Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>You can change a layout's background color by clicking on the settings icon on the right edge of the Designer. Simply hover over this area to see the Settings (gear) icon.</p>", 'mailpoet')
|
||||
"text" => __("<p>You can change a layout's background color by clicking on the settings icon on the right edge of the Designer. Simply hover over this area to see the Settings (gear) icon.</p>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -237,7 +237,7 @@ class NewsletterBlank121Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h3 style=\"text-align: center;\"><span style=\"font-weight: 600;\">Let's end with a single column. </span></h3>\n<p style=\"line-height: 25.6px;\">In the right sidebar, you can add these layout blocks to your email:</p>\n<p style=\"line-height: 25.6px;\"></p>\n<ul style=\"line-height: 25.6px;\">\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
"text" => __("<h3 style=\"text-align: center;\"><span style=\"font-weight: 600;\">Let's end with a single column. </span></h3>\n<p style=\"line-height: 25.6px;\">In the right sidebar, you can add these layout blocks to your email:</p>\n<p style=\"line-height: 25.6px;\"></p>\n<ul style=\"line-height: 25.6px;\">\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ class NewsletterBlank12Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class NewsletterBlank12Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started!</strong></h1>\n<p></p>\n<p>It's time to design your newsletter! In the right sidebar, you'll find 4 menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started!</strong></h1>\n<p></p>\n<p>It's time to design your newsletter! In the right sidebar, you'll find 4 menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "divider",
|
||||
@ -158,7 +158,7 @@ class NewsletterBlank12Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>In the right sidebar, you can add these layout blocks to your email:</p>\n<ul>\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
"text" => __("<p>In the right sidebar, you can add these layout blocks to your email:</p>\n<ul>\n<li>1 column</li>\n<li>2 columns</li>\n<li>3 columns</li>\n</ul>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
),
|
||||
@ -177,7 +177,7 @@ class NewsletterBlank12Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p><span style=\"line-height: 25.6px;\">You can change a layout's background color by clicking on the settings icon on the right edge of the Designer. Simply hover over this area to see the Settings (gear) icon.</span></p>", 'mailpoet')
|
||||
"text" => __("<p><span style=\"line-height: 25.6px;\">You can change a layout's background color by clicking on the settings icon on the right edge of the Designer. Simply hover over this area to see the Settings (gear) icon.</span></p>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ class NewsletterBlank13Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class NewsletterBlank13Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started! </strong></h1>\n<p></p>\n<p>It's time to design your newsletter! On the right sidebar, you'll find four menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started! </strong></h1>\n<p></p>\n<p>It's time to design your newsletter! On the right sidebar, you'll find four menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "divider",
|
||||
@ -154,11 +154,11 @@ class NewsletterBlank13Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h3>This template... </h3>", 'mailpoet')
|
||||
"text" => __("<h3>This template... </h3>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>In the right sidebar, you can add layout blocks to your newsletter.</p>", 'mailpoet')
|
||||
"text" => __("<p>In the right sidebar, you can add layout blocks to your newsletter.</p>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
),
|
||||
@ -173,7 +173,7 @@ class NewsletterBlank13Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h3>... has a... </h3>", 'mailpoet')
|
||||
"text" => __("<h3>... has a... </h3>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
|
@ -52,7 +52,7 @@ class NewsletterBlank1Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class NewsletterBlank1Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started! </strong></h1>\n<p></p>\n<p>It's time to design your newsletter! In the right sidebar, you'll find 4 menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Let's Get Started! </strong></h1>\n<p></p>\n<p>It's time to design your newsletter! In the right sidebar, you'll find 4 menu items that will help you customize your newsletter:</p>\n<ol>\n<li>Content</li>\n<li>Layout</li>\n<li>Styles</li>\n<li>Preview</li>\n</ol>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ class PostNotificationsBlank1Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class PostNotificationsBlank1Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Check Out Our New Blog Posts! </strong></h1>\n<p></p>\n<p>MailPoet can <span style=\"line-height: 1.6em; background-color: inherit;\"><em>automatically</em> </span><span style=\"line-height: 1.6em; background-color: inherit;\">send your new blog posts to your subscribers.</span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\"></span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\">Below, you'll find three recent posts, which are displayed automatically, thanks to the <em>Automatic Latest Content</em> widget, which can be found on the right sidebar, under <em>Content</em>.</span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\"></span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\">To edit the settings and styles of your post, simply click on a post below.</span></p>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Check Out Our New Blog Posts! </strong></h1>\n<p></p>\n<p>MailPoet can <span style=\"line-height: 1.6em; background-color: inherit;\"><em>automatically</em> </span><span style=\"line-height: 1.6em; background-color: inherit;\">send your new blog posts to your subscribers.</span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\"></span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\">Below, you'll find three recent posts, which are displayed automatically, thanks to the <em>Automatic Latest Content</em> widget, which can be found on the right sidebar, under <em>Content</em>.</span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\"></span></p>\n<p><span style=\"line-height: 1.6em; background-color: inherit;\">To edit the settings and styles of your post, simply click on a post below.</span></p>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "divider",
|
||||
|
@ -332,7 +332,7 @@ class Restaurant {
|
||||
))
|
||||
), array(
|
||||
"type" => "header",
|
||||
"text" => "<p><a href=\"[link:newsletter_view_in_browser_url]\">View this email in your web browser</a></p>",
|
||||
"text" => "<p><a href=\"[link:newsletter_view_in_browser_url]\">View this email in your web browser</a></p>",
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
|
@ -75,7 +75,7 @@ class SimpleText {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p style=\"text-align: left;\">Hi [subscriber:firstname | default:subscriber],</p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">In MailPoet, you can write emails in plain text, just like in a regular email. This can make your email newsletters more personal and attention-grabbing.</p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">Is this too simple? You can still style your text with basic formatting, like <strong>bold</strong> or <em>italics.</em></p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">Finally, you can also add a call-to-action button between 2 blocks of text, like this:</p>", 'mailpoet')
|
||||
"text" => __("<p style=\"text-align: left;\">Hi [subscriber:firstname | default:subscriber],</p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">In MailPoet, you can write emails in plain text, just like in a regular email. This can make your email newsletters more personal and attention-grabbing.</p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">Is this too simple? You can still style your text with basic formatting, like <strong>bold</strong> or <em>italics.</em></p>\n<p style=\"text-align: left;\"></p>\n<p style=\"text-align: left;\">Finally, you can also add a call-to-action button between 2 blocks of text, like this:</p>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -131,7 +131,7 @@ class SimpleText {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>Thanks for reading. See you soon!</p>\n<p></p>\n<p><strong><em>The MailPoet Team</em></strong></p>", 'mailpoet')
|
||||
"text" => __("<p>Thanks for reading. See you soon!</p>\n<p></p>\n<p><strong><em>The MailPoet Team</em></strong></p>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "footer",
|
||||
|
@ -70,7 +70,7 @@ class StoreDiscount {
|
||||
)
|
||||
), array(
|
||||
"type" => "text",
|
||||
"text" => __("<p></p>\n<p>Hi [subscriber:firstname | default:reader]</p>\n<p class=\"\"></p>\n<p>Fancy 15% off your next order? Use this coupon on all your favourite products from our store until Wednesday. Just enter the code on the payments page and your discount will applied.</p>", 'mailpoet')
|
||||
"text" => __("<p></p>\n<p>Hi [subscriber:firstname | default:reader]</p>\n<p class=\"\"></p>\n<p>Fancy 15% off your next order? Use this coupon on all your favourite products from our store until Wednesday. Just enter the code on the payments page and your discount will applied.</p>", 'mailpoet')
|
||||
), array(
|
||||
"type" => "spacer",
|
||||
"styles" => array(
|
||||
@ -173,7 +173,7 @@ class StoreDiscount {
|
||||
)
|
||||
), array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong><em>Use your discount on these great products...</em></strong></h1>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong><em>Use your discount on these great products...</em></strong></h1>", 'mailpoet')
|
||||
), array(
|
||||
"type" => "spacer",
|
||||
"styles" => array(
|
||||
|
@ -70,7 +70,7 @@ class TravelEmail {
|
||||
)
|
||||
), array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\">Hi [subscriber:firstname | default:reader]!</h1>\n<p></p>\n<p>Greetings from New Zealand, we're here enjoying the sights and sounds (and bad smells!) of Rotarua. Yesterday we took advantage of the local amenities and visited the hot springs! </p>\n<p>Don't forget to stay up-to-date via twitter!</p>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\">Hi [subscriber:firstname | default:reader]!</h1>\n<p></p>\n<p>Greetings from New Zealand, we're here enjoying the sights and sounds (and bad smells!) of Rotarua. Yesterday we took advantage of the local amenities and visited the hot springs! </p>\n<p>Don't forget to stay up-to-date via twitter!</p>", 'mailpoet')
|
||||
), array(
|
||||
"type" => "social",
|
||||
"iconSet" => "circles",
|
||||
@ -414,7 +414,7 @@ class TravelEmail {
|
||||
)
|
||||
), array(
|
||||
"type" => "text",
|
||||
"text" => __("<p>Tomorrow we're heading towards Taupo where we'll visit the 'Craters of the moon' and go prawn fishing! Hopefully the weather will stay good.</p>\n<p></p>\n<p>Keep on travellin'</p>\n<p>Jane & Steven</p>", 'mailpoet')
|
||||
"text" => __("<p>Tomorrow we're heading towards Taupo where we'll visit the 'Craters of the moon' and go prawn fishing! Hopefully the weather will stay good.</p>\n<p></p>\n<p>Keep on travellin'</p>\n<p>Jane & Steven</p>", 'mailpoet')
|
||||
))
|
||||
))
|
||||
), array(
|
||||
@ -446,7 +446,7 @@ class TravelEmail {
|
||||
)
|
||||
), array(
|
||||
"type" => "header",
|
||||
"text" => ("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>"),
|
||||
"text" => ("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>"),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
|
@ -52,7 +52,7 @@ class WelcomeBlank12Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class WelcomeBlank12Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Hi, new subscriber!</strong></h1>\n<p></p>\n<p>[subscriber:firstname | default:Subscriber],</p>\n<p></p>\n<p>You recently joined our list and we'd like to give you a warm welcome!</p>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Hi, new subscriber!</strong></h1>\n<p></p>\n<p>[subscriber:firstname | default:Subscriber],</p>\n<p></p>\n<p>You recently joined our list and we'd like to give you a warm welcome!</p>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "divider",
|
||||
@ -182,7 +182,7 @@ class WelcomeBlank12Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h3>What's Next?</h3>", 'mailpoet')
|
||||
"text" => __("<h3>What's Next?</h3>", 'mailpoet')
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
|
@ -52,7 +52,7 @@ class WelcomeBlank1Column {
|
||||
"blocks" => array(
|
||||
array(
|
||||
"type" => "header",
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"text" => __("Display problems? <a href=\"[link:newsletter_view_in_browser_url]\">Open this email in your web browser</a>", 'mailpoet'),
|
||||
"styles" => array(
|
||||
"block" => array(
|
||||
"backgroundColor" => "transparent"
|
||||
@ -116,7 +116,7 @@ class WelcomeBlank1Column {
|
||||
),
|
||||
array(
|
||||
"type" => "text",
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Hi, new subscriber!</strong></h1>\n<p></p>\n<p>[subscriber:firstname | default:Subscriber],</p>\n<p></p>\n<p>You recently joined our list and we'd like to give you a warm welcome!</p>\n<p></p>\n<p>Want to get to know us better? Check out some of our most popular articles: </p>\n<ol>\n<li><a href=\"http://www.mailpoet.com/the-importance-of-focus-when-writing/\">The Importance of Focus When Writing</a></li>\n<li><a href=\"http://www.mailpoet.com/write-great-subject-line/\">How to Write a Great Subject Line</a></li>\n<li><a href=\"http://www.mailpoet.com/just-sit-write-advice-motivation-ernest-hemingway/\">Just Sit Down and Write – Advice on Motivation from Ernest Hemingway</a></li>\n</ol>", 'mailpoet')
|
||||
"text" => __("<h1 style=\"text-align: center;\"><strong>Hi, new subscriber!</strong></h1>\n<p></p>\n<p>[subscriber:firstname | default:Subscriber],</p>\n<p></p>\n<p>You recently joined our list and we'd like to give you a warm welcome!</p>\n<p></p>\n<p>Want to get to know us better? Check out some of our most popular articles: </p>\n<ol>\n<li><a href=\"http://www.mailpoet.com/the-importance-of-focus-when-writing/\">The Importance of Focus When Writing</a></li>\n<li><a href=\"http://www.mailpoet.com/write-great-subject-line/\">How to Write a Great Subject Line</a></li>\n<li><a href=\"http://www.mailpoet.com/just-sit-write-advice-motivation-ernest-hemingway/\">Just Sit Down and Write – Advice on Motivation from Ernest Hemingway</a></li>\n</ol>", 'mailpoet')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -8,27 +8,33 @@ use \MailPoet\Twig;
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Renderer {
|
||||
function __construct() {
|
||||
protected $cache_path;
|
||||
protected $caching_enabled;
|
||||
protected $debugging_enabled;
|
||||
protected $renderer;
|
||||
|
||||
function __construct($caching_enabled = false, $debugging_enabled = false) {
|
||||
$this->caching_enabled = $caching_enabled;
|
||||
$this->debugging_enabled = $debugging_enabled;
|
||||
$this->cache_path = Env::$temp_path . '/cache';
|
||||
|
||||
$file_system = new TwigFileSystem(Env::$views_path);
|
||||
$this->renderer = new TwigEnv(
|
||||
$file_system,
|
||||
array(
|
||||
'cache' => $this->detectCache(),
|
||||
'debug' => WP_DEBUG,
|
||||
'debug' => $this->debugging_enabled,
|
||||
'auto_reload' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function init() {
|
||||
$this->setupDebug();
|
||||
$this->setupTranslations();
|
||||
$this->setupFunctions();
|
||||
$this->setupHandlebars();
|
||||
$this->setupHelpscout();
|
||||
$this->setupGlobalVariables();
|
||||
$this->setupSyntax();
|
||||
|
||||
return $this->renderer;
|
||||
}
|
||||
|
||||
function setupTranslations() {
|
||||
@ -43,6 +49,10 @@ class Renderer {
|
||||
$this->renderer->addExtension(new Twig\Handlebars());
|
||||
}
|
||||
|
||||
function setupHelpscout() {
|
||||
$this->renderer->addExtension(new Twig\Helpscout());
|
||||
}
|
||||
|
||||
function setupGlobalVariables() {
|
||||
$this->renderer->addExtension(new Twig\Assets(array(
|
||||
'assets_url' => Env::$assets_url,
|
||||
@ -61,16 +71,30 @@ class Renderer {
|
||||
}
|
||||
|
||||
function detectCache() {
|
||||
$cache_path = Env::$temp_path . '/cache';
|
||||
if(WP_DEBUG === false) {
|
||||
return $cache_path;
|
||||
}
|
||||
return false;
|
||||
return $this->caching_enabled ? $this->cache_path : false;
|
||||
}
|
||||
|
||||
function setupDebug() {
|
||||
if(WP_DEBUG === true) {
|
||||
if($this->debugging_enabled) {
|
||||
$this->renderer->addExtension(new \Twig_Extension_Debug());
|
||||
}
|
||||
}
|
||||
|
||||
function render($template, $context = array()) {
|
||||
try {
|
||||
return $this->renderer->render($template, $context);
|
||||
} catch(\RuntimeException $e) {
|
||||
throw new \Exception(sprintf(
|
||||
__('Failed to render template "%s". Please ensure the template cache folder "%s" exists and has write permissions. Terminated with error: "%s"'),
|
||||
$template,
|
||||
$this->cache_path,
|
||||
$e->getMessage()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addGlobal($key, $value) {
|
||||
return $this->renderer->addGlobal($key, $value);
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,11 @@ class Widget {
|
||||
)
|
||||
);
|
||||
|
||||
echo $this->renderer->render('form/iframe.html', $data);
|
||||
try {
|
||||
echo $this->renderer->render('form/iframe.html', $data);
|
||||
} catch(\Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
@ -25,8 +25,7 @@ class Newsletter {
|
||||
if(!$newsletter) {
|
||||
return false;
|
||||
}
|
||||
// if the newsletter was previously rendered, return it
|
||||
// otherwise, process/render it
|
||||
// return the newsletter if it was previously rendered
|
||||
if(!is_null($queue->getNewsletterRenderedBody())) {
|
||||
return $newsletter;
|
||||
}
|
||||
@ -34,7 +33,7 @@ class Newsletter {
|
||||
if($this->tracking_enabled) {
|
||||
// hook to the newsletter post-processing filter and add tracking image
|
||||
$this->tracking_image_inserted = OpenTracking::addTrackingImage();
|
||||
// render newsletter and save its
|
||||
// render newsletter
|
||||
$rendered_newsletter = $newsletter->render();
|
||||
// hash and save all links
|
||||
$rendered_newsletter = LinksTask::process($rendered_newsletter, $newsletter, $queue);
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoet\Form\Util;
|
||||
use MailPoet\Form\Widget;
|
||||
use MailPoet\Config\Env;
|
||||
|
||||
class Export {
|
||||
static function getAll($form = null) {
|
||||
@ -41,39 +42,50 @@ class Export {
|
||||
case 'php':
|
||||
$output = array(
|
||||
'$form_widget = new \MailPoet\Form\Widget();',
|
||||
'echo $form_widget->widget(array(\'form\' => '.(int)$form['id'].', \'form_type\' => \'php\'));'
|
||||
'echo $form_widget->widget(array(\'form\' => '.
|
||||
(int)$form['id'].
|
||||
', \'form_type\' => \'php\'));'
|
||||
);
|
||||
return join("\n", $output);
|
||||
|
||||
case 'html':
|
||||
// TODO: get locale setting in order to load translations
|
||||
$wp_locale = \get_locale();
|
||||
|
||||
$output = array();
|
||||
|
||||
$output[] = '<!-- BEGIN Scripts : you should place them in the header of your theme -->';
|
||||
$output[] = '<!-- '.
|
||||
__(
|
||||
'BEGIN Scripts: you should place them in the header of your theme',
|
||||
'mailpoet'
|
||||
).
|
||||
' -->';
|
||||
|
||||
// jQuery
|
||||
$output[] = '<script type="text/javascript" src="'.includes_url().'js/jquery/jquery.js'.'?mpv='.MAILPOET_VERSION.'"></script>';
|
||||
// CSS
|
||||
$output[] = '<link rel="stylesheet" type="text/css" href="'.
|
||||
Env::$assets_url.'/css/public.css?mp_ver='.MAILPOET_VERSION.
|
||||
'" />';
|
||||
|
||||
// (JS) form validation
|
||||
$output[] = '<script type="text/javascript" src="'.plugins_url('wysija-newsletters/'.'lib/jquery.validationEngine.js?mpv='.MAILPOET_VERSION).'"></script>';
|
||||
$output[] = '<script type="text/javascript" src="'.plugins_url('wysija-newsletters/'.'lib/jquery.validationEngine-en.js?mpv='.MAILPOET_VERSION).'"></script>';
|
||||
// jQuery
|
||||
$output[] = '<script type="text/javascript" src="'.
|
||||
includes_url().'js/jquery/jquery.js?mp_ver'.MAILPOET_VERSION.
|
||||
'"></script>';
|
||||
|
||||
// (CSS) form validation styles
|
||||
$output[] = '<link rel="stylesheet" type="text/css" href="'.plugins_url('wysija-newsletters/'.'lib/validationEngine.jquery.css?mpv='.MAILPOET_VERSION).'">';
|
||||
// JS
|
||||
$output[] = '<script type="text/javascript" src="'.
|
||||
Env::$assets_url.'/js/vendor.js?mp_ver='.MAILPOET_VERSION.
|
||||
'"></script>';
|
||||
$output[] = '<script type="text/javascript" src="'.
|
||||
Env::$assets_url.'/js/public.js?mp_ver='.MAILPOET_VERSION.
|
||||
'"></script>';
|
||||
|
||||
// (JS) form submission
|
||||
$output[] = '<script type="text/javascript" src="'.plugins_url('wysija-newsletters/'.'www/mailpoet_form_subscribe.js?mpv='.MAILPOET_VERSION).'"></script>';
|
||||
|
||||
// (JS) variables...
|
||||
// (JS) variables...
|
||||
$output[] = '<script type="text/javascript">';
|
||||
$output[] = ' var MailPoetData = MailPoetData || {';
|
||||
$output[] = ' var MailPoetForm = MailPoetForm || {';
|
||||
$output[] = ' is_rtl: '.((int)is_rtl()).",";
|
||||
$output[] = ' ajax_url: "'.admin_url('admin-ajax.php').'"';
|
||||
$output[] = ' };';
|
||||
$output[] = '</script>';
|
||||
$output[] = '<!--END Scripts-->';
|
||||
$output[] = '<!-- '.
|
||||
__('END Scripts', 'mailpoet').
|
||||
'-->';
|
||||
|
||||
$form_widget = new Widget();
|
||||
$output[] = $form_widget->widget(array(
|
||||
|
@ -165,9 +165,12 @@ class Widget extends \WP_Widget {
|
||||
|
||||
// render form
|
||||
$renderer = new Renderer();
|
||||
$renderer = $renderer->init();
|
||||
$output = $renderer->render('form/widget.html', $data);
|
||||
$output = do_shortcode($output);
|
||||
try {
|
||||
$output = $renderer->render('form/widget.html', $data);
|
||||
$output = do_shortcode($output);
|
||||
} catch(\Exception $e) {
|
||||
$output = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if($form_type === 'widget') {
|
||||
|
47
lib/Helpscout/Beacon.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace MailPoet\Helpscout;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\Setting;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Beacon {
|
||||
static function getData() {
|
||||
global $wpdb;
|
||||
$db_version = $wpdb->get_var('SELECT @@VERSION');
|
||||
$mta = Setting::getValue('mta');
|
||||
$current_theme = wp_get_theme();
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
return array(
|
||||
'name' => $current_user->display_name,
|
||||
'email' => $current_user->user_email,
|
||||
'PHP version' => PHP_VERSION,
|
||||
'MailPoet version' => MAILPOET_VERSION,
|
||||
'WordPress version' => get_bloginfo('version'),
|
||||
'Database version' => $db_version,
|
||||
'WP_MEMORY_LIMIT' => WP_MEMORY_LIMIT,
|
||||
'WP_MAX_MEMORY_LIMIT' => WP_MAX_MEMORY_LIMIT,
|
||||
'WP_DEBUG' => WP_DEBUG,
|
||||
'PHP max_execution_time' => ini_get('max_execution_time'),
|
||||
'PHP memory_limit' => ini_get('memory_limit'),
|
||||
'PHP upload_max_filesize' => ini_get('upload_max_filesize'),
|
||||
'PHP post_max_size' => ini_get('post_max_size'),
|
||||
'WordPress language' => get_locale(),
|
||||
'Multisite environment?' => (is_multisite() ? 'Yes' : 'No'),
|
||||
'Current Theme' => $current_theme->get('Name').
|
||||
' (version '.$current_theme->get('Version').')',
|
||||
'Active Plugin names' => join(", ", get_option('active_plugins')),
|
||||
'Sending Method' => $mta['method'],
|
||||
'Sending Frequency' => sprintf('%d emails every %d minutes',
|
||||
$mta['frequency']['emails'],
|
||||
$mta['frequency']['interval']
|
||||
),
|
||||
'Task Scheduler method' => Setting::getValue('cron_trigger.method'),
|
||||
'Default FROM address' => Setting::getValue('sender.address'),
|
||||
'Default Reply-To address' => Setting::getValue('reply_to.address'),
|
||||
'Bounce Email Address' => Setting::getValue('bounce.address'),
|
||||
'Total number of subscribers' => Subscriber::getTotalSubscribers()
|
||||
);
|
||||
}
|
||||
}
|
@ -20,6 +20,15 @@ class Handler {
|
||||
// constrain sort order value to either be "asc" or "desc"
|
||||
$sort_order = ($sort_order === 'asc') ? 'asc' : 'desc';
|
||||
|
||||
// sanitize sort by
|
||||
$sort_by = (!empty($data['sort_by']))
|
||||
? filter_var($data['sort_by'], FILTER_SANITIZE_STRING)
|
||||
: '';
|
||||
|
||||
if(empty($sort_by)) {
|
||||
$sort_by = 'id';
|
||||
}
|
||||
|
||||
$this->data = array(
|
||||
// extra parameters
|
||||
'params' => (isset($data['params']) ? $data['params'] : array()),
|
||||
@ -32,7 +41,7 @@ class Handler {
|
||||
// searching
|
||||
'search' => (isset($data['search']) ? $data['search'] : null),
|
||||
// sorting
|
||||
'sort_by' => (!empty($data['sort_by']) ? $data['sort_by'] : 'id'),
|
||||
'sort_by' => $sort_by,
|
||||
'sort_order' => $sort_order,
|
||||
// grouping
|
||||
'group' => (isset($data['group']) ? $data['group'] : null),
|
||||
|
@ -17,7 +17,7 @@ class AmazonSES {
|
||||
public $reply_to;
|
||||
public $date;
|
||||
public $date_without_time;
|
||||
const SES_REGIONS = array(
|
||||
private $available_regions = array(
|
||||
'US East (N. Virginia)' => 'us-east-1',
|
||||
'US West (Oregon)' => 'us-west-2',
|
||||
'EU (Ireland)' => 'eu-west-1'
|
||||
@ -26,7 +26,7 @@ class AmazonSES {
|
||||
function __construct($region, $access_key, $secret_key, $sender, $reply_to) {
|
||||
$this->aws_access_key = $access_key;
|
||||
$this->aws_secret_key = $secret_key;
|
||||
$this->aws_region = (in_array($region, self::SES_REGIONS)) ? $region : false;
|
||||
$this->aws_region = (in_array($region, $this->available_regions)) ? $region : false;
|
||||
if(!$this->aws_region) {
|
||||
throw new \Exception(__('Unsupported Amazon SES region.', 'mailpoet'));
|
||||
}
|
||||
@ -42,6 +42,7 @@ class AmazonSES {
|
||||
$this->date_without_time = gmdate('Ymd');
|
||||
}
|
||||
|
||||
|
||||
function send($newsletter, $subscriber) {
|
||||
$result = wp_remote_post(
|
||||
$this->url,
|
||||
|
@ -14,6 +14,8 @@ class Subscriber extends Model {
|
||||
const STATUS_UNSUBSCRIBED = 'unsubscribed';
|
||||
const STATUS_UNCONFIRMED = 'unconfirmed';
|
||||
|
||||
const SUBSCRIPTION_LIMIT_COOLDOWN = 60;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
@ -150,14 +152,49 @@ class Subscriber extends Model {
|
||||
}
|
||||
|
||||
static function verifyToken($email, $token) {
|
||||
return hash_equals(self::generateToken($email), $token);
|
||||
return call_user_func('hash_equals', self::generateToken($email), $token);
|
||||
}
|
||||
|
||||
static function subscribe($subscriber_data = array(), $segment_ids = array()) {
|
||||
// filter out keys from the subscriber_data array
|
||||
// that should not be editable when subscribing
|
||||
$reserved_columns = array(
|
||||
'id',
|
||||
'wp_user_id',
|
||||
'status',
|
||||
'subscribed_ip',
|
||||
'confirmed_ip',
|
||||
'confirmed_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at'
|
||||
);
|
||||
$subscriber_data = array_diff_key(
|
||||
$subscriber_data,
|
||||
array_flip($reserved_columns)
|
||||
);
|
||||
|
||||
$signup_confirmation_enabled = (bool)Setting::getValue(
|
||||
'signup_confirmation.enabled'
|
||||
);
|
||||
|
||||
$subscriber_data['subscribed_ip'] = (isset($_SERVER['REMOTE_ADDR']))
|
||||
? $_SERVER['REMOTE_ADDR']
|
||||
: null;
|
||||
|
||||
// make sure we don't allow too many subscriptions with the same ip address
|
||||
$subscription_count = Subscriber::where(
|
||||
'subscribed_ip',
|
||||
$subscriber_data['subscribed_ip']
|
||||
)->whereRaw(
|
||||
'TIME_TO_SEC(TIMEDIFF(NOW(), created_at)) < ?',
|
||||
self::SUBSCRIPTION_LIMIT_COOLDOWN
|
||||
)->count();
|
||||
|
||||
if($subscription_count > 0) {
|
||||
throw new \Exception(__('You need to wait before subscribing again.', 'mailpoet'));
|
||||
}
|
||||
|
||||
$subscriber = self::findOne($subscriber_data['email']);
|
||||
|
||||
if($subscriber === false) {
|
||||
@ -629,7 +666,9 @@ class Subscriber extends Model {
|
||||
return self::whereIn('status', array(
|
||||
self::STATUS_SUBSCRIBED,
|
||||
self::STATUS_UNCONFIRMED
|
||||
))->count();
|
||||
))
|
||||
->whereNull('deleted_at')
|
||||
->count();
|
||||
}
|
||||
|
||||
static function bulkTrash($orm) {
|
||||
|
@ -38,10 +38,11 @@ class Renderer {
|
||||
|
||||
function render($data, $column_count) {
|
||||
$block_content = '';
|
||||
array_map(function($block) use (&$block_content, &$column_content, $column_count) {
|
||||
$rendered_block_element = $this->createElementFromBlockType($block, $column_count);
|
||||
$_this = $this;
|
||||
array_map(function($block) use (&$block_content, &$column_content, $column_count, $_this) {
|
||||
$rendered_block_element = $_this->createElementFromBlockType($block, $column_count);
|
||||
if(isset($block['blocks'])) {
|
||||
$rendered_block_element = $this->render($block, $column_count);
|
||||
$rendered_block_element = $_this->render($block, $column_count);
|
||||
}
|
||||
// vertical orientation denotes column container
|
||||
if($block['type'] === 'container' && $block['orientation'] === 'vertical') {
|
||||
|
@ -6,6 +6,9 @@ use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
class Text {
|
||||
static function render($element) {
|
||||
$html = $element['text'];
|
||||
// replace with spaces
|
||||
$html = str_replace(' ', ' ', $html);
|
||||
$html = str_replace('\xc2\xa0', ' ', $html);
|
||||
$html = self::convertBlockquotesToTables($html);
|
||||
$html = self::convertParagraphsToTables($html);
|
||||
$html = self::styleLists($html);
|
||||
|
@ -11,7 +11,7 @@ class Renderer {
|
||||
$this->getOneColumnTemplate($styles, $class) :
|
||||
$this->getMultipleColumnsTemplate($styles, $width, $alignment, $class);
|
||||
$result = array_map(function($content) use ($template) {
|
||||
$content = self::removePaddingFromLastElement($content);
|
||||
$content = Renderer::removePaddingFromLastElement($content);
|
||||
return $template['content_start'] . $content . $template['content_end'];
|
||||
}, $columns_data);
|
||||
$result = implode('', $result);
|
||||
|
@ -59,13 +59,14 @@ class Renderer {
|
||||
? $content['blocks']
|
||||
: array();
|
||||
|
||||
$rendered_content = array_map(function($content_block) {
|
||||
$_this = $this;
|
||||
$rendered_content = array_map(function($content_block) use($_this) {
|
||||
$column_count = count($content_block['blocks']);
|
||||
$column_data = $this->blocks_renderer->render(
|
||||
$column_data = $_this->blocks_renderer->render(
|
||||
$content_block,
|
||||
$column_count
|
||||
);
|
||||
return $this->columns_renderer->render(
|
||||
return $_this->columns_renderer->render(
|
||||
$content_block['styles'],
|
||||
$column_count,
|
||||
$column_data
|
||||
@ -107,6 +108,7 @@ class Renderer {
|
||||
}
|
||||
|
||||
function renderTextVersion($template) {
|
||||
$template = utf8_encode($template);
|
||||
return \Html2Text\Html2Text::convert($template);
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ class StylesHelper {
|
||||
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;';
|
||||
return StylesHelper::translateCSSAttribute($attribute) . ': ' . $style . ' !important;';
|
||||
}
|
||||
}, array_keys($data[$type]), $data[$type]);
|
||||
return implode('', $styles);
|
||||
|
@ -14,4 +14,4 @@ class Date {
|
||||
);
|
||||
return (isset($actions[$action])) ? $actions[$action] : false;
|
||||
}
|
||||
}
|
||||
}
|
@ -125,4 +125,4 @@ class Link {
|
||||
private static function getShortcode($action) {
|
||||
return sprintf('[link:%s]', $action);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Shortcodes\Categories;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Newsletter\Shortcodes\ShortcodesHelper;
|
||||
|
||||
use MailPoet\Models\Newsletter as NewsletterModel;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
require_once( ABSPATH . "wp-includes/pluggable.php" );
|
||||
require_once(ABSPATH . "wp-includes/pluggable.php");
|
||||
|
||||
class Newsletter {
|
||||
static function process($action,
|
||||
@ -16,7 +16,7 @@ class Newsletter {
|
||||
) {
|
||||
switch($action) {
|
||||
case 'subject':
|
||||
return ($newsletter) ? $newsletter['subject'] : false;
|
||||
return ($newsletter) ? $newsletter->subject : false;
|
||||
|
||||
case 'total':
|
||||
return substr_count($content, 'data-post-id');
|
||||
@ -28,10 +28,10 @@ class Newsletter {
|
||||
return ($latest_post) ? $latest_post['post_title'] : false;
|
||||
|
||||
case 'number':
|
||||
if($newsletter['type'] !== 'notification') return false;
|
||||
if($newsletter->type !== NewsletterModel::TYPE_NOTIFICATION_HISTORY) return false;
|
||||
$sent_newsletters =
|
||||
SendingQueue::where('newsletter_id', $newsletter['id'])
|
||||
->where('status', 'completed')
|
||||
NewsletterModel::where('parent_id', $newsletter->parent_id)
|
||||
->where('status', NewsletterModel::STATUS_SENT)
|
||||
->count();
|
||||
return ++$sent_newsletters;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter\Shortcodes\Categories;
|
||||
|
||||
use MailPoet\Models\Subscriber as SubscriberModel;
|
||||
use MailPoet\Models\SubscriberCustomField;
|
||||
|
||||
@ -15,14 +16,14 @@ class Subscriber {
|
||||
) {
|
||||
switch($action) {
|
||||
case 'firstname':
|
||||
return ($subscriber) ? $subscriber['first_name'] : $default_value;
|
||||
return ($subscriber) ? $subscriber->first_name : $default_value;
|
||||
case 'lastname':
|
||||
return ($subscriber) ? $subscriber['last_name'] : $default_value;
|
||||
return ($subscriber) ? $subscriber->last_name : $default_value;
|
||||
case 'email':
|
||||
return ($subscriber) ? $subscriber['email'] : false;
|
||||
return ($subscriber) ? $subscriber->email : false;
|
||||
case 'displayname':
|
||||
if($subscriber && $subscriber['wp_user_id']) {
|
||||
$wp_user = get_userdata($subscriber['wp_user_id']);
|
||||
if($subscriber && $subscriber->wp_user_id) {
|
||||
$wp_user = get_userdata($subscriber->wp_user_id);
|
||||
return $wp_user->user_login;
|
||||
}
|
||||
return $default_value;
|
||||
@ -31,10 +32,10 @@ class Subscriber {
|
||||
->count();
|
||||
default:
|
||||
if(preg_match('/cf_(\d+)/', $action, $custom_field) &&
|
||||
!empty($subscriber['id'])
|
||||
!empty($subscriber->id)
|
||||
) {
|
||||
$custom_field = SubscriberCustomField
|
||||
::where('subscriber_id', $subscriber['id'])
|
||||
::where('subscriber_id', $subscriber->id)
|
||||
->where('custom_field_id', $custom_field[1])
|
||||
->findOne();
|
||||
return ($custom_field) ? $custom_field->value : false;
|
||||
|
@ -12,15 +12,9 @@ class Shortcodes {
|
||||
$subscriber = false,
|
||||
$queue = false
|
||||
) {
|
||||
$this->newsletter = (is_object($newsletter)) ?
|
||||
$newsletter->asArray() :
|
||||
$newsletter;
|
||||
$this->subscriber = (is_object($subscriber)) ?
|
||||
$subscriber->asArray() :
|
||||
$subscriber;
|
||||
$this->queue = (is_object($queue)) ?
|
||||
$queue->asArray() :
|
||||
$queue;
|
||||
$this->newsletter = $newsletter;
|
||||
$this->subscriber = $subscriber;
|
||||
$this->queue = $queue;
|
||||
}
|
||||
|
||||
function extract($content, $categories = false) {
|
||||
@ -48,9 +42,10 @@ class Shortcodes {
|
||||
}
|
||||
|
||||
function process($shortcodes, $content = false) {
|
||||
$_this = $this;
|
||||
$processed_shortcodes = array_map(
|
||||
function($shortcode) use ($content) {
|
||||
$shortcode_details = $this->match($shortcode);
|
||||
function($shortcode) use ($content, $_this) {
|
||||
$shortcode_details = $_this->match($shortcode);
|
||||
$shortcode_category = !empty($shortcode_details['category']) ?
|
||||
ucfirst($shortcode_details['category']) :
|
||||
false;
|
||||
@ -58,7 +53,7 @@ class Shortcodes {
|
||||
$shortcode_details['action'] :
|
||||
false;
|
||||
$shortcode_class =
|
||||
self::SHORTCODE_CATEGORY_NAMESPACE . $shortcode_category;
|
||||
Shortcodes::SHORTCODE_CATEGORY_NAMESPACE . $shortcode_category;
|
||||
$shortcode_default_value = !empty($shortcode_details['default']) ?
|
||||
$shortcode_details['default'] :
|
||||
false;
|
||||
@ -66,9 +61,9 @@ class Shortcodes {
|
||||
$custom_shortcode = apply_filters(
|
||||
'mailpoet_newsletter_shortcode',
|
||||
$shortcode,
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$this->queue,
|
||||
$_this->newsletter,
|
||||
$_this->subscriber,
|
||||
$_this->queue,
|
||||
$content
|
||||
);
|
||||
return ($custom_shortcode === $shortcode) ?
|
||||
@ -78,9 +73,9 @@ class Shortcodes {
|
||||
return $shortcode_class::process(
|
||||
$shortcode_action,
|
||||
$shortcode_default_value,
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$this->queue,
|
||||
$_this->newsletter,
|
||||
$_this->subscriber,
|
||||
$_this->queue,
|
||||
$content
|
||||
);
|
||||
}, $shortcodes);
|
||||
|
@ -1,8 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoet\Settings;
|
||||
|
||||
use MailPoet\Mailer\Methods\AmazonSES;
|
||||
|
||||
class Hosts {
|
||||
private static $_smtp = array(
|
||||
'AmazonSES' => array(
|
||||
@ -14,7 +12,11 @@ class Hosts {
|
||||
'access_key',
|
||||
'secret_key'
|
||||
),
|
||||
'regions' => AmazonSES::SES_REGIONS
|
||||
'regions' => array(
|
||||
'US East (N. Virginia)' => 'us-east-1',
|
||||
'US West (Oregon)' => 'us-west-2',
|
||||
'EU (Ireland)' => 'eu-west-1'
|
||||
)
|
||||
),
|
||||
'SendGrid' => array(
|
||||
'name' => 'SendGrid',
|
||||
|
@ -83,10 +83,8 @@ class MailChimp {
|
||||
}
|
||||
if(!isset($header_hash)) {
|
||||
$header_hash = md5(implode(',', $header));
|
||||
} else {
|
||||
if(md5(implode(',', $header) !== $header_hash)) {
|
||||
return $this->throwException('headers');
|
||||
}
|
||||
} elseif(md5(implode(',', $header) !== $header_hash)) {
|
||||
return $this->throwException('headers');
|
||||
}
|
||||
} else {
|
||||
$subscribers[] = $obj;
|
||||
@ -147,4 +145,4 @@ class MailChimp {
|
||||
}
|
||||
throw new \Exception($errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,18 +7,23 @@ class Manage {
|
||||
|
||||
static function onSave() {
|
||||
$action = (isset($_POST['action']) ? $_POST['action'] : null);
|
||||
$token = (isset($_POST['token']) ? $_POST['token'] : null);
|
||||
|
||||
if($action !== 'mailpoet_subscription_update') {
|
||||
Url::redirectBack();
|
||||
}
|
||||
|
||||
$reserved_keywords = array('action', 'mailpoet_redirect');
|
||||
$reserved_keywords = array('action', 'token', 'mailpoet_redirect');
|
||||
$subscriber_data = array_diff_key(
|
||||
$_POST,
|
||||
array_flip($reserved_keywords)
|
||||
);
|
||||
|
||||
if(isset($subscriber_data['email'])) {
|
||||
if(
|
||||
isset($subscriber_data['email'])
|
||||
&&
|
||||
Subscriber::verifyToken($subscriber_data['email'], $token)
|
||||
) {
|
||||
if($subscriber_data['email'] !== Pages::DEMO_EMAIL) {
|
||||
$subscriber = Subscriber::createOrUpdate($subscriber_data);
|
||||
$errors = $subscriber->getErrors();
|
||||
|
@ -59,6 +59,8 @@ class Pages {
|
||||
function confirm() {
|
||||
if($this->subscriber !== false) {
|
||||
$this->subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$this->subscriber->confirmed_ip = $_SERVER['REMOTE_ADDR'];
|
||||
$this->subscriber->setExpr('confirmed_at', 'NOW()');
|
||||
$this->subscriber->save();
|
||||
}
|
||||
}
|
||||
@ -324,7 +326,12 @@ class Pages {
|
||||
$form_html .= '<input type="hidden" name="segments" value="" />';
|
||||
$form_html .= '<input type="hidden" name="mailpoet_redirect" '.
|
||||
'value="'.Url::getCurrentUrl().'" />';
|
||||
$form_html .= '<input type="hidden" name="email" value="'.$subscriber->email.'" />';
|
||||
$form_html .= '<input type="hidden" name="email" value="'.
|
||||
$subscriber->email.
|
||||
'" />';
|
||||
$form_html .= '<input type="hidden" name="token" value="'.
|
||||
Subscriber::generateToken($subscriber->email).
|
||||
'" />';
|
||||
|
||||
$form_html .= '<p class="mailpoet_paragraph">';
|
||||
$form_html .= '<label>Email *<br /><strong>'.$subscriber->email.'</strong></label>';
|
||||
|
21
lib/Twig/Helpscout.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace MailPoet\Twig;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Helpscout extends \Twig_Extension {
|
||||
|
||||
public function getName() {
|
||||
return 'helpscout';
|
||||
}
|
||||
|
||||
public function getFunctions() {
|
||||
return array(
|
||||
new \Twig_SimpleFunction(
|
||||
'get_helpscout_data',
|
||||
'\MailPoet\Helpscout\Beacon::getData',
|
||||
array('is_safe' => array('all'))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -21,16 +21,15 @@ class I18n extends \Twig_Extension {
|
||||
$twig_functions = array();
|
||||
// list of WP functions to map
|
||||
$functions = array(
|
||||
'localize',
|
||||
'__',
|
||||
'_n',
|
||||
'date',
|
||||
'date_format'
|
||||
'localize' => 'localize',
|
||||
'__' => 'translate',
|
||||
'_n' => 'pluralize',
|
||||
'date' => 'date'
|
||||
);
|
||||
|
||||
foreach($functions as $function) {
|
||||
foreach($functions as $twig_function => $function) {
|
||||
$twig_functions[] = new \Twig_SimpleFunction(
|
||||
$function,
|
||||
$twig_function,
|
||||
array($this, $function),
|
||||
array('is_safe' => array('all'))
|
||||
);
|
||||
@ -52,13 +51,13 @@ class I18n extends \Twig_Extension {
|
||||
return join("\n", $output);
|
||||
}
|
||||
|
||||
function __() {
|
||||
function translate() {
|
||||
$args = func_get_args();
|
||||
|
||||
return call_user_func_array('__', $this->setTextDomain($args));
|
||||
}
|
||||
|
||||
function _n() {
|
||||
function pluralize() {
|
||||
$args = func_get_args();
|
||||
|
||||
return call_user_func_array('_n', $this->setTextDomain($args));
|
||||
|
@ -185,15 +185,8 @@ class CSS {
|
||||
* If you pass $contents then the original HTML is not downloaded and $contents is used instead.
|
||||
* $url is mandatory as it is used to resolve the links to the stylesheets found in the HTML.
|
||||
*/
|
||||
function inlineCSS($url, $contents=null)
|
||||
{
|
||||
// Download the HTML if it was not provided
|
||||
if($contents === null) {
|
||||
$html = HtmlDomParser::file_get_html($url, false, null, -1, -1, true, true, DEFAULT_TARGET_CHARSET, false, DEFAULT_BR_TEXT, DEFAULT_SPAN_TEXT);
|
||||
} else {
|
||||
// use the data provided!
|
||||
$html = HtmlDomParser::str_get_html($contents, true, true, DEFAULT_TARGET_CHARSET, false, DEFAULT_BR_TEXT, DEFAULT_SPAN_TEXT);
|
||||
}
|
||||
function inlineCSS($url, $contents=null) {
|
||||
$html = \pQuery::parseStr($contents);
|
||||
|
||||
if(!is_object($html)) {
|
||||
return false;
|
||||
@ -202,13 +195,13 @@ class CSS {
|
||||
$css_blocks = '';
|
||||
|
||||
// Find all <style> blocks and cut styles from them (leaving media queries)
|
||||
foreach($html->find('style') as $style) {
|
||||
list($_css_to_parse, $_css_to_keep) = self::splitMediaQueries($style->innertext());
|
||||
foreach($html->query('style') as $style) {
|
||||
list($_css_to_parse, $_css_to_keep) = self::splitMediaQueries($style->getInnerText());
|
||||
$css_blocks .= $_css_to_parse;
|
||||
if(!empty($_css_to_keep)) {
|
||||
$style->innertext = $_css_to_keep;
|
||||
$style->setInnerText($_css_to_keep);
|
||||
} else {
|
||||
$style->outertext = '';
|
||||
$style->setOuterText('');
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +218,7 @@ class CSS {
|
||||
// We loop over each rule by increasing order of specificity, find the nodes matching the selector
|
||||
// and apply the CSS properties
|
||||
foreach ($rules as $rule) {
|
||||
foreach($html->find($rule['selector']) as $node) {
|
||||
foreach($html->query($rule['selector']) as $node) {
|
||||
// I'm leaving this for debug purposes, it has proved useful.
|
||||
/*
|
||||
if($node->already_styled === 'yes')
|
||||
|
19
lib/Util/License/Features/Subscribers.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace MailPoet\Util\License\Features;
|
||||
|
||||
use MailPoet\Models\Subscriber as SubscriberModel;
|
||||
use MailPoet\Util\License\License;
|
||||
|
||||
class Subscribers {
|
||||
public $license;
|
||||
const SUBSCRIBERS_LIMIT = 2000;
|
||||
|
||||
function __construct($license = false) {
|
||||
$this->license = ($license) ? $license : License::getLicense();
|
||||
}
|
||||
|
||||
function check($subscribers_limit = self::SUBSCRIBERS_LIMIT) {
|
||||
if($this->license) return false;
|
||||
return SubscriberModel::getTotalSubscribers() > $subscribers_limit;
|
||||
}
|
||||
}
|
13
lib/Util/License/License.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace MailPoet\Util\License;
|
||||
|
||||
class License {
|
||||
static function getLicense($license = false) {
|
||||
if(!$license) {
|
||||
$license = defined('MAILPOET_PREMIUM_LICENSE') ?
|
||||
MAILPOET_PREMIUM_LICENSE :
|
||||
false;
|
||||
}
|
||||
return $license;
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ class Notice {
|
||||
private $type;
|
||||
private $message;
|
||||
|
||||
protected function __construct($type, $message) {
|
||||
function __construct($type, $message) {
|
||||
$this->type = $type;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ if(!defined('ABSPATH')) exit;
|
||||
use \MailPoet\Config\Initializer;
|
||||
/*
|
||||
* Plugin Name: MailPoet
|
||||
* Version: 0.0.50
|
||||
* Version: 3.0.0-beta.4
|
||||
* Plugin URI: http://www.mailpoet.com
|
||||
* Description: MailPoet Newsletters.
|
||||
* Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
|
||||
* Author: MailPoet
|
||||
* Author URI: http://www.mailpoet.com
|
||||
* Requires at least: 4.0
|
||||
@ -22,7 +22,7 @@ use \MailPoet\Config\Initializer;
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
define('MAILPOET_VERSION', '0.0.50');
|
||||
define('MAILPOET_VERSION', '3.0.0-beta.4');
|
||||
|
||||
$initializer = new Initializer(array(
|
||||
'file' => __FILE__,
|
||||
|
@ -12,10 +12,8 @@
|
||||
"backbone.marionette": "2.4.7",
|
||||
"backbone.radio": "1.0.5",
|
||||
"backbone.supermodel": "1.2.0",
|
||||
"c3": "~0.4.10",
|
||||
"classnames": "^2.1.3",
|
||||
"codemirror": "^5.8.0",
|
||||
"d3": "~3.5.5",
|
||||
"handlebars": "3.0.3",
|
||||
"history": "1.13.1",
|
||||
"html2canvas": "0.5.0-alpha2",
|
||||
@ -26,17 +24,13 @@
|
||||
"parsleyjs": "^2.1.2",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react-infinity": "latest",
|
||||
"react-prefixr": "latest",
|
||||
"react-router": "latest",
|
||||
"react-string-replace": "^0.3.2",
|
||||
"react-waypoint": "latest",
|
||||
"select2": "^4.0.0",
|
||||
"spectrum-colorpicker": "^1.6.2",
|
||||
"tinymce": "4.3.12",
|
||||
"underscore": "1.8.3",
|
||||
"velocity-animate": "1.2.3",
|
||||
"xss": "^0.2.10"
|
||||
"velocity-animate": "1.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expose-loader": "latest",
|
||||
@ -55,7 +49,6 @@
|
||||
"sinon": "1.14.1",
|
||||
"sinon-chai": "2.7.0",
|
||||
"stylus": "latest",
|
||||
"swag": "~0.7.0",
|
||||
"webpack": "1.11.0"
|
||||
}
|
||||
}
|
||||
|
BIN
plugin_repository/assets/banner-1500x500.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
plugin_repository/assets/banner-772x250.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
plugin_repository/assets/icon-128x128.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
plugin_repository/assets/screenshot-1.png
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
plugin_repository/assets/screenshot-2.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
plugin_repository/assets/screenshot-3.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
plugin_repository/assets/screenshot-4.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
plugin_repository/assets/screenshot-5.png
Normal file
After Width: | Height: | Size: 46 KiB |
36
readme.txt
@ -2,8 +2,8 @@
|
||||
Contributors: mailpoet
|
||||
Tags: newsletter, email, welcome email, post notification, autoresponder, mailchimp, signup, smtp
|
||||
Requires at least: 4.6
|
||||
Tested up to: 4.6
|
||||
Stable tag: 3.0.0
|
||||
Tested up to: 4.6.1
|
||||
Stable tag: 3.0.0-beta.4
|
||||
Create and send beautiful emails and newsletters from WordPress.
|
||||
|
||||
== Description ==
|
||||
@ -83,7 +83,35 @@ Our [support site](https://docs.mailpoet.com/) has plenty of articles. You can w
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.0.0 - 2016-09 =
|
||||
= 3.0.0-beta.4 - 2016-11 =
|
||||
|
||||
* Hello world.
|
||||
* Updated HelpScout beacon to provide support articles;
|
||||
* Fixed handling of URLs containing shortcodes in newsletter editor;
|
||||
* Security fixes;
|
||||
* Fixed subscriber count to not count trashed subscribers;
|
||||
* Fixed template renderer to gracefully display an error when template caching issues arise;
|
||||
* Added security measures to prevent mass subscriptions.
|
||||
|
||||
= 3.0.0-beta.3 - 2016-11 =
|
||||
|
||||
* Improved compatibility with PHP 7;
|
||||
* Fixed showing current newsletter status in newsletter listings when there are no subscribers to send to;
|
||||
* Removed obsolete libraries;
|
||||
* Fixed security issues;
|
||||
* Fixed html form embed code to use correct paths;
|
||||
* Updated settings documentation URL;
|
||||
* Improved text fitting in newsletter type/template selection boxes;
|
||||
* Fixed Populator compatibility with earlier PHP versions;
|
||||
* Fixed newsletter number shortcode for notification newsletters;
|
||||
* Enhanced HelpScout support beacon report with extra support data;
|
||||
* Fixed email renderer to not throw entity warnings on earlier PHP versions;
|
||||
* Fixed newsletter preview incompatibility errors for earlier PHP versions;
|
||||
|
||||
= 3.0.0-beta.2 - 2016-10 =
|
||||
|
||||
* Fixed compatibility issues with PHP versions earlier than PHP 5.6;
|
||||
* Renamed 'Emails' email type to 'Newsletters';
|
||||
|
||||
= 3.0.0-beta.1 - 2016-10 =
|
||||
|
||||
* Initial public beta release.
|
||||
|
@ -15,7 +15,7 @@
|
||||
<!-- All parameters in function signature should be used within the function -->
|
||||
<!--<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter"/>-->
|
||||
<!-- Don't use methods that extend and only call the parent method -->
|
||||
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
|
||||
<!--<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>-->
|
||||
|
||||
<!-- Disallow usage of BOMs -->
|
||||
<rule ref="Generic.Files.ByteOrderMark"/>
|
||||
@ -120,4 +120,7 @@
|
||||
<!-- Remove space between if/for/while and opening parenthesis -->
|
||||
<rule ref="MailPoet.ControlStructures.ControlSignature"/>
|
||||
|
||||
<!-- Run against the PHPCompatibility ruleset -->
|
||||
<rule ref="PHPCompatibility" />
|
||||
<config name="testVersion" value="5.3-7.0"/>
|
||||
</ruleset>
|
||||
|
@ -4,6 +4,7 @@ use \MailPoet\API\Endpoints\Subscribers;
|
||||
use \MailPoet\API\Response as APIResponse;
|
||||
use \MailPoet\Models\Subscriber;
|
||||
use \MailPoet\Models\Segment;
|
||||
use \MailPoet\Models\Setting;
|
||||
|
||||
class SubscribersTest extends MailPoetTest {
|
||||
function _before() {
|
||||
@ -26,6 +27,12 @@ class SubscribersTest extends MailPoetTest {
|
||||
$this->segment_2->id
|
||||
)
|
||||
));
|
||||
|
||||
// setup mailer
|
||||
Setting::setValue('sender', array(
|
||||
'address' => 'sender@mailpoet.com',
|
||||
'name' => 'Sender'
|
||||
));
|
||||
}
|
||||
|
||||
function testItCanGetASubscriber() {
|
||||
@ -354,6 +361,46 @@ class SubscribersTest extends MailPoetTest {
|
||||
expect($response->errors[0]['message'])->contains('has no method');
|
||||
}
|
||||
|
||||
function testItCannotSubscribeWithoutSegments() {
|
||||
$router = new Subscribers();
|
||||
$response = $router->subscribe(array(
|
||||
'email' => 'toto@mailpoet.com'
|
||||
// no segments specified
|
||||
));
|
||||
|
||||
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||
expect($response->errors[0]['message'])->equals('Please select a list.');
|
||||
}
|
||||
|
||||
function testItCanSubscribe() {
|
||||
$router = new Subscribers();
|
||||
$response = $router->subscribe(array(
|
||||
'email' => 'toto@mailpoet.com',
|
||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||
));
|
||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||
}
|
||||
|
||||
function testItCannotMassSubscribe() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
$router = new Subscribers();
|
||||
$response = $router->subscribe(array(
|
||||
'email' => 'toto@mailpoet.com',
|
||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||
));
|
||||
|
||||
try {
|
||||
$response = $router->subscribe(array(
|
||||
'email' => 'tata@mailpoet.com',
|
||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||
));
|
||||
$this->fail('It should not be possible to subscribe a second time so soon');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('You need to wait before subscribing again.');
|
||||
}
|
||||
}
|
||||
|
||||
function _after() {
|
||||
Segment::deleteMany();
|
||||
Subscriber::deleteMany();
|
||||
|
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
use Codeception\Util\Stub;
|
||||
use \MailPoet\Config\Renderer;
|
||||
|
||||
class RendererTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->renderer = new Renderer();
|
||||
$this->renderer = new Renderer($caching = false, $debugging = false);
|
||||
}
|
||||
|
||||
function testItWillNotEnableCacheWhenWpDebugIsOn() {
|
||||
@ -11,6 +12,47 @@ class RendererTest extends MailPoetTest {
|
||||
expect($result)->equals(false);
|
||||
}
|
||||
|
||||
function testItDelegatesRenderingToTwig() {
|
||||
$renderer = Stub::construct(
|
||||
$this->renderer,
|
||||
array(),
|
||||
array(
|
||||
'renderer' => Stub::makeEmpty('Twig_Environment',
|
||||
array(
|
||||
'render' => Stub::atLeastOnce(function() { return 'test render'; }),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
expect($renderer->render('non-existing-template.html', array('somekey' => 'someval')))->equals('test render');
|
||||
}
|
||||
|
||||
function testItRethrowsTwigCacheExceptions() {
|
||||
$exception_message = 'this is a test error';
|
||||
$renderer = Stub::construct(
|
||||
$this->renderer,
|
||||
array(true, false),
|
||||
array(
|
||||
'renderer' => Stub::makeEmpty('Twig_Environment',
|
||||
array(
|
||||
'render' => Stub::atLeastOnce(function() use ($exception_message) {
|
||||
throw new \RuntimeException($exception_message);
|
||||
}),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
$renderer->render('non-existing-template.html', array('somekey' => 'someval'));
|
||||
self::fail('Twig exception was not rethrown');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->contains($exception_message);
|
||||
expect($e->getMessage())->notEquals($exception_message);
|
||||
}
|
||||
}
|
||||
|
||||
function _after() {
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,10 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
class ShortcodesTaskTest extends MailPoetTest {
|
||||
function testItCanReplaceShortcodes() {
|
||||
$queue = $newsletter = array(
|
||||
$queue = $newsletter = (object)array(
|
||||
'id' => 1
|
||||
|
||||
);
|
||||
$subscriber = array(
|
||||
$subscriber = (object)array(
|
||||
'email' => 'test@xample. com',
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe'
|
||||
|
107
tests/unit/Helpscout/BeaconTest.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
use \MailPoet\Helpscout\Beacon;
|
||||
use \MailPoet\Models\Setting;
|
||||
use \MailPoet\Models\Subscriber;
|
||||
|
||||
class BeaconTest extends MailPoetTest {
|
||||
function _before() {
|
||||
// create 3 users (1 confirmed, 1 subscribed, 1 unsubscribed)
|
||||
Subscriber::createOrUpdate(array(
|
||||
'email' => 'user1@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED
|
||||
));
|
||||
Subscriber::createOrUpdate(array(
|
||||
'email' => 'user2@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_UNCONFIRMED
|
||||
));
|
||||
Subscriber::createOrUpdate(array(
|
||||
'email' => 'user3@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_UNSUBSCRIBED
|
||||
));
|
||||
|
||||
$this->beacon_data = Beacon::getData();
|
||||
}
|
||||
|
||||
function testItReturnsPhpVersion() {
|
||||
expect($this->beacon_data['PHP version'])->equals(PHP_VERSION);
|
||||
}
|
||||
|
||||
function testItReturnsMailpoetVersion() {
|
||||
expect($this->beacon_data['MailPoet version'])->equals(MAILPOET_VERSION);
|
||||
}
|
||||
|
||||
function testItReturnsWordpressVersion() {
|
||||
expect($this->beacon_data['WordPress version'])->equals(get_bloginfo('version'));
|
||||
}
|
||||
|
||||
function testItReturnsDatabaseVersion() {
|
||||
global $wpdb;
|
||||
$db_version = $wpdb->get_var('SELECT @@VERSION');
|
||||
expect($this->beacon_data['Database version'])->equals($db_version);
|
||||
}
|
||||
|
||||
function testItReturnsWpMemoryLimit() {
|
||||
expect($this->beacon_data['WP_MEMORY_LIMIT'])->equals(WP_MEMORY_LIMIT);
|
||||
}
|
||||
|
||||
function testItReturnsWpMaxMemoryLimit() {
|
||||
expect($this->beacon_data['WP_MAX_MEMORY_LIMIT'])->equals(WP_MAX_MEMORY_LIMIT);
|
||||
}
|
||||
|
||||
function testItReturnsWpDebugValue() {
|
||||
expect($this->beacon_data['WP_DEBUG'])->equals(WP_DEBUG);
|
||||
}
|
||||
|
||||
function testItReturnsPhpMaxExecutionTime() {
|
||||
expect($this->beacon_data['PHP max_execution_time'])->equals(ini_get('max_execution_time'));
|
||||
}
|
||||
|
||||
function testItReturnsPhpMemoryLimit() {
|
||||
expect($this->beacon_data['PHP memory_limit'])->equals(ini_get('memory_limit'));
|
||||
}
|
||||
|
||||
function testItReturnsPhpUploadMaxFilesize() {
|
||||
expect($this->beacon_data['PHP upload_max_filesize'])->equals(ini_get('upload_max_filesize'));
|
||||
}
|
||||
|
||||
function testItReturnsPhpPostMaxSize() {
|
||||
expect($this->beacon_data['PHP post_max_size'])->equals(ini_get('post_max_size'));
|
||||
}
|
||||
|
||||
function testItReturnsWpLanguage() {
|
||||
expect($this->beacon_data['WordPress language'])->equals(get_locale());
|
||||
}
|
||||
|
||||
function testItReturnsIfWpIsMultisite() {
|
||||
expect($this->beacon_data['Multisite environment?'])->equals(is_multisite() ? 'Yes' : 'No');
|
||||
}
|
||||
|
||||
function testItReturnsCurrentThemeNameAndVersion() {
|
||||
$current_theme = wp_get_theme();
|
||||
expect($this->beacon_data['Current Theme'])->contains($current_theme->get('Name'));
|
||||
expect($this->beacon_data['Current Theme'])->contains($current_theme->get('Version'));
|
||||
}
|
||||
|
||||
function testItReturnsActivePlugins() {
|
||||
expect($this->beacon_data['Active Plugin names'])->equals(join(", ", get_option('active_plugins')));
|
||||
}
|
||||
|
||||
function testItReturnsSendingMethodDetails() {
|
||||
$mta = Setting::getValue('mta');
|
||||
expect($this->beacon_data['Sending Method'])->equals($mta['method']);
|
||||
expect($this->beacon_data['Sending Frequency'])->contains($mta['frequency']['emails'].' emails');
|
||||
expect($this->beacon_data['Sending Frequency'])->contains($mta['frequency']['interval'].' minutes');
|
||||
}
|
||||
|
||||
function testItReturnsSomeSettings() {
|
||||
expect($this->beacon_data['Task Scheduler method'])->equals(Setting::getValue('cron_trigger.method'));
|
||||
expect($this->beacon_data['Default FROM address'])->equals(Setting::getValue('sender.address'));
|
||||
expect($this->beacon_data['Default Reply-To address'])->equals(Setting::getValue('reply_to.address'));
|
||||
expect($this->beacon_data['Bounce Email Address'])->equals(Setting::getValue('bounce.address'));
|
||||
}
|
||||
|
||||
function testItReturnsTotalNumberOfSubscribers() {
|
||||
// unsubscribed users are not taken into account
|
||||
expect($this->beacon_data['Total number of subscribers'])->equals(2);
|
||||
}
|
||||
}
|
@ -314,6 +314,42 @@ class SubscriberTest extends MailPoetTest {
|
||||
expect($subscriber->deleted_at)->equals(null);
|
||||
}
|
||||
|
||||
function testItCannotSubscribeWithReservedColumns() {
|
||||
$segment = Segment::create();
|
||||
$segment->hydrate(array('name' => 'List #1'));
|
||||
$segment->save();
|
||||
|
||||
$subscriber = Subscriber::subscribe(
|
||||
array(
|
||||
'email' => 'donald@mailpoet.com',
|
||||
'first_name' => 'Donald',
|
||||
'last_name' => 'Trump',
|
||||
// the fields below should NOT be taken into account
|
||||
'id' => 1337,
|
||||
'wp_user_id' => 7331,
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED,
|
||||
'created_at' => '1984-03-09 00:00:01',
|
||||
'updated_at' => '1984-03-09 00:00:02',
|
||||
'deleted_at' => '1984-03-09 00:00:03'
|
||||
),
|
||||
array($segment->id())
|
||||
);
|
||||
|
||||
expect($subscriber->id > 0)->equals(true);
|
||||
expect($subscriber->id)->notEquals(1337);
|
||||
expect($subscriber->segments()->count())->equals(1);
|
||||
expect($subscriber->email)->equals('donald@mailpoet.com');
|
||||
expect($subscriber->first_name)->equals('Donald');
|
||||
expect($subscriber->last_name)->equals('Trump');
|
||||
|
||||
expect($subscriber->wp_user_id)->equals(null);
|
||||
expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED);
|
||||
expect($subscriber->created_at)->notEquals('1984-03-09 00:00:01');
|
||||
expect($subscriber->updated_at)->notEquals('1984-03-09 00:00:02');
|
||||
expect($subscriber->created_at)->equals($subscriber->updated_at);
|
||||
expect($subscriber->deleted_at)->equals(null);
|
||||
}
|
||||
|
||||
function testItCanBeUpdatedByEmail() {
|
||||
$subscriber_updated = Subscriber::createOrUpdate(array(
|
||||
'email' => $this->data['email'],
|
||||
@ -465,6 +501,12 @@ class SubscriberTest extends MailPoetTest {
|
||||
'status' => Subscriber::STATUS_UNSUBSCRIBED
|
||||
));
|
||||
|
||||
$subscriber_4 = Subscriber::createOrUpdate(array(
|
||||
'email' => 'subscriber_4@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED,
|
||||
'deleted_at' => Carbon::now()->toDateTimeString()
|
||||
));
|
||||
|
||||
// counts only subscribed & unconfirmed users
|
||||
$total = Subscriber::getTotalSubscribers();
|
||||
expect($total)->equals(2);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use MailPoet\Config\Populator;
|
||||
use MailPoet\Models\CustomField;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
@ -22,11 +23,7 @@ class ShortcodesTest extends MailPoetTest {
|
||||
$this->WP_user = $this->_createWPUser();
|
||||
$this->WP_post = $this->_createWPPost();
|
||||
$this->subscriber = $this->_createSubscriber();
|
||||
$this->newsletter = array(
|
||||
'subject' => 'some subject',
|
||||
'type' => 'notification',
|
||||
'id' => 2
|
||||
);
|
||||
$this->newsletter = $this->_createNewsletter();
|
||||
$this->shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes(
|
||||
$this->newsletter,
|
||||
$this->subscriber
|
||||
@ -72,7 +69,7 @@ class ShortcodesTest extends MailPoetTest {
|
||||
$shortcode = array('[some:shortcode]');
|
||||
$result = $shortcodes_object->process($shortcode);
|
||||
expect($result[0])->false();
|
||||
add_filter('mailpoet_newsletter_shortcode', function (
|
||||
add_filter('mailpoet_newsletter_shortcode', function(
|
||||
$shortcode, $newsletter, $subscriber, $queue, $content) {
|
||||
if($shortcode === '[some:shortcode]') return 'success';
|
||||
}, 10, 5);
|
||||
@ -98,7 +95,7 @@ class ShortcodesTest extends MailPoetTest {
|
||||
'<a href="#">not post</a>';
|
||||
$result =
|
||||
$shortcodes_object->process(array('[newsletter:subject]'));
|
||||
expect($result[0])->equals($this->newsletter['subject']);
|
||||
expect($result[0])->equals($this->newsletter->subject);
|
||||
$result =
|
||||
$shortcodes_object->process(array('[newsletter:total]'), $content);
|
||||
expect($result[0])->equals(2);
|
||||
@ -106,12 +103,32 @@ class ShortcodesTest extends MailPoetTest {
|
||||
$shortcodes_object->process(array('[newsletter:post_title]'));
|
||||
$wp_post = get_post($this->WP_post);
|
||||
expect($result['0'])->equals($wp_post->post_title);
|
||||
$result =
|
||||
$shortcodes_object->process(array('[newsletter:number]'));
|
||||
}
|
||||
|
||||
|
||||
function itCanProcessPostNotificationNewsletterNumberShortcode() {
|
||||
// create first post notification
|
||||
$post_notification_history = $this->_createNewsletter(
|
||||
$parent_id = $this->newsletter_id,
|
||||
$type = Newsletter::TYPE_NOTIFICATION_HISTORY
|
||||
);
|
||||
$shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes(
|
||||
$post_notification_history,
|
||||
$this->subscriber
|
||||
);
|
||||
$result = $shortcodes_object->process(array('[newsletter:number]'));
|
||||
expect($result['0'])->equals(1);
|
||||
$queue = $this->_createQueue();
|
||||
$result =
|
||||
$shortcodes_object->process(array('[newsletter:number]'));
|
||||
|
||||
// create another post notification
|
||||
$post_notification_history = $this->_createNewsletter(
|
||||
$parent_id = $this->newsletter_id,
|
||||
$type = Newsletter::TYPE_NOTIFICATION_HISTORY
|
||||
);
|
||||
$shortcodes_object = new MailPoet\Newsletter\Shortcodes\Shortcodes(
|
||||
$post_notification_history,
|
||||
$this->subscriber
|
||||
);
|
||||
$result = $shortcodes_object->process(array('[newsletter:number]'));
|
||||
expect($result['0'])->equals(2);
|
||||
}
|
||||
|
||||
@ -228,7 +245,7 @@ class ShortcodesTest extends MailPoetTest {
|
||||
$shortcode = '[link:shortcode]';
|
||||
$result = $shortcodes_object->process(array($shortcode));
|
||||
expect($result[0])->false();
|
||||
add_filter('mailpoet_newsletter_shortcode_link', function (
|
||||
add_filter('mailpoet_newsletter_shortcode_link', function(
|
||||
$shortcode, $newsletter, $subscriber, $queue) {
|
||||
if($shortcode === '[link:shortcode]') return 'success';
|
||||
}, 10, 4);
|
||||
@ -271,15 +288,30 @@ class ShortcodesTest extends MailPoetTest {
|
||||
return Subscriber::findOne($subscriber->id);
|
||||
}
|
||||
|
||||
function _createNewsletter($parent_id = null, $type = Newsletter::TYPE_NOTIFICATION) {
|
||||
$newsletter = Newsletter::create();
|
||||
$newsletter->hydrate(
|
||||
array(
|
||||
'subject' => 'some subject',
|
||||
'type' => $type,
|
||||
'status' => Newsletter::STATUS_SENT,
|
||||
'parent_id' => $parent_id,
|
||||
)
|
||||
);
|
||||
$newsletter->save();
|
||||
return Newsletter::findOne($newsletter->id);
|
||||
}
|
||||
|
||||
function _createQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $this->newsletter['id'];
|
||||
$queue->status = 'completed';
|
||||
$queue->save();
|
||||
return $queue;
|
||||
return SendingQueue::findOne($queue->id);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . CustomField::$_table);
|
||||
|
34
tests/unit/Util/License/Features/SubscribersTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Fixtures;
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||
|
||||
class SubscribersFeaturesTest extends MailPoetTest {
|
||||
function testChecksIfSubscribersWithinLimitWhenPremiumLicenseDoesNotExist() {
|
||||
$subscribers_feature = new SubscribersFeature();
|
||||
expect($subscribers_feature->check(0))->false();
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->hydrate(Fixtures::get('subscriber_template'));
|
||||
$subscriber->save();
|
||||
expect($subscribers_feature->check(0))->true();
|
||||
}
|
||||
|
||||
function testChecksIfSubscribersWithinLimitWhenPremiumLicenseExists() {
|
||||
$subscribers_feature = Stub::construct(
|
||||
new SubscribersFeature(),
|
||||
array(
|
||||
'license' => true
|
||||
)
|
||||
);
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->hydrate(Fixtures::get('subscriber_template'));
|
||||
$subscriber->save();
|
||||
expect($subscribers_feature->check(0))->false();
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
}
|
||||
}
|
10
tests/unit/Util/License/LicenseTest.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Util\License\License;
|
||||
|
||||
class LicenseTest extends MailPoetTest {
|
||||
function testItGetsLicense() {
|
||||
expect(License::getLicense())->false();
|
||||
expect(License::getLicense('valid'))->equals('valid');
|
||||
}
|
||||
}
|
@ -57,10 +57,18 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
|
||||
|
||||
<script type="text/javascript">
|
||||
if(window['HS'] !== undefined) {
|
||||
// HelpScout Beacon: Configuration
|
||||
HS.beacon.config({
|
||||
icon: 'message',
|
||||
zIndex: 50000,
|
||||
instructions: '<%= __('Want to give feedback to the MailPoet team? Contact us here. Please provide as much information as possible!') %>',
|
||||
instructions: "<%= __('Want to give feedback to the MailPoet team? Contact us here. Please provide as much information as possible!') %>"
|
||||
});
|
||||
|
||||
// HelpScout Beacon: Custom information
|
||||
HS.beacon.ready(function() {
|
||||
HS.beacon.identify(
|
||||
<%= json_encode(get_helpscout_data()) %>
|
||||
);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
@ -322,8 +322,8 @@
|
||||
'failedToFetchAvailablePosts': __('Failed to fetch available posts'),
|
||||
'failedToFetchRenderedPosts': __('Failed to fetch rendered posts'),
|
||||
'shortcodesWindowTitle': __('Select a shortcode'),
|
||||
'unsubscribeLinkMissing': __('All newsletters must include an "Unsubscribe" link. Add a footer widget to your newsletter to continue'),
|
||||
'newsletterPreviewEmailMissing': __('Enter an email address to send the preview newsletter to'),
|
||||
'unsubscribeLinkMissing': __('All emails must include an "Unsubscribe" link. Add a footer widget to your email to continue.'),
|
||||
'newsletterPreviewEmailMissing': __('Enter an email address to send the preview newsletter to.'),
|
||||
'newsletterPreviewSent': __('Your test email has been sent!'),
|
||||
'templateNameMissing': __('Please add a template name'),
|
||||
'templateDescriptionMissing': __('Please add a template description'),
|
||||
@ -1185,7 +1185,7 @@
|
||||
validateUnsubscribeLinkPresent: true, // TODO: Add validation based on whether Mailpoet MTA is used or not
|
||||
},
|
||||
urls: {
|
||||
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ params('id')) %>',
|
||||
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | number_format)) %>',
|
||||
imageMissing: '<%= image_url(
|
||||
"newsletter_editor/image-missing.svg"
|
||||
) %>',
|
||||
@ -1196,7 +1196,7 @@
|
||||
endpoint: 'newsletters',
|
||||
action: 'get',
|
||||
data: {
|
||||
id: <%= params('id') %>
|
||||
id: "<%= params('id') | number_format %>",
|
||||
}
|
||||
}).always(function() {
|
||||
MailPoet.Modal.loading(false);
|
||||
|
@ -1,2 +1,2 @@
|
||||
<div class="mailpoet_container_empty">{{#ifCond emptyContainerMessage '!==' ''}}{{emptyContainerMessage}}{{else}}{{#if isRoot}}<%= __('Drop layout here!') %>{{else}}<%= __('Drop content here!') %>{{/if}}{{/ifCond}}</div>
|
||||
<div class="mailpoet_container_empty">{{#ifCond emptyContainerMessage '!==' ''}}{{emptyContainerMessage}}{{else}}{{#if isRoot}}<%= __('Add a column block here.') %>{{else}}<%= __('Add a content block here.') %>{{/if}}{{/ifCond}}</div>
|
||||
{{debug}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<h3><%= __('Layout') %></h3>
|
||||
<h3><%= __('Columns') %></h3>
|
||||
<div class="mailpoet_form_field">
|
||||
<label>
|
||||
<div class="mailpoet_form_field_input_option">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="handlediv" title="Click to toggle"><br></div>
|
||||
<h3><%= __('Layout') %></h3>
|
||||
<h3><%= __('Columns') %></h3>
|
||||
<div class="mailpoet_region_content clearfix">
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<% block translations %>
|
||||
<%= localize({
|
||||
'pageTitle': __('Newsletters'),
|
||||
'pageTitle': __('Emails'),
|
||||
|
||||
'tabStandardTitle': __('Newsletters'),
|
||||
'tabWelcomeTitle': __('Welcome Emails'),
|
||||
@ -75,7 +75,7 @@
|
||||
'trash': __('Trash'),
|
||||
'edit': __('Edit'),
|
||||
'duplicate': __('Duplicate'),
|
||||
'newsletterDuplicated': __('Newsletter "%$1s" has been duplicated'),
|
||||
'newsletterDuplicated': __('Email "%$1s" has been duplicated.'),
|
||||
'notSentYet': __('Not sent yet'),
|
||||
'scheduledFor': __('Scheduled for'),
|
||||
'scheduleIt': __('Schedule it'),
|
||||
@ -97,18 +97,18 @@
|
||||
'delete': __('Delete'),
|
||||
'select': __('Select'),
|
||||
'preview': __('Preview'),
|
||||
'selectTemplateTitle': __('Select a template'),
|
||||
'selectTemplateTitle': __('Select a responsive template'),
|
||||
|
||||
'draftNewsletterTitle': __('Subject'),
|
||||
'pickCampaignType': __('Pick a type of campaign'),
|
||||
'pickCampaignType': __('Select type of email'),
|
||||
'regularNewsletterTypeTitle': __('Newsletter'),
|
||||
'regularNewsletterTypeDescription': __('Send a newsletter with images, buttons, dividers, and social bookmarks. Or, just send a basic text email.'),
|
||||
'create': __('Create'),
|
||||
'welcomeNewsletterTypeTitle': __('Welcome Email'),
|
||||
'welcomeNewsletterTypeDescription': __('Automatically send an email (or series of emails) to new subscribers or WordPress users. Send a day, a week, or a month after they sign up.'),
|
||||
'setUp': __('Set up'),
|
||||
'postNotificationNewsletterTypeTitle': __('Post Notifications'),
|
||||
'postNotificationsNewsletterTypeDescription': __('Automatically send posts immediately, daily, weekly or monthly. Filter by categories, if you like.'),
|
||||
'postNotificationNewsletterTypeTitle': __('Latest Post Notifications'),
|
||||
'postNotificationsNewsletterTypeDescription': __('Let MailPoet email your subscribers with your latest content. You can send daily, weekly, monthly, or even immediately after publication.'),
|
||||
'selectFrequency': __('Select a frequency'),
|
||||
'postNotificationSubjectLineTip': __("Insert [newsletter:total] to show number of posts, [newsletter:post_title] to show the latest post's title & [newsletter:number] to display the issue number."),
|
||||
'activate': __('Activate'),
|
||||
@ -146,7 +146,7 @@
|
||||
'subjectLineTip': __("Be creative! It's the first thing that your subscribers see. Tempt them to open your email."),
|
||||
'emptySubjectLineError': __('Please specify a subject'),
|
||||
'segments': __('Lists'),
|
||||
'segmentsTip': __('Your email newsletter(s) will be sent to this list.'),
|
||||
'segmentsTip': __('This subscriber segment will be used for this email.'),
|
||||
'selectSegmentPlaceholder': __('Select a list'),
|
||||
'noSegmentsSelectedError': __('Please select a list'),
|
||||
'sender': __('Sender'),
|
||||
@ -160,7 +160,7 @@
|
||||
'newsletterUpdated': __('Newsletter was updated successfully!'),
|
||||
'newsletterAdded': __('Newsletter was added successfully!'),
|
||||
'newsletterSendingError': __('An error occurred while trying to send. <a href="%$1s">Please check your settings</a>'),
|
||||
'finalNewsletterStep': __('Final step: last details'),
|
||||
'finalNewsletterStep': __('Final Step: Last Details'),
|
||||
'saveDraftAndClose': __('Save as draft and close'),
|
||||
'orSimply': __('or simply'),
|
||||
'goBackToDesign': __('go back to the Design page'),
|
||||
@ -231,6 +231,7 @@
|
||||
'sendingToSegmentsNotSpecified': __('You need to select a list to send to.'),
|
||||
|
||||
'backToPostNotifications': __('Back to Post notifications'),
|
||||
'sentOn': __('Sent on')
|
||||
'sentOn': __('Sent on'),
|
||||
'noSubscribers': __('No subscribers!')
|
||||
}) %>
|
||||
<% endblock %>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label>
|
||||
<%= __('Newsletter task scheduler') %>
|
||||
<%= __('Newsletter task scheduler (cron)') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('Select what will activate your newsletter queue.') %>
|
||||
|
@ -148,7 +148,7 @@
|
||||
<%= __('Subscribe in registration form') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('Allow users who register as a WordPress user on your website to subscribe to a MailPoet list (in addition to the "WordPress Users" list') %>
|
||||
<%= __('Allow users who register as a WordPress user on your website to subscribe to a MailPoet list (in addition to the "WordPress Users" list)') %>
|
||||
</p>
|
||||
</th>
|
||||
<td>
|
||||
@ -203,7 +203,7 @@
|
||||
</div>
|
||||
<% else %>
|
||||
<p>
|
||||
<em><%= __('Registration is disabled on this site') %></em>
|
||||
<em><%= __('Registration is disabled on this site.') %></em>
|
||||
</p>
|
||||
<% endif %>
|
||||
</td>
|
||||
@ -270,9 +270,9 @@
|
||||
<%= __('Unsubscribe page') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('When your subscribers click the "Unsubscribe" link, they will be directed to this page') %>
|
||||
<%= __('When your subscribers click the "Unsubscribe" link, they will be directed to this page.') %>
|
||||
<br />
|
||||
<%= __('Use this shortcode on your website\'s WordPress pages: [mailpoet_manage text="Manage your subscription"]') %>
|
||||
<%= __('If you want to use a custom Unsubscribe page, simply paste this shortcode on to a WordPress page: [mailpoet_manage_text="Manage your subscription"]') %>
|
||||
</p>
|
||||
</th>
|
||||
<td>
|
||||
@ -340,7 +340,7 @@
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label>
|
||||
<%= __('Shortcode to Display Total Number of Subscribers') %>
|
||||
<%= __('Shortcode to display total number of subscribers') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('Paste this shortcode on a post or page to display the total number of confirmed subscribers') %>
|
||||
|
@ -109,7 +109,7 @@
|
||||
<br />
|
||||
<%= __('Send with an external email provider. This is usually not free.') %>
|
||||
<a
|
||||
href="http://docs.mailpoet.com/article/53-send-with-smtp-when-using-a-professional-sending-provider"
|
||||
href="http://docs.mailpoet.com/article/154-why-use-an-email-service-provider"
|
||||
target="_blank"
|
||||
><%= __('Read more.') %></a>
|
||||
</p>
|
||||
|
@ -194,7 +194,7 @@
|
||||
if(~~($(this).val()) === 1) {
|
||||
result = confirm("<%= __('Subscribers will need to activate their subscription via email in order to receive your newsletters. This is highly recommended!') %>");
|
||||
} else {
|
||||
result = confirm("<%= __('Unconfirmed subscribers will receive your newsletters from without needing to activate their subscriptions. This is not recommended!') %>");
|
||||
result = confirm("<%= __('New subscribers will be automatically confirmed, without having to confirm their subscription. This is not recommended!') %>");
|
||||
}
|
||||
// if the user confirmed changing the signup confirmation (yes/no)
|
||||
if(result === true) {
|
||||
|
@ -52,7 +52,7 @@
|
||||
'userColumns': __('User fields'),
|
||||
'selectedValueAlreadyMatched': __('The selected value is already matched to another field'),
|
||||
'confirmCorrespondingColumn': __('Confirm that this field corresponds to the selected field'),
|
||||
'columnContainInvalidElement': __('One of the fields contains an invalid email. Please fix it before continuing'),
|
||||
'columnContainInvalidElement': __('One of the fields contains an invalid email. Please fix it before continuing.'),
|
||||
'january': __('January'),
|
||||
'february': __('February'),
|
||||
'march': __('March'),
|
||||
@ -65,15 +65,15 @@
|
||||
'october': __('October'),
|
||||
'november': __('November'),
|
||||
'december': __('December'),
|
||||
'noDateFieldMatch': __("Do not match as a 'date field' if most of the rows for that field return the same error"),
|
||||
'emptyFirstRowDate': __('First row date cannot be empty'),
|
||||
'noDateFieldMatch': __("Do not match as a 'date field' if most of the rows for that field return the same error."),
|
||||
'emptyFirstRowDate': __('First row date cannot be empty.'),
|
||||
'verifyDateMatch': __('Verify that the date in blue matches the original date'),
|
||||
'pm': __('PM'),
|
||||
'am': __('AM'),
|
||||
'dateMatchError': __('Error matching date'),
|
||||
'columnContainsInvalidDate': __('One of the fields contains an invalid date. Please fix it before continuing'),
|
||||
'columnContainsInvalidDate': __('One of the fields contains an invalid date. Please fix before continuing.'),
|
||||
'listCreateError': __('Error adding a new list:'),
|
||||
'columnContainsInvalidElement': __('One of the fields contains an invalid email. Please fix before continuing'),
|
||||
'columnContainsInvalidElement': __('One of the fields contains an invalid email. Please fix before continuing.'),
|
||||
'customFieldCreateError': __('Custom field could not be created'),
|
||||
'subscribersCreated': __('%1$s subscribers added to %2$s.'),
|
||||
'subscribersUpdated': __('%1$s existing subscribers were updated and added to %2$s')
|
||||
|
@ -17,7 +17,7 @@
|
||||
'pageTitle': __('Subscribers'),
|
||||
'searchLabel': __('Search'),
|
||||
'loadingItems': __('Loading subscribers...'),
|
||||
'noItemsFound': __('No subscribers were found'),
|
||||
'noItemsFound': __('No subscribers were found.'),
|
||||
'selectAllLabel': __('All subscribers on this page are selected.'),
|
||||
'selectedAllLabel': __('All %d subscribers are selected'),
|
||||
'selectAllLink': __('Select all subscribers on all pages.'),
|
||||
|
@ -17,40 +17,39 @@
|
||||
<div style="position: absolute; top: .2em; right: 0;"><img src="<%= image_url('welcome_template/mailpoet-logo.png') %>" alt="MailPoet Logo" /></div>
|
||||
|
||||
<h2 class="nav-tab-wrapper wp-clearfix">
|
||||
<a href="admin.php?page=mailpoet-welcome" class="nav-tab"><%= __('What’s New') %></a>
|
||||
<a href="admin.php?page=mailpoet-update" class="nav-tab nav-tab-active"><%= __('Changelog') %></a>
|
||||
<a href="admin.php?page=mailpoet-welcome" class="nav-tab"><%= __('Welcome') %></a>
|
||||
<a href="admin.php?page=mailpoet-update" class="nav-tab nav-tab-active"><%= __("What's New") %></a>
|
||||
</h2>
|
||||
|
||||
<div id="mailpoet-changelog" clas="feature-section one-col">
|
||||
<h2><%= __("List of Changes") %></h2>
|
||||
<h3>0.0.50 - 2016-10-25</h3>
|
||||
<h3>3.0.0-beta.4 - 2016-11-15</h3>
|
||||
<ul>
|
||||
<li>Renamed "LICENSE" to "license.txt" in preparation for WP plugin repo;</li>
|
||||
<li>Updated "readme.txt" with newly prepared README text;</li>
|
||||
<li>Updated "View All Changes" button on plugin update page to link to MailPoet plugin repo page;</li>
|
||||
<li>Fixed date formatting to allow using escaped symbols;</li>
|
||||
<li>Fixed saving existing newsletters in newsletter editor and last newsletter creation step;</li>
|
||||
<li>Changed "Newsletter not found" error on newsletter editor page to be displayed permanently;</li>
|
||||
<li>Changed "newsletters.save" endpoint to require segment objects when saving newsletters;</li>
|
||||
<li>Fixed security issue with public token reuse on admin panel;</li>
|
||||
<li>Added endpoint specific access limits;</li>
|
||||
<li>Increased subscriber export filename length and complexity to make it more difficult to guess file names;</li>
|
||||
<li>Fixed sending queue to not send newsletters to trashed subscribers;</li>
|
||||
<li>Fixed post notifications to work properly with multiple notification newsletters sent at the same time;</li>
|
||||
<li>Fixed post notification newsletters to correctly set newsletter status once sending is completed;</li>
|
||||
<li>Fixed post notification newsletters to not send newsletters without any ALC posts;</li>
|
||||
<li>Fixed selecting multiple data fields in subscriber export.</li>
|
||||
<li>Updated HelpScout beacon to provide support articles;</li>
|
||||
<li>Fixed handling of URLs containing shortcodes in newsletter editor;</li>
|
||||
<li>Security fixes;</li>
|
||||
<li>Fixed subscriber count to not count trashed subscribers;</li>
|
||||
<li>Fixed template renderer to gracefully display an error when template caching issues arise;</li>
|
||||
<li>Added security measures to prevent mass subscriptions.</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<h3>0.0.49 - 2016-10-18</h3>
|
||||
<h3>3.0.0-beta.3 - 2016-11-08</h3>
|
||||
<ul>
|
||||
<li>Fixed security issues in Front Router, subscriber import, newsletter preview, admin listings, Idiorm demo code and subscriber verification;</li>
|
||||
<li>Added unit tests for newsletter scheduler;</li>
|
||||
<li>Added "Read more" documentation URL describing "WordPress Users" list in admin listings.</li>
|
||||
<li>Improved compatibility with PHP 7;</li>
|
||||
<li>Fixed showing current newsletter status in newsletter listings when there are no subscribers to send to;</li>
|
||||
<li>Removed obsolete libraries;</li>
|
||||
<li>Fixed security issues;</li>
|
||||
<li>Fixed html form embed code to use correct paths;</li>
|
||||
<li>Updated settings documentation URL;</li>
|
||||
<li>Improved text fitting in newsletter type/template selection boxes;</li>
|
||||
<li>Fixed Populator compatibility with earlier PHP versions;</li>
|
||||
<li>Fixed newsletter number shortcode for notification newsletters;</li>
|
||||
<li>Enhanced HelpScout support beacon report with extra support data;</li>
|
||||
<li>Fixed email renderer to not throw entity warnings on earlier PHP versions;</li>
|
||||
<li>Fixed newsletter preview incompatibility errors for earlier PHP versions.</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
@ -26,8 +26,8 @@
|
||||
<div style="position: absolute; top: .2em; right: 0;"><img src="<%= image_url('welcome_template/mailpoet-logo.png') %>" alt="<%= __('MailPoet Logo') %>" /></div>
|
||||
|
||||
<h2 class="nav-tab-wrapper wp-clearfix">
|
||||
<a href="admin.php?page=mailpoet-welcome" class="nav-tab nav-tab-active"><%= __('What’s New') %></a>
|
||||
<a href="admin.php?page=mailpoet-update" class="nav-tab"><%= __('Changelog') %></a>
|
||||
<a href="admin.php?page=mailpoet-welcome" class="nav-tab nav-tab-active"><%= __('Welcome') %></a>
|
||||
<a href="admin.php?page=mailpoet-update" class="nav-tab"><%= __("What's new") %></a>
|
||||
</h2>
|
||||
|
||||
<div class="headline-feature feature-video">
|
||||
|
@ -150,6 +150,7 @@ config.push(_.extend({}, baseConfig, {
|
||||
'newsletter_editor/behaviors/ResizableBehavior.js',
|
||||
'newsletter_editor/behaviors/SortableBehavior.js',
|
||||
'newsletter_editor/behaviors/ShowSettingsBehavior.js',
|
||||
'newsletter_editor/behaviors/TextEditorBehavior.js',
|
||||
'newsletter_editor/blocks/base.js',
|
||||
'newsletter_editor/blocks/container.js',
|
||||
'newsletter_editor/blocks/button.js',
|
||||
@ -227,6 +228,7 @@ config.push(_.extend({}, baseConfig, {
|
||||
'newsletter_editor/behaviors/ResizableBehavior.js',
|
||||
'newsletter_editor/behaviors/SortableBehavior.js',
|
||||
'newsletter_editor/behaviors/ShowSettingsBehavior.js',
|
||||
'newsletter_editor/behaviors/TextEditorBehavior.js',
|
||||
'newsletter_editor/blocks/base.js',
|
||||
'newsletter_editor/blocks/container.js',
|
||||
'newsletter_editor/blocks/button.js',
|
||||
|