Compare commits
284 Commits
Author | SHA1 | Date | |
---|---|---|---|
1bd8aed192 | |||
cfdf72867e | |||
5888620fc1 | |||
55ba605eb0 | |||
7a73ca7d1a | |||
1918894c5c | |||
0c5589a3e3 | |||
d6eaa4ac8a | |||
b0571b97f5 | |||
6d51ca8011 | |||
d3289dfb84 | |||
bfffdd7274 | |||
c5b8b2aef0 | |||
d7bcf1b817 | |||
f30ed153ce | |||
f436088a16 | |||
db8cb7499d | |||
49c4adc754 | |||
405e743171 | |||
3508ac36b4 | |||
f17c8228cd | |||
3dd5ac0536 | |||
4ebdff49e0 | |||
4a72995bf4 | |||
ef27ac0b84 | |||
2b4adef6c2 | |||
f650455a90 | |||
afbe25e215 | |||
d93249f077 | |||
6223ef77d9 | |||
a423123b66 | |||
1b3d3082b0 | |||
fa117cc7dd | |||
acd407c1f1 | |||
9baf4b068f | |||
18d852e147 | |||
b8dc306741 | |||
6ea056c042 | |||
bcf1b37c6a | |||
2986cdba85 | |||
53a8ae74e2 | |||
8bab01506c | |||
c664045444 | |||
6b8149210d | |||
f31d30b318 | |||
d9fbbdc02d | |||
8136ee2d9b | |||
f7cf6e2131 | |||
f2d1787bd5 | |||
fb51765d3f | |||
088ad5fb42 | |||
2f5b3c0c0a | |||
04ac4d896c | |||
f3b96af863 | |||
eb42b0b98d | |||
304667eb49 | |||
dad1082cd7 | |||
37cf0f3d29 | |||
d61c6dff58 | |||
3734ac578d | |||
b3f56c9d8e | |||
3603eeee77 | |||
59d30cc139 | |||
6ff3bbbb72 | |||
a561e10156 | |||
99f2cf6702 | |||
c6b72e729b | |||
c5bc0f36a4 | |||
efc5c34bf9 | |||
3929efbdd9 | |||
0e0c41882e | |||
79cc708fc6 | |||
8fa98879b8 | |||
331ba385e9 | |||
71ce46d78d | |||
c493de6569 | |||
ff2c2ace86 | |||
7fa789cfd1 | |||
ae6269eb63 | |||
a8f4779bfe | |||
6868142e35 | |||
133d123919 | |||
05c128d12d | |||
bdab0c12fa | |||
75b94690e2 | |||
80fddd6c58 | |||
c807ead5fd | |||
f004bb5368 | |||
1d756e95a7 | |||
1fb0da9fda | |||
a0017b91ee | |||
444ab17342 | |||
44f3058326 | |||
ec09fbcb78 | |||
ed352bb1d3 | |||
375bbd2759 | |||
9fb9d25132 | |||
30f79aa589 | |||
69f8daac95 | |||
03f3a6080c | |||
44f84c6cdb | |||
31008a6895 | |||
2490d8c919 | |||
5886dbfd25 | |||
e48d55f0b1 | |||
42339927cf | |||
b492bcecc0 | |||
6ab7debb7b | |||
b76ce6c26f | |||
6fbc7b1593 | |||
69c8670b01 | |||
da44a87415 | |||
9fb17d4a6b | |||
16dd286f9d | |||
5025f10f9f | |||
1278d9648c | |||
289811a595 | |||
916ae97f73 | |||
876e386966 | |||
9582e58dda | |||
213bca8050 | |||
dc97d3115e | |||
90eb443965 | |||
1b40f02715 | |||
c5a02c6136 | |||
492cd8c96b | |||
7f091d7188 | |||
1c081623b9 | |||
87332037c2 | |||
62023397f4 | |||
37ec6dc1a6 | |||
81c277ca93 | |||
f8fea75130 | |||
a4457649f7 | |||
1d6a09f010 | |||
faec553521 | |||
37fcf3a234 | |||
68a56aada8 | |||
f744305834 | |||
7a9402f5b5 | |||
de6d7e0cae | |||
a3c56b84ce | |||
3d4defd563 | |||
52da08abb2 | |||
b9637b52e9 | |||
0369a23fe8 | |||
f690e1a095 | |||
22e8e34213 | |||
12b46736c5 | |||
4950e47297 | |||
d7c5c8c3e7 | |||
46b0fcf37b | |||
b07c4d0e6e | |||
eb107799a7 | |||
4eec0a42f9 | |||
9a5a3a08c6 | |||
151683c632 | |||
fd2103d1aa | |||
7696b6ec5d | |||
d972b96255 | |||
35ccfb8bcf | |||
7ff036b1e9 | |||
983d56c29b | |||
a2528939ba | |||
c136d91dd2 | |||
bf00e82596 | |||
0e10f6c820 | |||
c056e95249 | |||
1be7fda1cf | |||
0b0c0f5759 | |||
59a4428965 | |||
3f5c36d2d4 | |||
3cc5812c1d | |||
3e616201ad | |||
5558ebad45 | |||
63bd093f35 | |||
ec6559b8be | |||
3421406dc7 | |||
a2917c08f6 | |||
5fa9b5a8dd | |||
41ad86ba1f | |||
067b3ff3e6 | |||
9b9cb1455a | |||
a5569a6a55 | |||
71c1026729 | |||
f102e847bf | |||
3158e2c460 | |||
a438f13bb0 | |||
5ed0a5819c | |||
6dd3c6acda | |||
ca2c1c2e6f | |||
1305a10ee0 | |||
5e36eb818b | |||
cfde82ff5f | |||
af98ade650 | |||
598432466e | |||
9469ce83f1 | |||
5624f4c7a0 | |||
82a001dc05 | |||
a9b424fb79 | |||
d31af9d71c | |||
ff7a24590f | |||
ea87a7acf8 | |||
9d36a17261 | |||
9c3cb5a509 | |||
4dd7f32f3a | |||
1c6fca7f83 | |||
c5b376bd21 | |||
5d2800bc25 | |||
6675d5a20d | |||
28c39d301c | |||
afa0d3af63 | |||
b05344b1d3 | |||
2e88d7cce0 | |||
cb558ce2ab | |||
ed30d8f639 | |||
9410d4f10a | |||
354d249e1d | |||
008fdb94c5 | |||
d0fb94b3f8 | |||
a451f00ed3 | |||
0e0c371b28 | |||
2e52f3bb92 | |||
a3a5016278 | |||
cb5d7cb9a0 | |||
a44d4ed0b5 | |||
7bd23288f6 | |||
08c663759c | |||
c46ee07674 | |||
18398a3bfb | |||
88d9315f8b | |||
8bc95db0c9 | |||
c05a20cff9 | |||
08cb994252 | |||
543ad81e28 | |||
641ba04685 | |||
8e4d07c658 | |||
420650f37f | |||
775f7faee4 | |||
13b91ad051 | |||
2d3ec13473 | |||
3094cfc076 | |||
6aadd1fdc4 | |||
13589a4660 | |||
5f124659d0 | |||
d3ebc9706c | |||
e83d01ff28 | |||
9600e4f220 | |||
3e746d1545 | |||
3cc43aa302 | |||
c610d87e85 | |||
362ee49ce4 | |||
515515ba9f | |||
ed7da1a8fe | |||
12c036dbef | |||
1dd4ade04d | |||
0706450f9a | |||
b837a153d1 | |||
6d22a85fd7 | |||
3d706414b7 | |||
ef0cbb3e9f | |||
f5552847a3 | |||
101ef0cff4 | |||
9e70ba5e6e | |||
8f1a7ed3de | |||
6aa976ba1f | |||
db85604f18 | |||
7605fc71ac | |||
2c98270084 | |||
a5300624c2 | |||
2714c7fa9a | |||
49b65729db | |||
e053b62a70 | |||
88113cf22e | |||
5bf352e9fc | |||
5a7d5ac3f0 | |||
05848ce7aa | |||
b58d996ac7 | |||
16fa4491a5 | |||
456deede14 | |||
4ef50ca551 | |||
5ff7d98b00 | |||
3018dff1ff | |||
9386fe8328 |
15
.circle_ci/apache/mailpoet.loc.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Listen 8080
|
||||||
|
|
||||||
|
<VirtualHost *:8080>
|
||||||
|
UseCanonicalName Off
|
||||||
|
ServerName mailpoet.loc
|
||||||
|
DocumentRoot /home/ubuntu/mailpoet/wordpress
|
||||||
|
DirectoryIndex index.php
|
||||||
|
LogLevel notice
|
||||||
|
|
||||||
|
<Directory /home/ubuntu/mailpoet/wordpress>
|
||||||
|
AllowOverride All
|
||||||
|
Allow from All
|
||||||
|
</Directory>
|
||||||
|
</VirtualHost>
|
||||||
|
|
2
.gitignore
vendored
@ -12,7 +12,7 @@ npm-debug.log
|
|||||||
/views/cache/**
|
/views/cache/**
|
||||||
temp
|
temp
|
||||||
.idea
|
.idea
|
||||||
wysija-newsletters.zip
|
mailpoet.zip
|
||||||
tests/javascript/testBundles
|
tests/javascript/testBundles
|
||||||
assets/css/*.css
|
assets/css/*.css
|
||||||
assets/js/*.js
|
assets/js/*.js
|
||||||
|
47
RoboFile.php
@ -102,31 +102,51 @@ class RoboFile extends \Robo\Tasks {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUnit($file = null) {
|
function testUnit($opts=['file' => null, 'xml' => false]) {
|
||||||
$this->loadEnv();
|
$this->loadEnv();
|
||||||
$this->_exec('vendor/bin/codecept build');
|
$this->_exec('vendor/bin/codecept build');
|
||||||
$this->_exec('vendor/bin/codecept run unit -f '.(($file) ? $file : ''));
|
|
||||||
|
$command = 'vendor/bin/codecept run unit -f '.(($opts['file']) ? $opts['file'] : '');
|
||||||
|
|
||||||
|
if($opts['xml']) {
|
||||||
|
$command .= ' --xml';
|
||||||
|
}
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCoverage($file = null) {
|
function testCoverage($opts=['file' => null, 'xml' => false]) {
|
||||||
$this->loadEnv();
|
$this->loadEnv();
|
||||||
$this->_exec('vendor/bin/codecept build');
|
$this->_exec('vendor/bin/codecept build');
|
||||||
$this->_exec(join(' ', array(
|
$command = join(' ', array(
|
||||||
'vendor/bin/codecept run',
|
'vendor/bin/codecept run',
|
||||||
(($file) ? $file : ''),
|
(($opts['file']) ? $opts['file'] : ''),
|
||||||
'--coverage',
|
'--coverage',
|
||||||
'--coverage-html'
|
($opts['xml']) ? '--coverage-xml' : '--coverage-html'
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if($opts['xml']) {
|
||||||
|
$command .= ' --xml';
|
||||||
|
}
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testJavascript() {
|
function testJavascript($xml_output_file = null) {
|
||||||
$this->compileJs();
|
$this->compileJs();
|
||||||
|
|
||||||
$this->_exec(join(' ', array(
|
$command = join(' ', array(
|
||||||
'./node_modules/.bin/mocha',
|
'./node_modules/.bin/mocha',
|
||||||
'-r tests/javascript/mochaTestHelper.js',
|
'-r tests/javascript/mochaTestHelper.js',
|
||||||
'tests/javascript/testBundles/**/*.js'
|
'tests/javascript/testBundles/**/*.js'
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if(!empty($xml_output_file)) {
|
||||||
|
$command .= sprintf(
|
||||||
|
' --reporter xunit --reporter-options output="%s"',
|
||||||
|
$xml_output_file
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDebug() {
|
function testDebug() {
|
||||||
@ -141,8 +161,13 @@ class RoboFile extends \Robo\Tasks {
|
|||||||
$this->_exec('vendor/bin/codecept run -g failed');
|
$this->_exec('vendor/bin/codecept run -g failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function qa() {
|
||||||
|
$this->qaLint();
|
||||||
|
$this->qaCodeSniffer('all');
|
||||||
|
}
|
||||||
|
|
||||||
function qaLint() {
|
function qaLint() {
|
||||||
$this->_exec('./tasks/php_lint.sh lib/ tests/');
|
$this->_exec('./tasks/php_lint.sh lib/ tests/ mailpoet.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
function qaCodeSniffer($severity='errors') {
|
function qaCodeSniffer($severity='errors') {
|
||||||
|
@ -60,16 +60,20 @@
|
|||||||
.mailpoet_boxes .mailpoet_description
|
.mailpoet_boxes .mailpoet_description
|
||||||
float:left
|
float:left
|
||||||
width: 245px
|
width: 245px
|
||||||
max-height: calc(110px - 2em)
|
max-height: calc(115px - 2em)
|
||||||
padding-bottom: 2em
|
padding-bottom: 2em
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
.mailpoet_boxes .mailpoet_description h3
|
h3
|
||||||
margin: 0 0 1em 0
|
margin: 0 0 0.7em 0
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
white-space: nowrap
|
max-width: 210px
|
||||||
text-overflow: ellipsis
|
line-height: 1.4em
|
||||||
max-width: 220px
|
|
||||||
|
p
|
||||||
|
font-size: 13px
|
||||||
|
line-height: 1.5
|
||||||
|
margin: 1em 0
|
||||||
|
|
||||||
.mailpoet_boxes .mailpoet_actions
|
.mailpoet_boxes .mailpoet_actions
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
$tool-inactive-color = #bbbbbb
|
$tool-inactive-color = #333333
|
||||||
$tool-inactive-secondary-color = #ffffff
|
$tool-inactive-secondary-color = #ffffff
|
||||||
$tool-hover-color = #333333
|
$tool-hover-color = #bbbbbb
|
||||||
$tool-hover-secondary-color = #ffffff
|
$tool-hover-secondary-color = #ffffff
|
||||||
$tool-active-color = #d2d2d4
|
$tool-active-color = #d2d2d4
|
||||||
$tool-active-secondary-color = #ffffff
|
$tool-active-secondary-color = #ffffff
|
||||||
@ -12,21 +12,42 @@ $master-column-tool-width = 24px
|
|||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: 0
|
||||||
right: 0
|
right: 0
|
||||||
display: none
|
|
||||||
z-index: 20
|
z-index: 20
|
||||||
padding: 2px
|
padding: 2px
|
||||||
text-align: right
|
text-align: right
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
position: relative
|
||||||
|
right: -100%
|
||||||
|
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000)
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
&.mailpoet_display_tools
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
right: 0
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
a
|
a
|
||||||
vertical-align: top
|
vertical-align: top
|
||||||
|
|
||||||
.mailpoet_container_horizontal + &
|
.mailpoet_container_horizontal + &
|
||||||
left: 100%
|
left: 100%
|
||||||
|
right: initial
|
||||||
padding-left: 5px
|
padding-left: 5px
|
||||||
|
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
left: -100%
|
||||||
|
right: initial
|
||||||
|
|
||||||
|
&.mailpoet_display_tools
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
left: 0
|
||||||
|
|
||||||
.mailpoet_tool
|
.mailpoet_tool
|
||||||
width: $master-column-tool-width
|
width: $master-column-tool-width
|
||||||
height: $master-column-tool-width
|
height: $master-column-tool-width
|
||||||
|
display: block
|
||||||
|
|
||||||
.mailpoet_tool_icon
|
.mailpoet_tool_icon
|
||||||
width: $master-column-tool-width
|
width: $master-column-tool-width
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.mailpoet_input_title,
|
.mailpoet_input_title,
|
||||||
.mailpoet_input_preheader
|
.mailpoet_input_preheader
|
||||||
width: 400px
|
width: 500px
|
||||||
padding: 3px
|
padding: 3px
|
||||||
line-height: normal
|
line-height: normal
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ $active-social-icon-set-border-color = #adadad
|
|||||||
$active-social-icon-set-background-color = #daebf2
|
$active-social-icon-set-background-color = #daebf2
|
||||||
$social-icon-set-hover-border-color = $primary-active-color
|
$social-icon-set-hover-border-color = $primary-active-color
|
||||||
|
|
||||||
$tool-inactive-color = #bbbbbb
|
$tool-inactive-color = #333333
|
||||||
$tool-hover-color = #333333
|
$tool-hover-color = #bbbbbb
|
||||||
$tool-active-color = #d2d2d4
|
$tool-active-color = #d2d2d4
|
||||||
|
|
||||||
$tool-width = 16px
|
$tool-width = 16px
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
animation-slide-open-downwards()
|
animation-slide-open-downwards($max-height = 2000px)
|
||||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||||
max-height: 2000px
|
max-height: $max-height
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
overflow-y: hidden
|
||||||
|
|
||||||
&.mailpoet_closed
|
&.mailpoet_closed
|
||||||
max-height: 0
|
max-height: 0px
|
||||||
opacity: 0
|
opacity: 0
|
||||||
overflow-y: hidden
|
|
||||||
|
|
||||||
animation-background-color()
|
animation-background-color()
|
||||||
transition: background 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
transition: background 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||||
|
BIN
assets/img/blank_templates/fake-logo.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
BIN
assets/img/sample_templates/discount/bicycle-header2.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/img/sample_templates/discount/bicycle-header3.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/img/sample_templates/discount/orange-bicycle.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
assets/img/sample_templates/discount/red-icycle.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
assets/img/sample_templates/restaurant/boyga-1329911-639x852.jpg
Normal file
After Width: | Height: | Size: 303 KiB |
BIN
assets/img/sample_templates/restaurant/burger.jpg
Normal file
After Width: | Height: | Size: 289 KiB |
BIN
assets/img/sample_templates/restaurant/header.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 498 KiB |
BIN
assets/img/sample_templates/travel/gallery1.jpg
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
assets/img/sample_templates/travel/gallery2.jpg
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
assets/img/sample_templates/travel/gallery3.jpg
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
assets/img/sample_templates/travel/gallery4.jpg
Normal file
After Width: | Height: | Size: 156 KiB |
BIN
assets/img/sample_templates/travel/glow-worms.jpg
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
assets/img/sample_templates/travel/header.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
assets/img/sample_templates/travel/holiday-park.jpg
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
assets/img/sample_templates/travel/luge.jpg
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
assets/img/welcome_template/beacon.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.8 KiB |
BIN
assets/img/welcome_template/mailpoet-logo.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
@ -1,4 +1,4 @@
|
|||||||
define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
define('ajax', ['mailpoet', 'jquery', 'underscore'], function(MailPoet, jQuery, _) {
|
||||||
'use strict';
|
'use strict';
|
||||||
MailPoet.Ajax = {
|
MailPoet.Ajax = {
|
||||||
version: 0.5,
|
version: 0.5,
|
||||||
@ -8,19 +8,11 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
endpoint: null,
|
endpoint: null,
|
||||||
action: null,
|
action: null,
|
||||||
token: null,
|
token: null,
|
||||||
data: {},
|
data: {}
|
||||||
onSuccess: function(data, textStatus, xhr) {},
|
|
||||||
onError: function(xhr, textStatus, errorThrown) {}
|
|
||||||
},
|
|
||||||
get: function(options) {
|
|
||||||
return this.request('get', options);
|
|
||||||
},
|
},
|
||||||
post: function(options) {
|
post: function(options) {
|
||||||
return this.request('post', options);
|
return this.request('post', options);
|
||||||
},
|
},
|
||||||
delete: function(options) {
|
|
||||||
return this.request('delete', options);
|
|
||||||
},
|
|
||||||
init: function(options) {
|
init: function(options) {
|
||||||
// merge options
|
// merge options
|
||||||
this.options = jQuery.extend({}, this.defaults, options);
|
this.options = jQuery.extend({}, this.defaults, options);
|
||||||
@ -50,31 +42,31 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
|
|
||||||
// set request params
|
// set request params
|
||||||
var params = this.getParams();
|
var params = this.getParams();
|
||||||
var jqXHR;
|
var deferred = jQuery.Deferred();
|
||||||
|
|
||||||
// make ajax request depending on method
|
// remove null values from the data object
|
||||||
if(method === 'get') {
|
if (_.isObject(params.data)) {
|
||||||
jqXHR = jQuery.get(
|
params.data = _.pick(params.data, function(value) {
|
||||||
this.options.url,
|
return (value !== null)
|
||||||
params,
|
})
|
||||||
this.options.onSuccess,
|
|
||||||
'json'
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
jqXHR = jQuery.ajax({
|
|
||||||
url: this.options.url,
|
|
||||||
type : 'post',
|
|
||||||
data: params,
|
|
||||||
dataType: 'json',
|
|
||||||
success : this.options.onSuccess,
|
|
||||||
error : this.options.onError
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ajax request
|
||||||
|
deferred = jQuery.post(
|
||||||
|
this.options.url,
|
||||||
|
params,
|
||||||
|
null,
|
||||||
|
'json'
|
||||||
|
).then(function(data) {
|
||||||
|
return data;
|
||||||
|
}, function(xhr) {
|
||||||
|
return xhr.responseJSON;
|
||||||
|
});
|
||||||
|
|
||||||
// clear options
|
// clear options
|
||||||
this.options = {};
|
this.options = {};
|
||||||
|
|
||||||
return jqXHR;
|
return deferred;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
define(
|
|
||||||
[
|
|
||||||
'react',
|
|
||||||
'react-dom',
|
|
||||||
'mailpoet'
|
|
||||||
],
|
|
||||||
function(
|
|
||||||
React,
|
|
||||||
ReactDOM,
|
|
||||||
MailPoet
|
|
||||||
) {
|
|
||||||
var CronControl = React.createClass({
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
status: 'loading'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getCronData: function() {
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'cron',
|
|
||||||
action: 'getStatus'
|
|
||||||
})
|
|
||||||
.done(function(response) {
|
|
||||||
jQuery('.button-primary')
|
|
||||||
.removeClass('disabled');
|
|
||||||
if(response.status !== undefined) {
|
|
||||||
this.setState(response);
|
|
||||||
} else {
|
|
||||||
this.replaceState();
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
componentDidMount: function() {
|
|
||||||
if(this.isMounted()) {
|
|
||||||
this.getCronData();
|
|
||||||
setInterval(this.getCronData, 5000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
controlCron: function(action) {
|
|
||||||
if(jQuery('.button-primary').hasClass('disabled')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
jQuery('.button-primary')
|
|
||||||
.addClass('disabled');
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'cron',
|
|
||||||
action: action,
|
|
||||||
})
|
|
||||||
.done(function(response) {
|
|
||||||
if(!response.result) {
|
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('daemonControlError'));
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
if(this.state.status === 'loading') {
|
|
||||||
return(<div>{MailPoet.I18n.t('loadingDaemonStatus')}</div>);
|
|
||||||
}
|
|
||||||
switch(this.state.status) {
|
|
||||||
case 'started':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
{MailPoet.I18n.t('cronDaemonIsRunning')}
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'stop')}>{MailPoet.I18n.t('stop')}</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'starting':
|
|
||||||
case 'stopping':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
{MailPoet.I18n.t('cronDaemonState').replace('%$1s', this.state.status)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'stopped':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
{MailPoet.I18n.t('cronDaemonState').replace('%$1s', this.state.status)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'start')}>{MailPoet.I18n.t('start')}</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const container = document.getElementById('cron_container');
|
|
||||||
|
|
||||||
if(container) {
|
|
||||||
ReactDOM.render(
|
|
||||||
<CronControl />,
|
|
||||||
container
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
@ -127,37 +127,12 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateType = this.props.field.params.date_type;
|
const dateTime = Moment(value);
|
||||||
const dateParts = value.split('-');
|
|
||||||
let year = '';
|
|
||||||
let month = '';
|
|
||||||
let day = '';
|
|
||||||
|
|
||||||
switch(dateType) {
|
|
||||||
case 'year_month_day':
|
|
||||||
year = ~~(dateParts[0]);
|
|
||||||
month = ~~(dateParts[1]);
|
|
||||||
day = ~~(dateParts[2]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'year_month':
|
|
||||||
year = ~~(dateParts[0]);
|
|
||||||
month = ~~(dateParts[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'month':
|
|
||||||
month = ~~(dateParts[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'year':
|
|
||||||
year = ~~(dateParts[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
year: year,
|
year: dateTime.format('YYYY'),
|
||||||
month: month,
|
month: dateTime.format('M'),
|
||||||
day: day
|
day: dateTime.format('D')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
formatValue() {
|
formatValue() {
|
||||||
@ -228,7 +203,7 @@ define([
|
|||||||
|
|
||||||
const fields = dateSelects.map(type => {
|
const fields = dateSelects.map(type => {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 'yyyy':
|
case 'YYYY':
|
||||||
return (<FormFieldDateYear
|
return (<FormFieldDateYear
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'year' }
|
ref={ 'year' }
|
||||||
@ -239,7 +214,7 @@ define([
|
|||||||
/>);
|
/>);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'mm':
|
case 'MM':
|
||||||
return (<FormFieldDateMonth
|
return (<FormFieldDateMonth
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'month' }
|
ref={ 'month' }
|
||||||
@ -251,7 +226,7 @@ define([
|
|||||||
/>);
|
/>);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dd':
|
case 'DD':
|
||||||
return (<FormFieldDateDay
|
return (<FormFieldDateDay
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'day' }
|
ref={ 'day' }
|
||||||
|
@ -66,22 +66,22 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'get',
|
action: 'get',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
if(response === false) {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
item: {}
|
|
||||||
}, function() {
|
|
||||||
this.context.router.push('/new');
|
|
||||||
}.bind(this));
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
item: response
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}).done((response) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
item: response.data
|
||||||
|
});
|
||||||
|
}).fail((response) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
item: {}
|
||||||
|
}, function() {
|
||||||
|
this.context.router.push('/new');
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleSubmit: function(e) {
|
handleSubmit: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -115,29 +115,25 @@ define(
|
|||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: item
|
data: item
|
||||||
}).done(function(response) {
|
}).always(() => {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
|
}).done((response) => {
|
||||||
if(response.result === true) {
|
if(this.props.onSuccess !== undefined) {
|
||||||
if(this.props.onSuccess !== undefined) {
|
this.props.onSuccess();
|
||||||
this.props.onSuccess();
|
|
||||||
} else {
|
|
||||||
this.context.router.push('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.props.params.id !== undefined) {
|
|
||||||
this.props.messages.onUpdate();
|
|
||||||
} else {
|
|
||||||
this.props.messages.onCreate();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(response.result === false) {
|
this.context.router.push('/');
|
||||||
if(response.errors.length > 0) {
|
|
||||||
this.setState({ errors: response.errors });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
|
||||||
|
if(this.props.params.id !== undefined) {
|
||||||
|
this.props.messages.onUpdate();
|
||||||
|
} else {
|
||||||
|
this.props.messages.onCreate();
|
||||||
|
}
|
||||||
|
}).fail((response) => {
|
||||||
|
if(response.errors.length > 0) {
|
||||||
|
this.setState({ errors: response.errors });
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleValueChange: function(e) {
|
handleValueChange: function(e) {
|
||||||
if (this.props.onChange) {
|
if (this.props.onChange) {
|
||||||
@ -159,7 +155,7 @@ define(
|
|||||||
var errors = this.getErrors().map(function(error, index) {
|
var errors = this.getErrors().map(function(error, index) {
|
||||||
return (
|
return (
|
||||||
<p key={ 'error-'+index } className="mailpoet_error">
|
<p key={ 'error-'+index } className="mailpoet_error">
|
||||||
{ error }
|
{ error.message }
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -15,6 +15,10 @@ const columns = [
|
|||||||
name: 'segments',
|
name: 'segments',
|
||||||
label: MailPoet.I18n.t('segments')
|
label: MailPoet.I18n.t('segments')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'signups',
|
||||||
|
label: MailPoet.I18n.t('signups')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'created_at',
|
name: 'created_at',
|
||||||
label: MailPoet.I18n.t('createdOn'),
|
label: MailPoet.I18n.t('createdOn'),
|
||||||
@ -23,48 +27,48 @@ const columns = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash: function(response) {
|
onTrash: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneFormTrashed')
|
MailPoet.I18n.t('oneFormTrashed')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleFormsTrashed')
|
MailPoet.I18n.t('multipleFormsTrashed')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete: function(response) {
|
onDelete: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneFormDeleted')
|
MailPoet.I18n.t('oneFormDeleted')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleFormsDeleted')
|
MailPoet.I18n.t('multipleFormsDeleted')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore: function(response) {
|
onRestore: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneFormRestored')
|
MailPoet.I18n.t('oneFormRestored')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleFormsRestored')
|
MailPoet.I18n.t('multipleFormsRestored')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
@ -95,14 +99,21 @@ const item_actions = [
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'forms',
|
endpoint: 'forms',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: item.id
|
data: {
|
||||||
}).done(function(response) {
|
id: item.id
|
||||||
if (response !== false && response['name'] !== undefined) {
|
}
|
||||||
MailPoet.Notice.success(
|
}).done((response) => {
|
||||||
(MailPoet.I18n.t('formDuplicated')).replace('%$1s', response.name)
|
MailPoet.Notice.success(
|
||||||
|
(MailPoet.I18n.t('formDuplicated')).replace('%$1s', response.data.name)
|
||||||
|
);
|
||||||
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
refresh();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -116,9 +127,14 @@ const FormList = React.createClass({
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'forms',
|
endpoint: 'forms',
|
||||||
action: 'create'
|
action: 'create'
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.form_id) {
|
window.location = mailpoet_form_edit_url + response.data.id;
|
||||||
window.location = mailpoet_form_edit_url + response.form_id;
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -146,9 +162,12 @@ const FormList = React.createClass({
|
|||||||
</strong>
|
</strong>
|
||||||
{ actions }
|
{ actions }
|
||||||
</td>
|
</td>
|
||||||
<td className="column-format" data-colname={MailPoet.I18n.t('segments')}>
|
<td className="column" data-colname={MailPoet.I18n.t('segments')}>
|
||||||
{ segments }
|
{ segments }
|
||||||
</td>
|
</td>
|
||||||
|
<td className="column" data-colname={MailPoet.I18n.t('signups')}>
|
||||||
|
{ form.signups }
|
||||||
|
</td>
|
||||||
<td className="column-date" data-colname={MailPoet.I18n.t('createdOn')}>
|
<td className="column-date" data-colname={MailPoet.I18n.t('createdOn')}>
|
||||||
<abbr>{ MailPoet.Date.format(form.created_at) }</abbr>
|
<abbr>{ MailPoet.Date.format(form.created_at) }</abbr>
|
||||||
</td>
|
</td>
|
||||||
|
@ -53,7 +53,10 @@ function(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(data.action) {
|
if(data.action) {
|
||||||
this.props.onBulkAction(selected_ids, data).then(onSuccess);
|
const promise = this.props.onBulkAction(selected_ids, data);
|
||||||
|
if (promise !== false) {
|
||||||
|
promise.then(onSuccess);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import MailPoet from 'mailpoet'
|
import MailPoet from 'mailpoet'
|
||||||
import jQuery from 'jquery'
|
import jQuery from 'jquery'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import _ from 'underscore'
|
||||||
import { Router, Link } from 'react-router'
|
import { Router, Link } from 'react-router'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import ListingBulkActions from 'listing/bulk_actions.jsx'
|
import ListingBulkActions from 'listing/bulk_actions.jsx'
|
||||||
@ -13,7 +14,7 @@ import ListingFilters from 'listing/filters.jsx'
|
|||||||
const ListingItem = React.createClass({
|
const ListingItem = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
toggled: true
|
expanded: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSelectItem: function(e) {
|
handleSelectItem: function(e) {
|
||||||
@ -34,7 +35,7 @@ const ListingItem = React.createClass({
|
|||||||
this.props.onDeleteItem(id);
|
this.props.onDeleteItem(id);
|
||||||
},
|
},
|
||||||
handleToggleItem: function(id) {
|
handleToggleItem: function(id) {
|
||||||
this.setState({ toggled: !this.state.toggled });
|
this.setState({ expanded: !this.state.expanded });
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var checkbox = false;
|
var checkbox = false;
|
||||||
@ -182,7 +183,7 @@ const ListingItem = React.createClass({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const row_classes = classNames({ 'is-expanded': !this.state.toggled });
|
const row_classes = classNames({ 'is-expanded': this.state.expanded });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className={ row_classes }>
|
<tr className={ row_classes }>
|
||||||
@ -303,13 +304,12 @@ const Listing = React.createClass({
|
|||||||
getParam: function(param) {
|
getParam: function(param) {
|
||||||
const regex = /(.*)\[(.*)\]/;
|
const regex = /(.*)\[(.*)\]/;
|
||||||
const matches = regex.exec(param);
|
const matches = regex.exec(param);
|
||||||
return [matches[1], matches[2]]
|
return [matches[1], matches[2]];
|
||||||
},
|
},
|
||||||
initWithParams: function(params) {
|
initWithParams: function(params) {
|
||||||
let state = this.getInitialState();
|
let state = this.getInitialState();
|
||||||
|
|
||||||
// check for url params
|
// check for url params
|
||||||
if (params.splat !== undefined) {
|
if (params.splat) {
|
||||||
params.splat.split('/').map(param => {
|
params.splat.split('/').map(param => {
|
||||||
let [key, value] = this.getParam(param);
|
let [key, value] = this.getParam(param);
|
||||||
switch(key) {
|
switch(key) {
|
||||||
@ -348,6 +348,17 @@ const Listing = React.createClass({
|
|||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
getParams: function() {
|
||||||
|
// get all route parameters (without the "splat")
|
||||||
|
let params = _.omit(this.props.params, 'splat');
|
||||||
|
// TODO:
|
||||||
|
// find a way to set the "type" in the routes definition
|
||||||
|
// so that it appears in `this.props.params`
|
||||||
|
if (this.props.type) {
|
||||||
|
params.type = this.props.type;
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
},
|
||||||
setParams: function() {
|
setParams: function() {
|
||||||
if (this.props.location) {
|
if (this.props.location) {
|
||||||
let params = Object.keys(this.state)
|
let params = Object.keys(this.state)
|
||||||
@ -378,18 +389,38 @@ const Listing = React.createClass({
|
|||||||
.filter(key => { return (key !== undefined) })
|
.filter(key => { return (key !== undefined) })
|
||||||
.join('/');
|
.join('/');
|
||||||
|
|
||||||
// prepend url with "tab" if specified
|
// set url
|
||||||
if (this.props.tab !== undefined) {
|
let url = this.getUrlWithParams(params);
|
||||||
params = `/${ this.props.tab }/${ params }`;
|
|
||||||
} else {
|
|
||||||
params = `/${ params }`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.location.pathname !== params) {
|
if (this.props.location.pathname !== url) {
|
||||||
this.context.router.push(`${params}`);
|
this.context.router.push(`${url}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getUrlWithParams: function(params) {
|
||||||
|
let base_url = (this.props.base_url !== undefined)
|
||||||
|
? this.props.base_url
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (base_url !== null) {
|
||||||
|
base_url = this.setBaseUrlParams(base_url);
|
||||||
|
return `/${ base_url }/${ params }`;
|
||||||
|
} else {
|
||||||
|
return `/${ params }`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setBaseUrlParams: function(base_url) {
|
||||||
|
if (base_url.indexOf(':') !== -1) {
|
||||||
|
const params = this.getParams();
|
||||||
|
Object.keys(params).map((key) => {
|
||||||
|
if (base_url.indexOf(':'+key) !== -1) {
|
||||||
|
base_url = base_url.replace(':'+key, params[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_url;
|
||||||
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
if (this.isMounted()) {
|
if (this.isMounted()) {
|
||||||
const params = this.props.params || {};
|
const params = this.props.params || {};
|
||||||
@ -416,7 +447,7 @@ const Listing = React.createClass({
|
|||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'listing',
|
action: 'listing',
|
||||||
data: {
|
data: {
|
||||||
tab: (this.props.tab) ? this.props.tab : '',
|
params: this.getParams(),
|
||||||
offset: (this.state.page - 1) * this.state.limit,
|
offset: (this.state.page - 1) * this.state.limit,
|
||||||
limit: this.state.limit,
|
limit: this.state.limit,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
@ -425,22 +456,29 @@ const Listing = React.createClass({
|
|||||||
sort_by: this.state.sort_by,
|
sort_by: this.state.sort_by,
|
||||||
sort_order: this.state.sort_order
|
sort_order: this.state.sort_order
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).always(() => {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}).done((response) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
items: response.items || [],
|
items: response.data || [],
|
||||||
filters: response.filters || {},
|
filters: response.meta.filters || {},
|
||||||
groups: response.groups || [],
|
groups: response.meta.groups || [],
|
||||||
count: response.count || 0,
|
count: response.meta.count || 0
|
||||||
loading: false
|
}, () => {
|
||||||
}, function() {
|
// if viewing an empty trash
|
||||||
if (this.props['onGetItems'] !== undefined) {
|
if (this.state.group === 'trash' && response.meta.count === 0) {
|
||||||
const count = (response.groups[0] !== undefined)
|
// redirect to default group
|
||||||
? ~~(response.groups[0].count)
|
this.handleGroup('all');
|
||||||
: 0;
|
|
||||||
this.props.onGetItems(count);
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
}.bind(this));
|
}).fail(function(response) {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleRestoreItem: function(id) {
|
handleRestoreItem: function(id) {
|
||||||
@ -452,8 +490,10 @@ const Listing = React.createClass({
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'restore',
|
action: 'restore',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onRestore'] !== undefined
|
&& this.props.messages['onRestore'] !== undefined
|
||||||
@ -461,7 +501,12 @@ const Listing = React.createClass({
|
|||||||
this.props.messages.onRestore(response);
|
this.props.messages.onRestore(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleTrashItem: function(id) {
|
handleTrashItem: function(id) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -472,8 +517,10 @@ const Listing = React.createClass({
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'trash',
|
action: 'trash',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onTrash'] !== undefined
|
&& this.props.messages['onTrash'] !== undefined
|
||||||
@ -481,7 +528,12 @@ const Listing = React.createClass({
|
|||||||
this.props.messages.onTrash(response);
|
this.props.messages.onTrash(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleDeleteItem: function(id) {
|
handleDeleteItem: function(id) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -492,8 +544,10 @@ const Listing = React.createClass({
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onDelete'] !== undefined
|
&& this.props.messages['onDelete'] !== undefined
|
||||||
@ -501,22 +555,29 @@ const Listing = React.createClass({
|
|||||||
this.props.messages.onDelete(response);
|
this.props.messages.onDelete(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleEmptyTrash: function() {
|
handleEmptyTrash: function() {
|
||||||
return this.handleBulkAction('all', {
|
return this.handleBulkAction('all', {
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
group: 'trash'
|
group: 'trash'
|
||||||
}).then(function(response) {
|
}).done((response) => {
|
||||||
if (~~(response) > 0) {
|
MailPoet.Notice.success(
|
||||||
MailPoet.Notice.success(
|
MailPoet.I18n.t('permanentlyDeleted').replace('%d', response.meta.count)
|
||||||
MailPoet.I18n.t('permanentlyDeleted').replace('%d', response)
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// redirect to default group
|
// redirect to default group
|
||||||
this.handleGroup('all');
|
this.handleGroup('all');
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleBulkAction: function(selected_ids, params) {
|
handleBulkAction: function(selected_ids, params) {
|
||||||
if (
|
if (
|
||||||
@ -524,14 +585,14 @@ const Listing = React.createClass({
|
|||||||
&& this.state.selected_ids.length === 0
|
&& this.state.selected_ids.length === 0
|
||||||
&& selected_ids !== 'all'
|
&& selected_ids !== 'all'
|
||||||
) {
|
) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
|
|
||||||
var data = params || {};
|
var data = params || {};
|
||||||
data.listing = {
|
data.listing = {
|
||||||
tab: (this.props.tab) ? this.props.tab : '',
|
params: this.getParams(),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
filter: this.state.filter,
|
filter: this.state.filter,
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Show Settings Behavior
|
||||||
|
*
|
||||||
|
* Opens up settings of a BlockView if contents are clicked upon
|
||||||
|
*/
|
||||||
|
define([
|
||||||
|
'backbone.marionette',
|
||||||
|
'jquery',
|
||||||
|
'newsletter_editor/behaviors/BehaviorsLookup',
|
||||||
|
], function(Marionette, jQuery, BehaviorsLookup) {
|
||||||
|
|
||||||
|
BehaviorsLookup.ShowSettingsBehavior = Marionette.Behavior.extend({
|
||||||
|
defaults: {
|
||||||
|
ignoreFrom: '', // selector
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
'click .mailpoet_content': 'showSettings',
|
||||||
|
},
|
||||||
|
showSettings: function(event) {
|
||||||
|
if(!this.isIgnoredElement(event.target)) {
|
||||||
|
this.view.triggerMethod('showSettings');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isIgnoredElement: function(element) {
|
||||||
|
return this.options.ignoreFrom
|
||||||
|
&& this.options.ignoreFrom.length > 0
|
||||||
|
&& jQuery(element).is(this.options.ignoreFrom);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -35,7 +35,12 @@ define([
|
|||||||
|
|
||||||
Module.ALCSupervisor = SuperModel.extend({
|
Module.ALCSupervisor = SuperModel.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.listenTo(App.getChannel(), 'automatedLatestContentRefresh', this.refresh);
|
var DELAY_REFRESH_FOR_MS = 500;
|
||||||
|
this.listenTo(
|
||||||
|
App.getChannel(),
|
||||||
|
'automatedLatestContentRefresh',
|
||||||
|
_.debounce(this.refresh, DELAY_REFRESH_FOR_MS)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
var models = App.findModels(function(model) {
|
var models = App.findModels(function(model) {
|
||||||
@ -107,9 +112,7 @@ define([
|
|||||||
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:featuredImagePosition change:titleAlignment change:titleIsLink change:imageFullWidth change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
|
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:featuredImagePosition change:titleAlignment change:titleIsLink change:imageFullWidth change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
|
||||||
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
|
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
|
||||||
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
|
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
|
||||||
this.on('add remove update reset', function(model, collection, options) {
|
this.on('add remove update reset', this._scheduleFetchPosts);
|
||||||
App.getChannel().trigger('automatedLatestContentRefresh');
|
|
||||||
});
|
|
||||||
this.on('refreshPosts', this.updatePosts, this);
|
this.on('refreshPosts', this.updatePosts, this);
|
||||||
},
|
},
|
||||||
updatePosts: function(posts) {
|
updatePosts: function(posts) {
|
||||||
@ -120,16 +123,7 @@ define([
|
|||||||
* ALC posts on each model change
|
* ALC posts on each model change
|
||||||
*/
|
*/
|
||||||
_scheduleFetchPosts: function() {
|
_scheduleFetchPosts: function() {
|
||||||
var TIMEOUT = 500,
|
App.getChannel().trigger('automatedLatestContentRefresh');
|
||||||
that = this;
|
|
||||||
if (this._fetchPostsTimer !== undefined) {
|
|
||||||
clearTimeout(this._fetchPostsTimer);
|
|
||||||
}
|
|
||||||
this._fetchPostsTimer = setTimeout(function() {
|
|
||||||
//that.fetchPosts();
|
|
||||||
App.getChannel().trigger('automatedLatestContentRefresh');
|
|
||||||
that._fetchPostsTimer = undefined;
|
|
||||||
}, TIMEOUT);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -180,17 +174,17 @@ define([
|
|||||||
"change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat',
|
"change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat',
|
||||||
"change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
"change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
||||||
"change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
"change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
||||||
"keyup .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"),
|
"input .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"),
|
||||||
"change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"),
|
"change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"),
|
||||||
"change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
"change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
||||||
"change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
"change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
||||||
"change .mailpoet_automated_latest_content_image_full_width": _.partial(this.changeBoolField, "imageFullWidth"),
|
"change .mailpoet_automated_latest_content_image_full_width": _.partial(this.changeBoolField, "imageFullWidth"),
|
||||||
"change .mailpoet_automated_latest_content_featured_image_position": _.partial(this.changeField, "featuredImagePosition"),
|
"change .mailpoet_automated_latest_content_featured_image_position": _.partial(this.changeField, "featuredImagePosition"),
|
||||||
"change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"),
|
"change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"),
|
||||||
"keyup .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
"input .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
||||||
"change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"),
|
"change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"),
|
||||||
"keyup .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
"input .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
||||||
"keyup .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"),
|
"input .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"),
|
||||||
"change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"),
|
"change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"),
|
||||||
"click .mailpoet_done_editing": "close",
|
"click .mailpoet_done_editing": "close",
|
||||||
};
|
};
|
||||||
@ -217,8 +211,10 @@ define([
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
transport: function(options, success, failure) {
|
transport: function(options, success, failure) {
|
||||||
var taxonomies,
|
var taxonomies;
|
||||||
promise = CommunicationComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
|
var promise = CommunicationComponent.getTaxonomies(
|
||||||
|
that.model.get('contentType')
|
||||||
|
).then(function(tax) {
|
||||||
taxonomies = tax;
|
taxonomies = tax;
|
||||||
// Fetch available terms based on the list of taxonomies already fetched
|
// Fetch available terms based on the list of taxonomies already fetched
|
||||||
var promise = CommunicationComponent.getTerms({
|
var promise = CommunicationComponent.getTerms({
|
||||||
@ -227,7 +223,7 @@ define([
|
|||||||
}).then(function(terms) {
|
}).then(function(terms) {
|
||||||
return {
|
return {
|
||||||
taxonomies: taxonomies,
|
taxonomies: taxonomies,
|
||||||
terms: terms,
|
terms: terms
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return promise;
|
return promise;
|
||||||
|
@ -99,12 +99,12 @@ define([
|
|||||||
},
|
},
|
||||||
showTools: function(_event) {
|
showTools: function(_event) {
|
||||||
if (!this.showingToolsDisabled) {
|
if (!this.showingToolsDisabled) {
|
||||||
this.$('> .mailpoet_tools').show();
|
this.$('> .mailpoet_tools').addClass('mailpoet_display_tools');
|
||||||
this.toolsView.triggerMethod('showTools');
|
this.toolsView.triggerMethod('showTools');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideTools: function(e) {
|
hideTools: function(e) {
|
||||||
this.$('> .mailpoet_tools').hide();
|
this.$('> .mailpoet_tools').removeClass('mailpoet_display_tools');
|
||||||
this.toolsView.triggerMethod('hideTools');
|
this.toolsView.triggerMethod('hideTools');
|
||||||
},
|
},
|
||||||
enableShowingTools: function() {
|
enableShowingTools: function() {
|
||||||
|
@ -19,7 +19,7 @@ define([
|
|||||||
return this._getDefaults({
|
return this._getDefaults({
|
||||||
type: 'button',
|
type: 'button',
|
||||||
text: 'Button',
|
text: 'Button',
|
||||||
url: 'http://google.com',
|
url: '',
|
||||||
styles: {
|
styles: {
|
||||||
block: {
|
block: {
|
||||||
backgroundColor: '#ff0000',
|
backgroundColor: '#ff0000',
|
||||||
@ -44,6 +44,9 @@ define([
|
|||||||
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
|
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
|
||||||
getTemplate: function() { return templates.buttonBlock; },
|
getTemplate: function() { return templates.buttonBlock; },
|
||||||
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
|
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
|
||||||
|
behaviors: _.extend({}, base.BlockView.prototype.behaviors, {
|
||||||
|
ShowSettingsBehavior: {},
|
||||||
|
}),
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
@ -65,8 +68,8 @@ define([
|
|||||||
getTemplate: function() { return templates.buttonBlockSettings; },
|
getTemplate: function() { return templates.buttonBlockSettings; },
|
||||||
events: function() {
|
events: function() {
|
||||||
return {
|
return {
|
||||||
"keyup .mailpoet_field_button_text": _.partial(this.changeField, "text"),
|
"input .mailpoet_field_button_text": _.partial(this.changeField, "text"),
|
||||||
"keyup .mailpoet_field_button_url": _.partial(this.changeField, "url"),
|
"input .mailpoet_field_button_url": _.partial(this.changeField, "url"),
|
||||||
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
||||||
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
|
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
|
||||||
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
|
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
|
||||||
@ -77,23 +80,19 @@ define([
|
|||||||
|
|
||||||
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"input .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"keyup .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
|
||||||
|
|
||||||
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"change .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
"input .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
||||||
"keyup .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
|
|
||||||
|
|
||||||
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"change .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
"input .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
||||||
"keyup .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
|
|
||||||
|
|
||||||
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
"change .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
"input .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
||||||
"keyup .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
|
|
||||||
|
|
||||||
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
|
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
|
||||||
"click .mailpoet_done_editing": "close",
|
"click .mailpoet_done_editing": "close",
|
||||||
|
@ -186,13 +186,13 @@ define([
|
|||||||
},
|
},
|
||||||
showTools: function() {
|
showTools: function() {
|
||||||
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
||||||
this.$(this.ui.tools).show();
|
this.$(this.ui.tools).addClass('mailpoet_display_tools');
|
||||||
this.toolsView.triggerMethod('showTools');
|
this.toolsView.triggerMethod('showTools');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideTools: function() {
|
hideTools: function() {
|
||||||
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
|
||||||
this.$(this.ui.tools).hide();
|
this.$(this.ui.tools).removeClass('mailpoet_display_tools');
|
||||||
this.toolsView.triggerMethod('hideTools');
|
this.toolsView.triggerMethod('hideTools');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,6 +43,9 @@ define([
|
|||||||
minLength: 0, // TODO: Move this number to editor configuration
|
minLength: 0, // TODO: Move this number to editor configuration
|
||||||
modelField: 'styles.block.padding',
|
modelField: 'styles.block.padding',
|
||||||
},
|
},
|
||||||
|
ShowSettingsBehavior: {
|
||||||
|
ignoreFrom: '.mailpoet_resize_handle'
|
||||||
|
},
|
||||||
}, base.BlockView.prototype.behaviors),
|
}, base.BlockView.prototype.behaviors),
|
||||||
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
|
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
@ -88,8 +91,7 @@ define([
|
|||||||
|
|
||||||
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"change .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
"input .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
||||||
"keyup .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
|
|
||||||
|
|
||||||
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
|
||||||
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
|
||||||
|
@ -17,8 +17,8 @@ define([
|
|||||||
defaults: function() {
|
defaults: function() {
|
||||||
return this._getDefaults({
|
return this._getDefaults({
|
||||||
type: 'image',
|
type: 'image',
|
||||||
link: 'http://example.org',
|
link: '',
|
||||||
src: 'no-image.png',
|
src: '',
|
||||||
alt: 'An image of...',
|
alt: 'An image of...',
|
||||||
fullWidth: true, // true | false
|
fullWidth: true, // true | false
|
||||||
width: '64px',
|
width: '64px',
|
||||||
@ -41,6 +41,9 @@ define([
|
|||||||
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
|
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
|
||||||
}, base.BlockView.prototype.templateHelpers.apply(this));
|
}, base.BlockView.prototype.templateHelpers.apply(this));
|
||||||
},
|
},
|
||||||
|
behaviors: _.extend({}, base.BlockView.prototype.behaviors, {
|
||||||
|
ShowSettingsBehavior: {},
|
||||||
|
}),
|
||||||
onRender: function() {
|
onRender: function() {
|
||||||
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
|
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
|
||||||
this.toolsRegion.show(this.toolsView);
|
this.toolsRegion.show(this.toolsView);
|
||||||
@ -61,9 +64,9 @@ define([
|
|||||||
getTemplate: function() { return templates.imageBlockSettings; },
|
getTemplate: function() { return templates.imageBlockSettings; },
|
||||||
events: function() {
|
events: function() {
|
||||||
return {
|
return {
|
||||||
"keyup .mailpoet_field_image_link": _.partial(this.changeField, "link"),
|
"input .mailpoet_field_image_link": _.partial(this.changeField, "link"),
|
||||||
"keyup .mailpoet_field_image_address": _.partial(this.changeField, "src"),
|
"input .mailpoet_field_image_address": _.partial(this.changeField, "src"),
|
||||||
"keyup .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
|
"input .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
|
||||||
"change .mailpoet_field_image_full_width": _.partial(this.changeBoolCheckboxField, "fullWidth"),
|
"change .mailpoet_field_image_full_width": _.partial(this.changeBoolCheckboxField, "fullWidth"),
|
||||||
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
|
||||||
"click .mailpoet_field_image_select_another_image": "showMediaManager",
|
"click .mailpoet_field_image_select_another_image": "showMediaManager",
|
||||||
|
@ -273,7 +273,7 @@ define([
|
|||||||
return {
|
return {
|
||||||
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'),
|
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'),
|
||||||
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'),
|
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'),
|
||||||
'keyup .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
|
'input .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
constructor: function() {
|
constructor: function() {
|
||||||
@ -302,8 +302,10 @@ define([
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
transport: function(options, success, failure) {
|
transport: function(options, success, failure) {
|
||||||
var taxonomies,
|
var taxonomies;
|
||||||
promise = CommunicationComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
|
var promise = CommunicationComponent.getTaxonomies(
|
||||||
|
that.model.get('contentType')
|
||||||
|
).then(function(tax) {
|
||||||
taxonomies = tax;
|
taxonomies = tax;
|
||||||
// Fetch available terms based on the list of taxonomies already fetched
|
// Fetch available terms based on the list of taxonomies already fetched
|
||||||
var promise = CommunicationComponent.getTerms({
|
var promise = CommunicationComponent.getTerms({
|
||||||
@ -312,7 +314,7 @@ define([
|
|||||||
}).then(function(terms) {
|
}).then(function(terms) {
|
||||||
return {
|
return {
|
||||||
taxonomies: taxonomies,
|
taxonomies: taxonomies,
|
||||||
terms: terms,
|
terms: terms
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return promise;
|
return promise;
|
||||||
@ -412,17 +414,17 @@ define([
|
|||||||
"change .mailpoet_posts_title_format": 'changeTitleFormat',
|
"change .mailpoet_posts_title_format": 'changeTitleFormat',
|
||||||
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
|
||||||
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
|
||||||
"keyup .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
|
"input .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
|
||||||
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
|
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
|
||||||
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
|
||||||
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
|
||||||
"change .mailpoet_posts_image_full_width": _.partial(this.changeBoolField, "imageFullWidth"),
|
"change .mailpoet_posts_image_full_width": _.partial(this.changeBoolField, "imageFullWidth"),
|
||||||
"change .mailpoet_posts_featured_image_position": _.partial(this.changeField, "featuredImagePosition"),
|
"change .mailpoet_posts_featured_image_position": _.partial(this.changeField, "featuredImagePosition"),
|
||||||
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
|
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
|
||||||
"keyup .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
"input .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
|
||||||
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
|
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
|
||||||
"keyup .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
"input .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
|
||||||
"keyup .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
|
"input .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
|
||||||
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
|
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -93,6 +93,7 @@ define([
|
|||||||
return {
|
return {
|
||||||
model: this.model.toJSON(),
|
model: this.model.toJSON(),
|
||||||
allIconSets: allIconSets.toJSON(),
|
allIconSets: allIconSets.toJSON(),
|
||||||
|
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -140,6 +141,7 @@ define([
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
HighlightEditingBehavior: {},
|
HighlightEditingBehavior: {},
|
||||||
|
ShowSettingsBehavior: {},
|
||||||
},
|
},
|
||||||
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
|
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
|
||||||
constructor: function() {
|
constructor: function() {
|
||||||
@ -148,6 +150,7 @@ define([
|
|||||||
Marionette.CompositeView.apply(this, arguments);
|
Marionette.CompositeView.apply(this, arguments);
|
||||||
},
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
|
this.on('showSettings', this.showSettings, this);
|
||||||
this.on('dom:refresh', this.showBlock, this);
|
this.on('dom:refresh', this.showBlock, this);
|
||||||
this._isFirstRender = true;
|
this._isFirstRender = true;
|
||||||
},
|
},
|
||||||
@ -168,13 +171,16 @@ define([
|
|||||||
this.regionManager.destroy();
|
this.regionManager.destroy();
|
||||||
},
|
},
|
||||||
showTools: function(_event) {
|
showTools: function(_event) {
|
||||||
this.$(this.ui.tools).show();
|
this.$(this.ui.tools).addClass('mailpoet_display_tools');
|
||||||
_event.stopPropagation();
|
_event.stopPropagation();
|
||||||
},
|
},
|
||||||
hideTools: function(_event) {
|
hideTools: function(_event) {
|
||||||
this.$(this.ui.tools).hide();
|
this.$(this.ui.tools).removeClass('mailpoet_display_tools');
|
||||||
_event.stopPropagation();
|
_event.stopPropagation();
|
||||||
},
|
},
|
||||||
|
showSettings: function(options) {
|
||||||
|
this.toolsView.triggerMethod('showSettings', options);
|
||||||
|
},
|
||||||
getDropFunc: function() {
|
getDropFunc: function() {
|
||||||
return function() {
|
return function() {
|
||||||
return this.model.clone();
|
return this.model.clone();
|
||||||
@ -274,9 +280,9 @@ define([
|
|||||||
return {
|
return {
|
||||||
"click .mailpoet_delete_block": "deleteIcon",
|
"click .mailpoet_delete_block": "deleteIcon",
|
||||||
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
|
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
|
||||||
"keyup .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
|
"input .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
|
||||||
"keyup .mailpoet_social_icon_field_link": this.changeLink,
|
"input .mailpoet_social_icon_field_link": this.changeLink,
|
||||||
"keyup .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
|
"input .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
modelEvents: {
|
modelEvents: {
|
||||||
@ -383,7 +389,7 @@ define([
|
|||||||
{
|
{
|
||||||
type: 'socialIcon',
|
type: 'socialIcon',
|
||||||
iconType: 'facebook',
|
iconType: 'facebook',
|
||||||
link: 'http://example.com',
|
link: 'http://www.facebook.com',
|
||||||
image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
|
image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
|
||||||
height: '32px',
|
height: '32px',
|
||||||
width: '32px',
|
width: '32px',
|
||||||
@ -392,7 +398,7 @@ define([
|
|||||||
{
|
{
|
||||||
type: 'socialIcon',
|
type: 'socialIcon',
|
||||||
iconType: 'twitter',
|
iconType: 'twitter',
|
||||||
link: 'http://example.com',
|
link: 'http://www.twitter.com',
|
||||||
image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
|
image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
|
||||||
height: '32px',
|
height: '32px',
|
||||||
width: '32px',
|
width: '32px',
|
||||||
|
@ -36,6 +36,9 @@ define([
|
|||||||
minLength: 20, // TODO: Move this number to editor configuration
|
minLength: 20, // TODO: Move this number to editor configuration
|
||||||
modelField: 'styles.block.height',
|
modelField: 'styles.block.height',
|
||||||
},
|
},
|
||||||
|
ShowSettingsBehavior: {
|
||||||
|
ignoreFrom: '.mailpoet_resize_handle'
|
||||||
|
},
|
||||||
}, base.BlockView.prototype.behaviors),
|
}, base.BlockView.prototype.behaviors),
|
||||||
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
|
||||||
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
|
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
|
||||||
|
@ -11,7 +11,7 @@ define([
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'automatedLatestContent',
|
endpoint: 'automatedLatestContent',
|
||||||
action: args.action,
|
action: args.action,
|
||||||
data: args.options || {},
|
data: args.options || {}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Module._cachedQuery = _.memoize(Module._query, JSON.stringify);
|
Module._cachedQuery = _.memoize(Module._query, JSON.stringify);
|
||||||
@ -19,16 +19,16 @@ define([
|
|||||||
Module.getNewsletter = function(options) {
|
Module.getNewsletter = function(options) {
|
||||||
return Module._query({
|
return Module._query({
|
||||||
action: 'get',
|
action: 'get',
|
||||||
options: options,
|
options: options
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.getPostTypes = function() {
|
Module.getPostTypes = function() {
|
||||||
return Module._cachedQuery({
|
return Module._cachedQuery({
|
||||||
action: 'getPostTypes',
|
action: 'getPostTypes',
|
||||||
options: {},
|
options: {}
|
||||||
}).then(function(types) {
|
}).then(function(response) {
|
||||||
return _.values(types);
|
return _.values(response.data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,36 +36,46 @@ define([
|
|||||||
return Module._cachedQuery({
|
return Module._cachedQuery({
|
||||||
action: 'getTaxonomies',
|
action: 'getTaxonomies',
|
||||||
options: {
|
options: {
|
||||||
postType: postType,
|
postType: postType
|
||||||
},
|
}
|
||||||
|
}).then(function(response) {
|
||||||
|
return response.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.getTerms = function(options) {
|
Module.getTerms = function(options) {
|
||||||
return Module._cachedQuery({
|
return Module._cachedQuery({
|
||||||
action: 'getTerms',
|
action: 'getTerms',
|
||||||
options: options,
|
options: options
|
||||||
|
}).then(function(response) {
|
||||||
|
return response.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.getPosts = function(options) {
|
Module.getPosts = function(options) {
|
||||||
return Module._cachedQuery({
|
return Module._cachedQuery({
|
||||||
action: 'getPosts',
|
action: 'getPosts',
|
||||||
options: options,
|
options: options
|
||||||
|
}).then(function(response) {
|
||||||
|
return response.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.getTransformedPosts = function(options) {
|
Module.getTransformedPosts = function(options) {
|
||||||
return Module._cachedQuery({
|
return Module._cachedQuery({
|
||||||
action: 'getTransformedPosts',
|
action: 'getTransformedPosts',
|
||||||
options: options,
|
options: options
|
||||||
|
}).then(function(response) {
|
||||||
|
return response.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Module.getBulkTransformedPosts = function(options) {
|
Module.getBulkTransformedPosts = function(options) {
|
||||||
return Module._query({
|
return Module._query({
|
||||||
action: 'getBulkTransformedPosts',
|
action: 'getBulkTransformedPosts',
|
||||||
options: options,
|
options: options
|
||||||
|
}).then(function(response) {
|
||||||
|
return response.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,7 +83,7 @@ define([
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: options || {},
|
data: options || {}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +91,7 @@ define([
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'sendPreview',
|
action: 'sendPreview',
|
||||||
data: options || {},
|
data: options || {}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ define([
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletterTemplates',
|
endpoint: 'newsletterTemplates',
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: data,
|
data: data
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,10 +65,6 @@ define([
|
|||||||
var $openRegion = this.$el.find('.mailpoet_sidebar_region:not(.closed)'),
|
var $openRegion = this.$el.find('.mailpoet_sidebar_region:not(.closed)'),
|
||||||
$targetRegion = this.$el.find(event.target).closest('.mailpoet_sidebar_region');
|
$targetRegion = this.$el.find(event.target).closest('.mailpoet_sidebar_region');
|
||||||
|
|
||||||
if ($openRegion.get(0) === $targetRegion.get(0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$openRegion.find('.mailpoet_region_content').velocity(
|
$openRegion.find('.mailpoet_region_content').velocity(
|
||||||
'slideUp',
|
'slideUp',
|
||||||
{
|
{
|
||||||
@ -79,16 +75,19 @@ define([
|
|||||||
}.bind(this)
|
}.bind(this)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$targetRegion.find('.mailpoet_region_content').velocity(
|
|
||||||
'slideDown',
|
if ($openRegion.get(0) !== $targetRegion.get(0)) {
|
||||||
{
|
$targetRegion.find('.mailpoet_region_content').velocity(
|
||||||
duration: 250,
|
'slideDown',
|
||||||
easing: "easeIn",
|
{
|
||||||
complete: function() {
|
duration: 250,
|
||||||
$targetRegion.removeClass('closed');
|
easing: "easeIn",
|
||||||
},
|
complete: function() {
|
||||||
}
|
$targetRegion.removeClass('closed');
|
||||||
);
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
@ -233,6 +232,12 @@ define([
|
|||||||
'click .mailpoet_show_preview': 'showPreview',
|
'click .mailpoet_show_preview': 'showPreview',
|
||||||
'click #mailpoet_send_preview': 'sendPreview',
|
'click #mailpoet_send_preview': 'sendPreview',
|
||||||
},
|
},
|
||||||
|
onBeforeDestroy: function() {
|
||||||
|
if (this.previewView) {
|
||||||
|
this.previewView.destroy();
|
||||||
|
this.previewView = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
showPreview: function() {
|
showPreview: function() {
|
||||||
var json = App.toJSON();
|
var json = App.toJSON();
|
||||||
|
|
||||||
@ -247,18 +252,31 @@ define([
|
|||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'showPreview',
|
action: 'showPreview',
|
||||||
data: json,
|
data: json,
|
||||||
}).done(function(response){
|
}).always(function() {
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
|
}).done(function(response) {
|
||||||
|
this.previewView = new Module.NewsletterPreviewView({
|
||||||
|
previewUrl: response.meta.preview_url
|
||||||
|
});
|
||||||
|
|
||||||
if (response.result === true) {
|
var view = this.previewView.render();
|
||||||
window.open(response.data.url, '_blank')
|
|
||||||
|
MailPoet.Modal.popup({
|
||||||
|
template: '',
|
||||||
|
element: this.previewView.$el,
|
||||||
|
title: MailPoet.I18n.t('newsletterPreview'),
|
||||||
|
onCancel: function() {
|
||||||
|
this.previewView.destroy();
|
||||||
|
this.previewView = null;
|
||||||
|
}.bind(this)
|
||||||
|
});
|
||||||
|
}.bind(this)).fail(function(response) {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
MailPoet.Notice.error(response.errors);
|
|
||||||
}).fail(function(error) {
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoet.I18n.t('newsletterPreviewFailed')
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
sendPreview: function() {
|
sendPreview: function() {
|
||||||
@ -283,32 +301,39 @@ define([
|
|||||||
// send test email
|
// send test email
|
||||||
MailPoet.Modal.loading(true);
|
MailPoet.Modal.loading(true);
|
||||||
|
|
||||||
CommunicationComponent.previewNewsletter(data).done(function(response) {
|
CommunicationComponent.previewNewsletter(data).always(function() {
|
||||||
if(response.result !== undefined && response.result === true) {
|
|
||||||
MailPoet.Notice.success(MailPoet.I18n.t('newsletterPreviewSent'), { scroll: true });
|
|
||||||
} else {
|
|
||||||
if (_.isArray(response.errors)) {
|
|
||||||
response.errors.map(function(error) {
|
|
||||||
MailPoet.Notice.error(error, { scroll: true });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoet.I18n.t('newsletterPreviewFailedToSend'),
|
|
||||||
{
|
|
||||||
scroll: true,
|
|
||||||
static: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
|
}).done(function(response) {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('newsletterPreviewSent'),
|
||||||
|
{ scroll: true });
|
||||||
}).fail(function(response) {
|
}).fail(function(response) {
|
||||||
// an error occurred
|
if (response.errors.length > 0) {
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true, static: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Module.NewsletterPreviewView = Marionette.ItemView.extend({
|
||||||
|
getTemplate: function() { return templates.newsletterPreview; },
|
||||||
|
initialize: function(options) {
|
||||||
|
this.previewUrl = options.previewUrl;
|
||||||
|
this.width = App.getConfig().get('newsletterPreview.width');
|
||||||
|
this.height = App.getConfig().get('newsletterPreview.height')
|
||||||
|
},
|
||||||
|
templateHelpers: function() {
|
||||||
|
return {
|
||||||
|
previewUrl: this.previewUrl,
|
||||||
|
width: this.width,
|
||||||
|
height: this.height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
App.on('before:start', function(options) {
|
App.on('before:start', function(options) {
|
||||||
App.registerWidget = Module.registerWidget;
|
App.registerWidget = Module.registerWidget;
|
||||||
App.getWidgets = Module.getWidgets;
|
App.getWidgets = Module.getWidgets;
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 26 KiB |
170
assets/js/src/newsletters/listings/mixins.jsx
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import MailPoet from 'mailpoet'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import jQuery from 'jquery'
|
||||||
|
|
||||||
|
const _QueueMixin = {
|
||||||
|
pauseSending: function(newsletter) {
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
endpoint: 'sendingQueue',
|
||||||
|
action: 'pause',
|
||||||
|
data: {
|
||||||
|
newsletter_id: newsletter.id
|
||||||
|
}
|
||||||
|
}).done(function() {
|
||||||
|
jQuery('#resume_'+newsletter.id).show();
|
||||||
|
jQuery('#pause_'+newsletter.id).hide();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resumeSending: function(newsletter) {
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
endpoint: 'sendingQueue',
|
||||||
|
action: 'resume',
|
||||||
|
data: {
|
||||||
|
newsletter_id: newsletter.id
|
||||||
|
}
|
||||||
|
}).done(function() {
|
||||||
|
jQuery('#pause_'+newsletter.id).show();
|
||||||
|
jQuery('#resume_'+newsletter.id).hide();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
renderQueueStatus: function(newsletter) {
|
||||||
|
if (!newsletter.queue) {
|
||||||
|
return (
|
||||||
|
<span>{MailPoet.I18n.t('notSentYet')}</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (newsletter.queue.status === 'scheduled') {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{ MailPoet.I18n.t('scheduledFor') } { MailPoet.Date.format(newsletter.queue.scheduled_at) }
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const progressClasses = classNames(
|
||||||
|
'mailpoet_progress',
|
||||||
|
{ 'mailpoet_progress_complete': newsletter.queue.status === 'completed'}
|
||||||
|
);
|
||||||
|
|
||||||
|
// calculate percentage done
|
||||||
|
const percentage = Math.round(
|
||||||
|
(newsletter.queue.count_processed * 100) / (newsletter.queue.count_total)
|
||||||
|
);
|
||||||
|
|
||||||
|
let label;
|
||||||
|
|
||||||
|
if (newsletter.queue.status === 'completed') {
|
||||||
|
label = (
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
MailPoet.I18n.t('newsletterQueueCompleted')
|
||||||
|
.replace(
|
||||||
|
"%$1d",
|
||||||
|
newsletter.queue.count_processed - newsletter.queue.count_failed
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"%$2d",
|
||||||
|
newsletter.queue.count_total
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
label = (
|
||||||
|
<span>
|
||||||
|
{ newsletter.queue.count_processed } / { newsletter.queue.count_total }
|
||||||
|
|
||||||
|
<a
|
||||||
|
id={ 'resume_'+newsletter.id }
|
||||||
|
className="button"
|
||||||
|
style={{ display: (newsletter.queue.status === 'paused')
|
||||||
|
? 'inline-block': 'none' }}
|
||||||
|
href="javascript:;"
|
||||||
|
onClick={ this.resumeSending.bind(null, newsletter) }
|
||||||
|
>{MailPoet.I18n.t('resume')}</a>
|
||||||
|
<a
|
||||||
|
id={ 'pause_'+newsletter.id }
|
||||||
|
className="button mailpoet_pause"
|
||||||
|
style={{ display: (newsletter.queue.status === null)
|
||||||
|
? 'inline-block': 'none' }}
|
||||||
|
href="javascript:;"
|
||||||
|
onClick={ this.pauseSending.bind(null, newsletter) }
|
||||||
|
>{MailPoet.I18n.t('pause')}</a>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={ progressClasses }>
|
||||||
|
<span
|
||||||
|
className="mailpoet_progress_bar"
|
||||||
|
style={ { width: percentage + "%"} }
|
||||||
|
></span>
|
||||||
|
<span className="mailpoet_progress_label">
|
||||||
|
{ percentage + "%" }
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p style={{ textAlign:'center' }}>
|
||||||
|
{ label }
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const _StatisticsMixin = {
|
||||||
|
renderStatistics: function(newsletter) {
|
||||||
|
if (
|
||||||
|
newsletter.statistics
|
||||||
|
&& newsletter.queue
|
||||||
|
&& newsletter.queue.status !== 'scheduled'
|
||||||
|
) {
|
||||||
|
const total_sent = ~~(newsletter.queue.count_processed);
|
||||||
|
|
||||||
|
let percentage_clicked = 0;
|
||||||
|
let percentage_opened = 0;
|
||||||
|
let percentage_unsubscribed = 0;
|
||||||
|
|
||||||
|
if (total_sent > 0) {
|
||||||
|
percentage_clicked = Math.round(
|
||||||
|
(~~(newsletter.statistics.clicked) * 100) / total_sent
|
||||||
|
);
|
||||||
|
percentage_opened = Math.round(
|
||||||
|
(~~(newsletter.statistics.opened) * 100) / total_sent
|
||||||
|
);
|
||||||
|
percentage_unsubscribed = Math.round(
|
||||||
|
(~~(newsletter.statistics.unsubscribed) * 100) / total_sent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{ percentage_opened }%, { percentage_clicked }%, { percentage_unsubscribed }%
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<span>{MailPoet.I18n.t('notSentYet')}</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { _QueueMixin as QueueMixin };
|
||||||
|
export { _StatisticsMixin as StatisticsMixin };
|
@ -17,8 +17,8 @@ import {
|
|||||||
} from 'newsletters/scheduling/common.jsx'
|
} from 'newsletters/scheduling/common.jsx'
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash(response) {
|
onTrash: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -28,12 +28,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersTrashed')
|
MailPoet.I18n.t('multipleNewslettersTrashed')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete(response) {
|
onDelete: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -43,12 +43,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersDeleted')
|
MailPoet.I18n.t('multipleNewslettersDeleted')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore(response) {
|
onRestore: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -58,7 +58,7 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersRestored')
|
MailPoet.I18n.t('multipleNewslettersRestored')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
@ -127,16 +127,23 @@ const newsletter_actions = [
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: newsletter.id
|
data: {
|
||||||
}).done(function(response) {
|
id: newsletter.id
|
||||||
if (response !== false && response.subject !== undefined) {
|
}
|
||||||
MailPoet.Notice.success(
|
}).done((response) => {
|
||||||
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
MailPoet.Notice.success(
|
||||||
'%$1s', response.subject
|
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
||||||
)
|
'%$1s', response.data.subject
|
||||||
|
)
|
||||||
|
);
|
||||||
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
refresh();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -158,20 +165,18 @@ const NewsletterListNotification = React.createClass({
|
|||||||
id: ~~(e.target.getAttribute('data-id')),
|
id: ~~(e.target.getAttribute('data-id')),
|
||||||
status: e.target.value
|
status: e.target.value
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if (response.result === false) {
|
if (response.data.status === 'active') {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('postNotificationActivationFailed'));
|
MailPoet.Notice.success(MailPoet.I18n.t('postNotificationActivated'));
|
||||||
|
|
||||||
// reset value to actual newsletter's status
|
|
||||||
e.target.value = response.status;
|
|
||||||
} else {
|
|
||||||
if (response.status === 'active') {
|
|
||||||
MailPoet.Notice.success(MailPoet.I18n.t('postNotificationActivated'));
|
|
||||||
}
|
|
||||||
// force refresh of listing so that groups are updated
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
// force refresh of listing so that groups are updated
|
||||||
|
this.forceUpdate();
|
||||||
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(MailPoet.I18n.t('postNotificationActivationFailed'));
|
||||||
|
|
||||||
|
// reset value to actual newsletter's status
|
||||||
|
e.target.value = response.status;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
renderStatus: function(newsletter) {
|
renderStatus: function(newsletter) {
|
||||||
return (
|
return (
|
||||||
@ -252,6 +257,20 @@ const NewsletterListNotification = React.createClass({
|
|||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
renderHistoryLink: function(newsletter) {
|
||||||
|
const childrenCount = ~~(newsletter.children_count);
|
||||||
|
if (childrenCount === 0) {
|
||||||
|
return (
|
||||||
|
MailPoet.I18n.t('notSentYet')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to={ `/notification/history/${ newsletter.id }` }
|
||||||
|
>{ MailPoet.I18n.t('viewHistory') }</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
renderItem: function(newsletter, actions) {
|
renderItem: function(newsletter, actions) {
|
||||||
const rowClasses = classNames(
|
const rowClasses = classNames(
|
||||||
'manage-column',
|
'manage-column',
|
||||||
@ -277,7 +296,7 @@ const NewsletterListNotification = React.createClass({
|
|||||||
{ this.renderSettings(newsletter) }
|
{ this.renderSettings(newsletter) }
|
||||||
</td>
|
</td>
|
||||||
<td className="column" data-colname={ MailPoet.I18n.t('history') }>
|
<td className="column" data-colname={ MailPoet.I18n.t('history') }>
|
||||||
<a href="#TODO">{ MailPoet.I18n.t('viewHistory') }</a>
|
{ this.renderHistoryLink(newsletter) }
|
||||||
</td>
|
</td>
|
||||||
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>
|
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>
|
||||||
<abbr>{ MailPoet.Date.format(newsletter.updated_at) }</abbr>
|
<abbr>{ MailPoet.Date.format(newsletter.updated_at) }</abbr>
|
||||||
@ -299,7 +318,8 @@ const NewsletterListNotification = React.createClass({
|
|||||||
location={ this.props.location }
|
location={ this.props.location }
|
||||||
params={ this.props.params }
|
params={ this.props.params }
|
||||||
endpoint="newsletters"
|
endpoint="newsletters"
|
||||||
tab="notification"
|
type="notification"
|
||||||
|
base_url="notification"
|
||||||
onRenderItem={ this.renderItem }
|
onRenderItem={ this.renderItem }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
|
125
assets/js/src/newsletters/listings/notification_history.jsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Router, Link } from 'react-router'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import jQuery from 'jquery'
|
||||||
|
import MailPoet from 'mailpoet'
|
||||||
|
|
||||||
|
import Listing from 'listing/listing.jsx'
|
||||||
|
import ListingTabs from 'newsletters/listings/tabs.jsx'
|
||||||
|
|
||||||
|
import { QueueMixin, StatisticsMixin } from 'newsletters/listings/mixins.jsx'
|
||||||
|
|
||||||
|
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
name: 'subject',
|
||||||
|
label: MailPoet.I18n.t('subject'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'status',
|
||||||
|
label: MailPoet.I18n.t('status')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'segments',
|
||||||
|
label: MailPoet.I18n.t('lists')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'statistics',
|
||||||
|
label: MailPoet.I18n.t('statistics'),
|
||||||
|
display: mailpoet_tracking_enabled
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'processed_at',
|
||||||
|
label: MailPoet.I18n.t('sentOn'),
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const newsletter_actions = [
|
||||||
|
{
|
||||||
|
name: 'view',
|
||||||
|
link: function(newsletter) {
|
||||||
|
return (
|
||||||
|
<a href={ newsletter.preview_url } target="_blank">
|
||||||
|
{MailPoet.I18n.t('preview')}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const NewsletterListNotificationHistory = React.createClass({
|
||||||
|
mixins: [QueueMixin, StatisticsMixin],
|
||||||
|
renderItem: function(newsletter, actions) {
|
||||||
|
const rowClasses = classNames(
|
||||||
|
'manage-column',
|
||||||
|
'column-primary',
|
||||||
|
'has-row-actions'
|
||||||
|
);
|
||||||
|
|
||||||
|
const segments = newsletter.segments.map(function(segment) {
|
||||||
|
return segment.name
|
||||||
|
}).join(', ');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<td className={ rowClasses }>
|
||||||
|
<strong>
|
||||||
|
<a
|
||||||
|
href={ newsletter.preview_url }
|
||||||
|
target="_blank"
|
||||||
|
>{ newsletter.subject }</a>
|
||||||
|
</strong>
|
||||||
|
{ actions }
|
||||||
|
</td>
|
||||||
|
<td className="column" data-colname={ MailPoet.I18n.t('status') }>
|
||||||
|
{ this.renderQueueStatus(newsletter) }
|
||||||
|
</td>
|
||||||
|
<td className="column" data-colname={ MailPoet.I18n.t('lists') }>
|
||||||
|
{ segments }
|
||||||
|
</td>
|
||||||
|
{ (mailpoet_tracking_enabled === true) ? (
|
||||||
|
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
|
||||||
|
{ this.renderStatistics(newsletter) }
|
||||||
|
</td>
|
||||||
|
) : null }
|
||||||
|
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>
|
||||||
|
<abbr>{ MailPoet.Date.format(newsletter.updated_at) }</abbr>
|
||||||
|
</td>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1 className="title">
|
||||||
|
{MailPoet.I18n.t('pageTitle')} <Link className="page-title-action" to="/new">{MailPoet.I18n.t('new')}</Link>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<ListingTabs tab="notification" />
|
||||||
|
|
||||||
|
<Link
|
||||||
|
className="page-title-action"
|
||||||
|
to="/notification"
|
||||||
|
>{MailPoet.I18n.t('backToPostNotifications')}</Link>
|
||||||
|
|
||||||
|
<Listing
|
||||||
|
limit={ mailpoet_listing_per_page }
|
||||||
|
location={ this.props.location }
|
||||||
|
params={ this.props.params }
|
||||||
|
endpoint="newsletters"
|
||||||
|
type="notification_history"
|
||||||
|
base_url="notification/history/:parent_id"
|
||||||
|
onRenderItem={ this.renderItem }
|
||||||
|
columns={columns}
|
||||||
|
item_actions={ newsletter_actions }
|
||||||
|
auto_refresh={ true }
|
||||||
|
sort_by="updated_at"
|
||||||
|
sort_order="desc"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = NewsletterListNotificationHistory;
|
@ -7,11 +7,13 @@ import MailPoet from 'mailpoet'
|
|||||||
import Listing from 'listing/listing.jsx'
|
import Listing from 'listing/listing.jsx'
|
||||||
import ListingTabs from 'newsletters/listings/tabs.jsx'
|
import ListingTabs from 'newsletters/listings/tabs.jsx'
|
||||||
|
|
||||||
|
import { QueueMixin, StatisticsMixin } from 'newsletters/listings/mixins.jsx'
|
||||||
|
|
||||||
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
|
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash(response) {
|
onTrash: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -21,12 +23,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersTrashed')
|
MailPoet.I18n.t('multipleNewslettersTrashed')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete(response) {
|
onDelete: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -36,12 +38,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersDeleted')
|
MailPoet.I18n.t('multipleNewslettersDeleted')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore(response) {
|
onRestore: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -51,7 +53,7 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersRestored')
|
MailPoet.I18n.t('multipleNewslettersRestored')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
@ -120,16 +122,23 @@ const newsletter_actions = [
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: newsletter.id
|
data: {
|
||||||
}).done(function(response) {
|
id: newsletter.id
|
||||||
if (response !== false && response.subject !== undefined) {
|
}
|
||||||
MailPoet.Notice.success(
|
}).done((response) => {
|
||||||
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
MailPoet.Notice.success(
|
||||||
'%$1s', response.subject
|
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
||||||
)
|
'%$1s', response.data.subject
|
||||||
|
)
|
||||||
|
);
|
||||||
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
refresh();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -139,135 +148,7 @@ const newsletter_actions = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const NewsletterListStandard = React.createClass({
|
const NewsletterListStandard = React.createClass({
|
||||||
pauseSending: function(newsletter) {
|
mixins: [QueueMixin, StatisticsMixin],
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'sendingQueue',
|
|
||||||
action: 'pause',
|
|
||||||
data: newsletter.id
|
|
||||||
}).done(function() {
|
|
||||||
jQuery('#resume_'+newsletter.id).show();
|
|
||||||
jQuery('#pause_'+newsletter.id).hide();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resumeSending: function(newsletter) {
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'sendingQueue',
|
|
||||||
action: 'resume',
|
|
||||||
data: newsletter.id
|
|
||||||
}).done(function() {
|
|
||||||
jQuery('#pause_'+newsletter.id).show();
|
|
||||||
jQuery('#resume_'+newsletter.id).hide();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
renderStatus: function(newsletter) {
|
|
||||||
if (!newsletter.queue) {
|
|
||||||
return (
|
|
||||||
<span>{MailPoet.I18n.t('notSentYet')}</span>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (newsletter.queue.status === 'scheduled') {
|
|
||||||
return (
|
|
||||||
<span>{MailPoet.I18n.t('scheduledFor')} { MailPoet.Date.format(newsletter.queue.scheduled_at) } </span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const progressClasses = classNames(
|
|
||||||
'mailpoet_progress',
|
|
||||||
{ 'mailpoet_progress_complete': newsletter.queue.status === 'completed'}
|
|
||||||
);
|
|
||||||
|
|
||||||
// calculate percentage done
|
|
||||||
const percentage = Math.round(
|
|
||||||
(newsletter.queue.count_processed * 100) / (newsletter.queue.count_total)
|
|
||||||
);
|
|
||||||
|
|
||||||
let label;
|
|
||||||
|
|
||||||
if (newsletter.queue.status === 'completed') {
|
|
||||||
label = (
|
|
||||||
<span>
|
|
||||||
{
|
|
||||||
MailPoet.I18n.t('newsletterQueueCompleted')
|
|
||||||
.replace("%$1d", newsletter.queue.count_processed - newsletter.queue.count_failed)
|
|
||||||
.replace("%$2d", newsletter.queue.count_total)
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
label = (
|
|
||||||
<span>
|
|
||||||
{ newsletter.queue.count_processed } / { newsletter.queue.count_total }
|
|
||||||
|
|
||||||
<a
|
|
||||||
id={ 'resume_'+newsletter.id }
|
|
||||||
className="button"
|
|
||||||
style={{ display: (newsletter.queue.status === 'paused') ? 'inline-block': 'none' }}
|
|
||||||
href="javascript:;"
|
|
||||||
onClick={ this.resumeSending.bind(null, newsletter) }
|
|
||||||
>{MailPoet.I18n.t('resume')}</a>
|
|
||||||
<a
|
|
||||||
id={ 'pause_'+newsletter.id }
|
|
||||||
className="button mailpoet_pause"
|
|
||||||
style={{ display: (newsletter.queue.status === null) ? 'inline-block': 'none' }}
|
|
||||||
href="javascript:;"
|
|
||||||
onClick={ this.pauseSending.bind(null, newsletter) }
|
|
||||||
>{MailPoet.I18n.t('pause')}</a>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className={ progressClasses }>
|
|
||||||
<span
|
|
||||||
className="mailpoet_progress_bar"
|
|
||||||
style={ { width: percentage + "%"} }
|
|
||||||
></span>
|
|
||||||
<span className="mailpoet_progress_label">
|
|
||||||
{ percentage + "%" }
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p style={{ textAlign:'center' }}>
|
|
||||||
{ label }
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renderStatistics: function(newsletter) {
|
|
||||||
if (mailpoet_tracking_enabled === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newsletter.statistics && newsletter.queue && newsletter.queue.status !== 'scheduled') {
|
|
||||||
const total_sent = ~~(newsletter.queue.count_processed);
|
|
||||||
|
|
||||||
let percentage_clicked = 0;
|
|
||||||
let percentage_opened = 0;
|
|
||||||
let percentage_unsubscribed = 0;
|
|
||||||
|
|
||||||
if (total_sent > 0) {
|
|
||||||
percentage_clicked = Math.round(
|
|
||||||
(~~(newsletter.statistics.clicked) * 100) / total_sent
|
|
||||||
);
|
|
||||||
percentage_opened = Math.round(
|
|
||||||
(~~(newsletter.statistics.opened) * 100) / total_sent
|
|
||||||
);
|
|
||||||
percentage_unsubscribed = Math.round(
|
|
||||||
(~~(newsletter.statistics.unsubscribed) * 100) / total_sent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
{ percentage_opened }%, { percentage_clicked }%, { percentage_unsubscribed }%
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<span>{MailPoet.I18n.t('notSentYet')}</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renderItem: function(newsletter, actions) {
|
renderItem: function(newsletter, actions) {
|
||||||
const rowClasses = classNames(
|
const rowClasses = classNames(
|
||||||
'manage-column',
|
'manage-column',
|
||||||
@ -291,7 +172,7 @@ const NewsletterListStandard = React.createClass({
|
|||||||
{ actions }
|
{ actions }
|
||||||
</td>
|
</td>
|
||||||
<td className="column" data-colname={ MailPoet.I18n.t('status') }>
|
<td className="column" data-colname={ MailPoet.I18n.t('status') }>
|
||||||
{ this.renderStatus(newsletter) }
|
{ this.renderQueueStatus(newsletter) }
|
||||||
</td>
|
</td>
|
||||||
<td className="column" data-colname={ MailPoet.I18n.t('lists') }>
|
<td className="column" data-colname={ MailPoet.I18n.t('lists') }>
|
||||||
{ segments }
|
{ segments }
|
||||||
@ -321,7 +202,8 @@ const NewsletterListStandard = React.createClass({
|
|||||||
location={ this.props.location }
|
location={ this.props.location }
|
||||||
params={ this.props.params }
|
params={ this.props.params }
|
||||||
endpoint="newsletters"
|
endpoint="newsletters"
|
||||||
tab="standard"
|
type="standard"
|
||||||
|
base_url="standard"
|
||||||
onRenderItem={this.renderItem}
|
onRenderItem={this.renderItem}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
|
@ -15,8 +15,8 @@ const mailpoet_segments = window.mailpoet_segments || {};
|
|||||||
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
|
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash(response) {
|
onTrash: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -26,12 +26,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersTrashed')
|
MailPoet.I18n.t('multipleNewslettersTrashed')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete(response) {
|
onDelete: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -41,12 +41,12 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersDeleted')
|
MailPoet.I18n.t('multipleNewslettersDeleted')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore(response) {
|
onRestore: (response) => {
|
||||||
const count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
|
|
||||||
if (count === 1) {
|
if (count === 1) {
|
||||||
@ -56,7 +56,7 @@ const messages = {
|
|||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleNewslettersRestored')
|
MailPoet.I18n.t('multipleNewslettersRestored')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
@ -125,16 +125,23 @@ const newsletter_actions = [
|
|||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: newsletter.id
|
data: {
|
||||||
}).done(function(response) {
|
id: newsletter.id
|
||||||
if (response !== false && response.subject !== undefined) {
|
}
|
||||||
MailPoet.Notice.success(
|
}).done((response) => {
|
||||||
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
MailPoet.Notice.success(
|
||||||
'%$1s', response.subject
|
(MailPoet.I18n.t('newsletterDuplicated')).replace(
|
||||||
)
|
'%$1s', response.data.subject
|
||||||
|
)
|
||||||
|
);
|
||||||
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
refresh();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -156,20 +163,18 @@ const NewsletterListWelcome = React.createClass({
|
|||||||
id: ~~(e.target.getAttribute('data-id')),
|
id: ~~(e.target.getAttribute('data-id')),
|
||||||
status: e.target.value
|
status: e.target.value
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if (response.result === false) {
|
if (response.data.status === 'active') {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('welcomeEmailActivationFailed'));
|
MailPoet.Notice.success(MailPoet.I18n.t('welcomeEmailActivated'));
|
||||||
|
|
||||||
// reset value to actual newsletter's status
|
|
||||||
e.target.value = response.status;
|
|
||||||
} else {
|
|
||||||
if (response.status === 'active') {
|
|
||||||
MailPoet.Notice.success(MailPoet.I18n.t('welcomeEmailActivated'));
|
|
||||||
}
|
|
||||||
// force refresh of listing so that groups are updated
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
// force refresh of listing so that groups are updated
|
||||||
|
this.forceUpdate();
|
||||||
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(MailPoet.I18n.t('welcomeEmailActivationFailed'));
|
||||||
|
|
||||||
|
// reset value to actual newsletter's status
|
||||||
|
e.target.value = response.status;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
renderStatus: function(newsletter) {
|
renderStatus: function(newsletter) {
|
||||||
let total_sent;
|
let total_sent;
|
||||||
@ -343,7 +348,8 @@ const NewsletterListWelcome = React.createClass({
|
|||||||
location={ this.props.location }
|
location={ this.props.location }
|
||||||
params={ this.props.params }
|
params={ this.props.params }
|
||||||
endpoint="newsletters"
|
endpoint="newsletters"
|
||||||
tab="welcome"
|
type="welcome"
|
||||||
|
base_url="welcome"
|
||||||
onRenderItem={ this.renderItem }
|
onRenderItem={ this.renderItem }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
|
@ -14,12 +14,13 @@ import NewsletterTypeNotification from 'newsletters/types/notification/notificat
|
|||||||
import NewsletterListStandard from 'newsletters/listings/standard.jsx'
|
import NewsletterListStandard from 'newsletters/listings/standard.jsx'
|
||||||
import NewsletterListWelcome from 'newsletters/listings/welcome.jsx'
|
import NewsletterListWelcome from 'newsletters/listings/welcome.jsx'
|
||||||
import NewsletterListNotification from 'newsletters/listings/notification.jsx'
|
import NewsletterListNotification from 'newsletters/listings/notification.jsx'
|
||||||
|
import NewsletterListNotificationHistory from 'newsletters/listings/notification_history.jsx'
|
||||||
|
|
||||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||||
|
|
||||||
const App = React.createClass({
|
const App = React.createClass({
|
||||||
render() {
|
render() {
|
||||||
return this.props.children
|
return this.props.children;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -31,18 +32,16 @@ if(container) {
|
|||||||
<Route path="/" component={ App }>
|
<Route path="/" component={ App }>
|
||||||
<IndexRedirect to="standard" />
|
<IndexRedirect to="standard" />
|
||||||
{/* Listings */}
|
{/* Listings */}
|
||||||
<Route name="listing/standard" path="standard" component={ NewsletterListStandard } />
|
<Route path="standard(/)**" params={{ tab: 'standard' }} component={ NewsletterListStandard } />
|
||||||
<Route name="listing/welcome" path="welcome" component={ NewsletterListWelcome } />
|
<Route path="welcome(/)**" component={ NewsletterListWelcome } />
|
||||||
<Route name="listing/notification" path="notification" component={ NewsletterListNotification } />
|
<Route path="notification/history/:parent_id(/)**" component={ NewsletterListNotificationHistory } />
|
||||||
<Route path="standard/*" component={ NewsletterListStandard } />
|
<Route path="notification(/)**" component={ NewsletterListNotification } />
|
||||||
<Route path="welcome/*" component={ NewsletterListWelcome } />
|
|
||||||
<Route path="notification/*" component={ NewsletterListNotification } />
|
|
||||||
{/* Newsletter: type selection */}
|
{/* Newsletter: type selection */}
|
||||||
<Route path="new" component={ NewsletterTypes } />
|
<Route path="new" component={ NewsletterTypes } />
|
||||||
{/* New newsletter: types */}
|
{/* New newsletter: types */}
|
||||||
<Route name="new/standard" path="new/standard" component={ NewsletterTypeStandard } />
|
<Route path="new/standard" component={ NewsletterTypeStandard } />
|
||||||
<Route name="new/welcome" path="new/welcome" component={ NewsletterTypeWelcome } />
|
<Route path="new/welcome" component={ NewsletterTypeWelcome } />
|
||||||
<Route name="new/notification" path="new/notification" component={ NewsletterTypeNotification } />
|
<Route path="new/notification" component={ NewsletterTypeNotification } />
|
||||||
{/* Template selection */}
|
{/* Template selection */}
|
||||||
<Route name="template" path="template/:id" component={ NewsletterTemplates } />
|
<Route name="template" path="template/:id" component={ NewsletterTemplates } />
|
||||||
{/* Sending options */}
|
{/* Sending options */}
|
||||||
|
@ -66,22 +66,22 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'get',
|
action: 'get',
|
||||||
data: id
|
data: {
|
||||||
}).done((response) => {
|
id: id
|
||||||
if(response === false) {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
item: {},
|
|
||||||
}, function() {
|
|
||||||
this.context.router.push('/new');
|
|
||||||
}.bind(this));
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
item: response,
|
|
||||||
fields: this.getFieldsByNewsletter(response),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}).done((response) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
item: response.data,
|
||||||
|
fields: this.getFieldsByNewsletter(response.data)
|
||||||
|
});
|
||||||
|
}).fail((response) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
item: {}
|
||||||
|
}, () => {
|
||||||
|
this.context.router.push('/new');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSend: function(e) {
|
handleSend: function(e) {
|
||||||
@ -90,78 +90,110 @@ define(
|
|||||||
if(!this.isValid()) {
|
if(!this.isValid()) {
|
||||||
jQuery('#mailpoet_newsletter').parsley().validate();
|
jQuery('#mailpoet_newsletter').parsley().validate();
|
||||||
} else {
|
} else {
|
||||||
this.setState({ loading: true });
|
this._save(e).done(() => {
|
||||||
|
this.setState({ loading: true });
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'newsletters',
|
|
||||||
action: 'save',
|
|
||||||
data: this.state.item,
|
|
||||||
}).then((response) => {
|
|
||||||
if (response.result === true) {
|
|
||||||
return MailPoet.Ajax.post({
|
|
||||||
endpoint: 'sendingQueue',
|
|
||||||
action: 'add',
|
|
||||||
data: _.extend({}, this.state.item, {
|
|
||||||
newsletter_id: this.props.params.id,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}).done((response) => {
|
}).done((response) => {
|
||||||
this.setState({ loading: false });
|
switch (response.data.type) {
|
||||||
|
case 'notification':
|
||||||
|
case 'welcome':
|
||||||
|
return MailPoet.Ajax.post({
|
||||||
|
endpoint: 'newsletters',
|
||||||
|
action: 'setStatus',
|
||||||
|
data: {
|
||||||
|
id: this.props.params.id,
|
||||||
|
status: 'active'
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
|
// redirect to listing based on newsletter type
|
||||||
|
this.context.router.push(`/${ this.state.item.type || '' }`);
|
||||||
|
|
||||||
if(response.result === true) {
|
// display success message depending on newsletter type
|
||||||
this.context.router.push(`/${ this.state.item.type || '' }`);
|
if (response.data.type === 'welcome') {
|
||||||
MailPoet.Notice.success(response.data.message);
|
MailPoet.Notice.success(
|
||||||
} else {
|
MailPoet.I18n.t('welcomeEmailActivated')
|
||||||
if(response.errors) {
|
);
|
||||||
MailPoet.Notice.error(response.errors);
|
} else if (response.data.type === 'notification') {
|
||||||
} else {
|
MailPoet.Notice.success(
|
||||||
MailPoet.Notice.error(
|
MailPoet.I18n.t('postNotificationActivated')
|
||||||
MailPoet.I18n.t('newsletterSendingError').replace("%$1s", '?page=mailpoet-settings')
|
);
|
||||||
);
|
}
|
||||||
}
|
}).fail(this._showError);
|
||||||
|
default:
|
||||||
|
return MailPoet.Ajax.post({
|
||||||
|
endpoint: 'sendingQueue',
|
||||||
|
action: 'add',
|
||||||
|
data: {
|
||||||
|
newsletter_id: this.props.params.id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
|
// redirect to listing based on newsletter type
|
||||||
|
this.context.router.push(`/${ this.state.item.type || '' }`);
|
||||||
|
|
||||||
|
if (response.data.status === 'scheduled') {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('newsletterHasBeenScheduled')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('newsletterBeingSent')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).fail(this._showError);
|
||||||
}
|
}
|
||||||
|
}).fail(this._showError).always(() => {
|
||||||
|
this.setState({ loading: false });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
handleSave: function(e) {
|
handleSave: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._save(e).done(() => {
|
|
||||||
|
this._save(e).done((response) => {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('newsletterUpdated')
|
||||||
|
);
|
||||||
|
}).done(() => {
|
||||||
this.context.router.push(`/${ this.state.item.type || '' }`);
|
this.context.router.push(`/${ this.state.item.type || '' }`);
|
||||||
});
|
}).fail(this._showError);
|
||||||
},
|
},
|
||||||
handleRedirectToDesign: function(e) {
|
handleRedirectToDesign: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var redirectTo = e.target.href;
|
var redirectTo = e.target.href;
|
||||||
|
|
||||||
this._save(e).done(() => {
|
this._save(e).done((response) => {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('newsletterUpdated')
|
||||||
|
);
|
||||||
|
}).done(() => {
|
||||||
window.location = redirectTo;
|
window.location = redirectTo;
|
||||||
});
|
}).fail(this._showError);
|
||||||
},
|
},
|
||||||
_save: function(e) {
|
_save: function(e) {
|
||||||
|
var data = this.state.item;
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
// Ensure that body is JSON encoded
|
||||||
|
if (!_.isUndefined(data.body)) {
|
||||||
|
data.body = JSON.stringify(data.body);
|
||||||
|
}
|
||||||
|
|
||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: this.state.item,
|
data: data,
|
||||||
}).done((response) => {
|
}).always(() => {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
|
|
||||||
if(response.result === true) {
|
|
||||||
MailPoet.Notice.success(
|
|
||||||
MailPoet.I18n.t('newsletterUpdated')
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if(response.errors) {
|
|
||||||
MailPoet.Notice.error(response.errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
_showError: (response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
handleFormChange: function(e) {
|
handleFormChange: function(e) {
|
||||||
var item = this.state.item,
|
var item = this.state.item,
|
||||||
field = e.target.name;
|
field = e.target.name;
|
||||||
|
@ -30,33 +30,35 @@ define(
|
|||||||
endpoint: 'newsletterTemplates',
|
endpoint: 'newsletterTemplates',
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: template
|
data: template
|
||||||
}).done(function(response) {
|
}).always(function() {
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
if(response.result === true) {
|
}).done((response) => {
|
||||||
this.props.onImport(template);
|
this.props.onImport(response.data);
|
||||||
} else {
|
}).fail((response) => {
|
||||||
response.map(function(error) {
|
if (response.errors.length > 0) {
|
||||||
MailPoet.Notice.error(error);
|
MailPoet.Notice.error(
|
||||||
});
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
handleSubmit: function(e) {
|
handleSubmit: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (_.size(this.refs.templateFile.files) <= 0) return false;
|
if (_.size(this.refs.templateFile.files) <= 0) return false;
|
||||||
|
|
||||||
var file = _.first(this.refs.templateFile.files),
|
var file = _.first(this.refs.templateFile.files);
|
||||||
reader = new FileReader(),
|
var reader = new FileReader();
|
||||||
saveTemplate = this.saveTemplate;
|
var saveTemplate = this.saveTemplate;
|
||||||
|
|
||||||
reader.onload = function(e) {
|
reader.onload = (e) => {
|
||||||
try {
|
try {
|
||||||
saveTemplate(JSON.parse(e.target.result));
|
saveTemplate(JSON.parse(e.target.result));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('templateFileMalformedError'));
|
MailPoet.Notice.error(MailPoet.I18n.t('templateFileMalformedError'));
|
||||||
}
|
}
|
||||||
}.bind(this);
|
};
|
||||||
|
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
},
|
},
|
||||||
@ -97,12 +99,12 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletterTemplates',
|
endpoint: 'newsletterTemplates',
|
||||||
action: 'getAll',
|
action: 'getAll',
|
||||||
}).done(function(response) {
|
}).always(() => {
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
if(this.isMounted()) {
|
}).done((response) => {
|
||||||
|
if (this.isMounted()) {
|
||||||
if(response.length === 0) {
|
if (response.data.length === 0) {
|
||||||
response = [
|
response.data = [
|
||||||
{
|
{
|
||||||
name:
|
name:
|
||||||
MailPoet.I18n.t('mailpoetGuideTemplateTitle'),
|
MailPoet.I18n.t('mailpoetGuideTemplateTitle'),
|
||||||
@ -110,14 +112,14 @@ define(
|
|||||||
MailPoet.I18n.t('mailpoetGuideTemplateDescription'),
|
MailPoet.I18n.t('mailpoetGuideTemplateDescription'),
|
||||||
readonly: "1"
|
readonly: "1"
|
||||||
}
|
}
|
||||||
]
|
];
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
templates: response,
|
templates: response.data,
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
handleSelectTemplate: function(template) {
|
handleSelectTemplate: function(template) {
|
||||||
var body = template.body;
|
var body = template.body;
|
||||||
@ -134,19 +136,17 @@ define(
|
|||||||
id: this.props.params.id,
|
id: this.props.params.id,
|
||||||
body: body
|
body: body
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result === true) {
|
// TODO: Move this URL elsewhere
|
||||||
// TODO: Move this URL elsewhere
|
window.location = 'admin.php?page=mailpoet-newsletter-editor&id=' + response.data.id;
|
||||||
window.location = 'admin.php?page=mailpoet-newsletter-editor&id=' + this.props.params.id;
|
}).fail((response) => {
|
||||||
} else {
|
if (response.errors.length > 0) {
|
||||||
response.errors.map(function(error) {
|
MailPoet.Notice.error(
|
||||||
MailPoet.Notice.error(error);
|
response.errors.map(function(error) { return error.message; }),
|
||||||
});
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
|
||||||
handlePreviewTemplate: function(template) {
|
|
||||||
console.log('preview template #'+template.id);
|
|
||||||
},
|
},
|
||||||
handleDeleteTemplate: function(template) {
|
handleDeleteTemplate: function(template) {
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
@ -160,10 +160,12 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'newsletterTemplates',
|
endpoint: 'newsletterTemplates',
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
data: template.id
|
data: {
|
||||||
}).done(function(response) {
|
id: template.id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
this.getTemplates();
|
this.getTemplates();
|
||||||
}.bind(this));
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ define(
|
|||||||
MailPoet.Modal.popup({
|
MailPoet.Modal.popup({
|
||||||
title: template.name,
|
title: template.name,
|
||||||
template: '<div class="mailpoet_boxes_preview" style="background-color: {{ body.globalStyles.body.backgroundColor }}"><img src="{{ thumbnail }}" /></div>',
|
template: '<div class="mailpoet_boxes_preview" style="background-color: {{ body.globalStyles.body.backgroundColor }}"><img src="{{ thumbnail }}" /></div>',
|
||||||
data: template,
|
data: template
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleTemplateImport: function() {
|
handleTemplateImport: function() {
|
||||||
@ -213,20 +215,19 @@ define(
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mailpoet_actions">
|
<div className="mailpoet_actions">
|
||||||
|
<a
|
||||||
|
className="button button-secondary"
|
||||||
|
onClick={ this.handleShowTemplate.bind(null, template) }
|
||||||
|
>
|
||||||
|
{MailPoet.I18n.t('preview')}
|
||||||
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
className="button button-primary"
|
className="button button-primary"
|
||||||
onClick={ this.handleSelectTemplate.bind(null, template) }
|
onClick={ this.handleSelectTemplate.bind(null, template) }
|
||||||
>
|
>
|
||||||
{MailPoet.I18n.t('select')}
|
{MailPoet.I18n.t('select')}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
|
||||||
style={ { display: 'none' }}
|
|
||||||
className="button button-secondary"
|
|
||||||
onClick={ this.handlePreviewTemplate.bind(null, template) }
|
|
||||||
>
|
|
||||||
{MailPoet.I18n.t('preview')}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
{ (template.readonly === "1") ? false : deleteLink }
|
{ (template.readonly === "1") ? false : deleteLink }
|
||||||
</li>
|
</li>
|
||||||
|
@ -28,17 +28,16 @@ define(
|
|||||||
type: type,
|
type: type,
|
||||||
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.newsletter.id) {
|
this.context.router.push(`/template/${response.data.id}`);
|
||||||
this.context.router.push(`/template/${response.newsletter.id}`);
|
}).fail((response) => {
|
||||||
} else {
|
if (response.errors.length > 0) {
|
||||||
if(response.errors.length > 0) {
|
MailPoet.Notice.error(
|
||||||
response.errors.map(function(error) {
|
response.errors.map(function(error) { return error.message; }),
|
||||||
MailPoet.Notice.error(error);
|
{ scroll: true }
|
||||||
});
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
|
@ -50,17 +50,16 @@ define(
|
|||||||
type: 'notification',
|
type: 'notification',
|
||||||
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
||||||
}),
|
}),
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.newsletter.id) {
|
this.showTemplateSelection(response.data.id);
|
||||||
this.showTemplateSelection(response.newsletter.id);
|
}).fail((response) => {
|
||||||
} else {
|
if (response.errors.length > 0) {
|
||||||
if(response.errors.length > 0) {
|
MailPoet.Notice.error(
|
||||||
response.errors.map(function(error) {
|
response.errors.map(function(error) { return error.message; }),
|
||||||
MailPoet.Notice.error(error);
|
{ scroll: true }
|
||||||
});
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
showTemplateSelection: function(newsletterId) {
|
showTemplateSelection: function(newsletterId) {
|
||||||
this.context.router.push(`/template/${newsletterId}`);
|
this.context.router.push(`/template/${newsletterId}`);
|
||||||
|
@ -25,19 +25,18 @@ define(
|
|||||||
endpoint: 'newsletters',
|
endpoint: 'newsletters',
|
||||||
action: 'create',
|
action: 'create',
|
||||||
data: {
|
data: {
|
||||||
type: 'standard',
|
type: 'standard'
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.newsletter.id) {
|
this.showTemplateSelection(response.data.id);
|
||||||
this.showTemplateSelection(response.newsletter.id);
|
}).fail((response) => {
|
||||||
} else {
|
if (response.errors.length > 0) {
|
||||||
if(response.errors.length > 0) {
|
MailPoet.Notice.error(
|
||||||
response.errors.map(function(error) {
|
response.errors.map(function(error) { return error.message; }),
|
||||||
MailPoet.Notice.error(error);
|
{ scroll: true }
|
||||||
});
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
|
@ -113,17 +113,16 @@ const WelcomeScheduling = React.createClass({
|
|||||||
type: 'welcome',
|
type: 'welcome',
|
||||||
options: this.state
|
options: this.state
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if (response.result && response.newsletter.id) {
|
this.showTemplateSelection(response.data.id);
|
||||||
this.showTemplateSelection(response.newsletter.id);
|
}).fail((response) => {
|
||||||
} else {
|
|
||||||
if (response.errors.length > 0) {
|
if (response.errors.length > 0) {
|
||||||
response.errors.map(function(error) {
|
MailPoet.Notice.error(
|
||||||
MailPoet.Notice.error(error);
|
response.errors.map(function(error) { return error.message; }),
|
||||||
});
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}.bind(this));
|
|
||||||
},
|
},
|
||||||
showTemplateSelection: function(newsletterId) {
|
showTemplateSelection: function(newsletterId) {
|
||||||
this.context.router.push(`/template/${ newsletterId }`);
|
this.context.router.push(`/template/${ newsletterId }`);
|
||||||
|
@ -57,18 +57,17 @@ define(
|
|||||||
data: _.extend({}, this.state, {
|
data: _.extend({}, this.state, {
|
||||||
type: 'welcome',
|
type: 'welcome',
|
||||||
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
||||||
}),
|
})
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.newsletter.id) {
|
this.showTemplateSelection(response.data.id);
|
||||||
this.showTemplateSelection(response.newsletter.id);
|
}).fail((response) => {
|
||||||
} else {
|
if (response.errors.length > 0) {
|
||||||
if(response.errors.length > 0) {
|
MailPoet.Notice.error(
|
||||||
response.errors.map(function(error) {
|
response.errors.map(function(error) { return error.message; }),
|
||||||
MailPoet.Notice.error(error);
|
{ scroll: true }
|
||||||
});
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
showTemplateSelection: function(newsletterId) {
|
showTemplateSelection: function(newsletterId) {
|
||||||
this.context.router.push(`/template/${newsletterId}`);
|
this.context.router.push(`/template/${newsletterId}`);
|
||||||
|
@ -36,48 +36,48 @@ var columns = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash: function(response) {
|
onTrash: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneSegmentTrashed')
|
MailPoet.I18n.t('oneSegmentTrashed')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleSegmentsTrashed')
|
MailPoet.I18n.t('multipleSegmentsTrashed')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete: function(response) {
|
onDelete: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneSegmentDeleted')
|
MailPoet.I18n.t('oneSegmentDeleted')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleSegmentsDeleted')
|
MailPoet.I18n.t('multipleSegmentsDeleted')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore: function(response) {
|
onRestore: (response) => {
|
||||||
var count = ~~response;
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
|
|
||||||
if(count === 1) {
|
if (count === 1) {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('oneSegmentRestored')
|
MailPoet.I18n.t('oneSegmentRestored')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
message = (
|
message = (
|
||||||
MailPoet.I18n.t('multipleSegmentsRestored')
|
MailPoet.I18n.t('multipleSegmentsRestored')
|
||||||
).replace('%$1d', count);
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
@ -106,16 +106,23 @@ const item_actions = [
|
|||||||
{
|
{
|
||||||
name: 'duplicate_segment',
|
name: 'duplicate_segment',
|
||||||
label: MailPoet.I18n.t('duplicate'),
|
label: MailPoet.I18n.t('duplicate'),
|
||||||
onClick: function(item, refresh) {
|
onClick: (item, refresh) => {
|
||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'segments',
|
endpoint: 'segments',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: item.id
|
data: {
|
||||||
}).done(function(response) {
|
id: item.id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
(MailPoet.I18n.t('listDuplicated')).replace('%$1s', response.name)
|
MailPoet.I18n.t('listDuplicated').replace('%$1s', response.data.name)
|
||||||
);
|
);
|
||||||
refresh();
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
display: function(segment) {
|
display: function(segment) {
|
||||||
|
@ -133,8 +133,7 @@ define(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MailPoet.Modal.loading(true);
|
MailPoet.Modal.loading(true);
|
||||||
MailPoet.Ajax
|
MailPoet.Ajax.post({
|
||||||
.post({
|
|
||||||
endpoint: 'ImportExport',
|
endpoint: 'ImportExport',
|
||||||
action: 'processExport',
|
action: 'processExport',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
@ -144,25 +143,22 @@ define(
|
|||||||
'segments': (exportData.segments) ? segmentsContainerElement.val() : false,
|
'segments': (exportData.segments) ? segmentsContainerElement.val() : false,
|
||||||
'subscriber_fields': subscriberFieldsContainerElement.val()
|
'subscriber_fields': subscriberFieldsContainerElement.val()
|
||||||
})
|
})
|
||||||
})
|
}).always(function(response) {
|
||||||
.done(function (response) {
|
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
if (response.result === false) {
|
}).done(function(response) {
|
||||||
MailPoet.Notice.error(response.errors);
|
resultMessage = MailPoet.I18n.t('exportMessage')
|
||||||
} else {
|
.replace('%1$s', '<strong>' + parseInt(response.data.totalExported).toLocaleString() + '</strong>')
|
||||||
resultMessage = MailPoet.I18n.t('exportMessage')
|
.replace('[link]', '<a href="' + response.data.exportFileURL + '" target="_blank" >')
|
||||||
.replace('%1$s', '<strong>' + parseInt(response.data.totalExported).toLocaleString() + '</strong>')
|
.replace('[/link]', '</a>');
|
||||||
.replace('[link]', '<a href="' + response.data.exportFileURL + '" target="_blank" >')
|
jQuery('#export_result_notice').html('<p>' + resultMessage + '</p>').show();
|
||||||
.replace('[/link]', '</a>');
|
window.location.href = response.data.exportFileURL;
|
||||||
jQuery('#export_result_notice').html('<p>' + resultMessage + '</p>').show();
|
}).fail(function(response) {
|
||||||
window.location.href = response.data.exportFileURL;
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.error(function (error) {
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoet.I18n.t('serverError') + error.statusText.toLowerCase() + '.'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -51,6 +51,12 @@ define(
|
|||||||
* STEP 1 (upload or copy/paste)
|
* STEP 1 (upload or copy/paste)
|
||||||
*/
|
*/
|
||||||
router.on('route:step1', function () {
|
router.on('route:step1', function () {
|
||||||
|
// set or reset temporary validation rule on all columns
|
||||||
|
mailpoetColumns = jQuery.map(mailpoetColumns, function (column, columnIndex) {
|
||||||
|
column.validation_rule = false;
|
||||||
|
return column;
|
||||||
|
});
|
||||||
|
|
||||||
if (typeof (importData.step1) !== 'undefined') {
|
if (typeof (importData.step1) !== 'undefined') {
|
||||||
showCurrentStep();
|
showCurrentStep();
|
||||||
return;
|
return;
|
||||||
@ -185,68 +191,59 @@ define(
|
|||||||
mailChimpKeyVerifyButtonElement.click(function () {
|
mailChimpKeyVerifyButtonElement.click(function () {
|
||||||
MailPoet.Modal.loading(true);
|
MailPoet.Modal.loading(true);
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'ImportExport',
|
endpoint: 'importExport',
|
||||||
action: 'getMailChimpLists',
|
action: 'getMailChimpLists',
|
||||||
data: {api_key: mailChimpKeyInputElement.val()}
|
data: {
|
||||||
}).done(function (response) {
|
api_key: mailChimpKeyInputElement.val()
|
||||||
if (response.result === false) {
|
}
|
||||||
MailPoet.Notice.hide();
|
}).always(function() {
|
||||||
MailPoet.Notice.error(response.errors);
|
MailPoet.Modal.loading(false);
|
||||||
jQuery('.mailpoet_mailchimp-key-status')
|
}).done(function(response) {
|
||||||
.removeClass()
|
jQuery('.mailpoet_mailchimp-key-status')
|
||||||
.addClass('mailpoet_mailchimp-key-status mailpoet_mailchimp-error');
|
.html('')
|
||||||
|
.removeClass()
|
||||||
|
.addClass('mailpoet_mailchimp-key-status mailpoet_mailchimp-ok');
|
||||||
|
if (response.data.length === 0) {
|
||||||
|
jQuery('.mailpoet_mailchimp-key-status').html(MailPoet.I18n.t('noMailChimpLists'));
|
||||||
mailChimpListsContainerElement.hide();
|
mailChimpListsContainerElement.hide();
|
||||||
toggleNextStepButton(mailChimpProcessButtonElement, 'off');
|
toggleNextStepButton(mailChimpProcessButtonElement, 'off');
|
||||||
} else {
|
} else {
|
||||||
jQuery('.mailpoet_mailchimp-key-status')
|
displayMailChimpLists(response.data);
|
||||||
.html('')
|
}
|
||||||
.removeClass()
|
}).fail(function(response) {
|
||||||
.addClass('mailpoet_mailchimp-key-status mailpoet_mailchimp-ok');
|
if (response.errors.length > 0) {
|
||||||
if (!response.data) {
|
MailPoet.Notice.error(
|
||||||
jQuery('.mailpoet_mailchimp-key-status').html(MailPoet.I18n.t('noMailChimpLists'));
|
response.errors.map(function(error) { return error.message; }),
|
||||||
mailChimpListsContainerElement.hide();
|
{ scroll: true }
|
||||||
toggleNextStepButton(mailChimpProcessButtonElement, 'off');
|
);
|
||||||
} else {
|
|
||||||
displayMailChimpLists(response.data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
}).error(function (error) {
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoet.I18n.t('serverError') + error.statusText.toLowerCase() + '.'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mailChimpProcessButtonElement.click(function () {
|
mailChimpProcessButtonElement.click(function () {
|
||||||
if (mailChimpProcessButtonElement.closest('table a').hasClass('disabled')) {
|
if (mailChimpProcessButtonElement.closest('table a').hasClass('button-disabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MailPoet.Modal.loading(true);
|
MailPoet.Modal.loading(true);
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'ImportExport',
|
endpoint: 'importExport',
|
||||||
action: 'getMailChimpSubscribers',
|
action: 'getMailChimpSubscribers',
|
||||||
data: {
|
data: {
|
||||||
api_key: mailChimpKeyInputElement.val(),
|
api_key: mailChimpKeyInputElement.val(),
|
||||||
lists: mailChimpListsContainerElement.find('select').val()
|
lists: mailChimpListsContainerElement.find('select').val()
|
||||||
}
|
}
|
||||||
}).done(function (response) {
|
}).always(function(response) {
|
||||||
if (response.result === true) {
|
|
||||||
importData.step1 = response.data;
|
|
||||||
router.navigate('step2', {trigger: true});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MailPoet.Notice.hide();
|
|
||||||
MailPoet.Notice.error(response.errors);
|
|
||||||
}
|
|
||||||
MailPoet.Modal.loading(false);
|
MailPoet.Modal.loading(false);
|
||||||
}).error(function () {
|
}).done(function(response) {
|
||||||
MailPoet.Modal.loading(false);
|
importData.step1 = response.data;
|
||||||
MailPoet.Notice.error(
|
router.navigate('step2', {trigger: true});
|
||||||
MailPoet.I18n.t('serverError') + result.statusText.toLowerCase() + '.'
|
}).fail(function(response) {
|
||||||
);
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -455,7 +452,7 @@ define(
|
|||||||
null,
|
null,
|
||||||
new Array(subscribers.subscribers[0].length)
|
new Array(subscribers.subscribers[0].length)
|
||||||
).map(String.prototype.valueOf, filler),
|
).map(String.prototype.valueOf, filler),
|
||||||
fillterPosition;
|
fillerPosition;
|
||||||
|
|
||||||
showCurrentStep();
|
showCurrentStep();
|
||||||
|
|
||||||
@ -565,79 +562,54 @@ define(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery('.mailpoet_create_segment').click(function () {
|
jQuery('.mailpoet_create_segment').click(function() {
|
||||||
MailPoet.Modal.popup({
|
MailPoet.Modal.popup({
|
||||||
title: MailPoet.I18n.t('addNewList'),
|
title: MailPoet.I18n.t('addNewList'),
|
||||||
template: jQuery('#new_segment_template').html()
|
template: jQuery('#new_segment_template').html()
|
||||||
})
|
})
|
||||||
jQuery('#new_segment_name').keypress(function (e) {
|
jQuery('#new_segment_name').keypress(function(e) {
|
||||||
if (e.which == 13) {
|
if (e.which == 13) {
|
||||||
jQuery('#new_segment_process').click();
|
jQuery('#new_segment_process').click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jQuery('#new_segment_process').click(function () {
|
jQuery('#new_segment_process').click(function () {
|
||||||
var segmentName = jQuery('#new_segment_name').val().trim(),
|
var segmentName = jQuery('#new_segment_name').val().trim();
|
||||||
segmentDescription = jQuery('#new_segment_description').val().trim(),
|
var segmentDescription = jQuery('#new_segment_description').val().trim();
|
||||||
isDuplicateListName = ( jQuery.map(mailpoetSegments, function (el) {
|
|
||||||
if (el.name.toLowerCase() === segmentName.toLowerCase()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}).length && segmentName) ? true : false;
|
|
||||||
if (segmentName === '') {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="segment_name_required"]:hidden').show();
|
|
||||||
} else {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="segment_name_required"]:visible').hide();
|
|
||||||
}
|
|
||||||
if (isDuplicateListName) {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="segment_name_not_unique"]:hidden').show();
|
|
||||||
} else {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="segment_name_not_unique"]:visible').hide();
|
|
||||||
}
|
|
||||||
if (segmentName && !isDuplicateListName) {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="segment_name_required"]:visible').hide();
|
|
||||||
MailPoet.Ajax
|
|
||||||
.post({
|
|
||||||
endpoint: 'ImportExport',
|
|
||||||
action: 'addSegment',
|
|
||||||
data: {
|
|
||||||
name: segmentName,
|
|
||||||
description: segmentDescription
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.done(function (response) {
|
|
||||||
if (response.result === true) {
|
|
||||||
mailpoetSegments.push({
|
|
||||||
'id': response.segment.id,
|
|
||||||
'name': response.segment.name
|
|
||||||
});
|
|
||||||
|
|
||||||
var selected_values = segmentSelectElement.val();
|
MailPoet.Ajax.post({
|
||||||
if (selected_values === null) {
|
endpoint: 'ImportExport',
|
||||||
selected_values = [response.segment.id]
|
action: 'addSegment',
|
||||||
} else {
|
data: {
|
||||||
selected_values.push(response.segment.id);
|
name: segmentName,
|
||||||
}
|
description: segmentDescription
|
||||||
|
}
|
||||||
|
}).done(function(response) {
|
||||||
|
mailpoetSegments.push({
|
||||||
|
'id': response.data.id,
|
||||||
|
'name': response.data.name
|
||||||
|
});
|
||||||
|
|
||||||
enableSegmentSelection(mailpoetSegments);
|
var selected_values = segmentSelectElement.val();
|
||||||
segmentSelectElement.val(selected_values).trigger('change');
|
if (selected_values === null) {
|
||||||
jQuery('.mailpoet_segments:hidden').show();
|
selected_values = [response.data.id]
|
||||||
jQuery('.mailpoet_no_segments:visible').hide();
|
} else {
|
||||||
MailPoet.Modal.close();
|
selected_values.push(response.data.id);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
MailPoet.Modal.close();
|
enableSegmentSelection(mailpoetSegments);
|
||||||
MailPoet.Notice.error(
|
segmentSelectElement.val(selected_values).trigger('change');
|
||||||
MailPoet.I18n.t('segmentCreateError') + response.message + '.'
|
jQuery('.mailpoet_segments:hidden').show();
|
||||||
);
|
jQuery('.mailpoet_no_segments:visible').hide();
|
||||||
}
|
MailPoet.Modal.close();
|
||||||
})
|
}).fail(function(response) {
|
||||||
.error(function (error) {
|
if (response.errors.length > 0) {
|
||||||
MailPoet.Modal.close();
|
MailPoet.Notice.hide();
|
||||||
MailPoet.Notice.error(
|
MailPoet.Notice.error(
|
||||||
MailPoet.I18n.t('serverError') + error.statusText.toLowerCase() + '.'
|
response.errors.map(function(error) { return error.message; }),
|
||||||
);
|
{ positionAfter: '#new_segment_name' }
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
jQuery('#new_segment_cancel').click(function () {
|
jQuery('#new_segment_cancel').click(function () {
|
||||||
MailPoet.Modal.close();
|
MailPoet.Modal.close();
|
||||||
@ -707,7 +679,7 @@ define(
|
|||||||
// display filler data (e.g., ellipsis) if we've reached the maximum number of rows and
|
// display filler data (e.g., ellipsis) if we've reached the maximum number of rows and
|
||||||
// subscribers count is greater than the maximum number of rows we're displaying
|
// subscribers count is greater than the maximum number of rows we're displaying
|
||||||
if (index === maxRowsToShow && subscribers.subscribersCount > (maxRowsToShow + 1)) {
|
if (index === maxRowsToShow && subscribers.subscribersCount > (maxRowsToShow + 1)) {
|
||||||
fillterPosition = index;
|
fillerPosition = index;
|
||||||
return filler;
|
return filler;
|
||||||
}
|
}
|
||||||
// if we're on the last line, show the total count of subscribers data
|
// if we're on the last line, show the total count of subscribers data
|
||||||
@ -745,114 +717,70 @@ define(
|
|||||||
.on('select2:selecting', function (selectEvent) {
|
.on('select2:selecting', function (selectEvent) {
|
||||||
var selectElement = this,
|
var selectElement = this,
|
||||||
selectedOptionId = selectEvent.params.args.data.id;
|
selectedOptionId = selectEvent.params.args.data.id;
|
||||||
|
// CREATE CUSTOM FIELD
|
||||||
if (selectedOptionId === 'create') {
|
if (selectedOptionId === 'create') {
|
||||||
selectEvent.preventDefault();
|
selectEvent.preventDefault();
|
||||||
jQuery(selectElement).select2('close');
|
jQuery(selectElement).select2('close');
|
||||||
MailPoet.Modal.popup({
|
MailPoet.Modal.popup({
|
||||||
title: MailPoet.I18n.t('addNewColumn'),
|
title: MailPoet.I18n.t('addNewField'),
|
||||||
template: jQuery('#new_column_template').html()
|
template: jQuery('#form_template_field_form').html()
|
||||||
});
|
});
|
||||||
jQuery('#new_column_name').keypress(function (e) {
|
jQuery('#form_field_new').parsley().on('form:submit', function(parsley) {
|
||||||
if (e.which == 13) {
|
// get data
|
||||||
jQuery('#new_column_process').click();
|
var data = jQuery(this.$element).serializeObject();
|
||||||
}
|
|
||||||
});
|
// save custom field
|
||||||
jQuery('#new_column_process').click(function () {
|
MailPoet.Ajax.post({
|
||||||
var name = jQuery('#new_column_name').val().trim(),
|
endpoint: 'customFields',
|
||||||
type = jQuery('#new_column_type').val().trim(),
|
action: 'save',
|
||||||
columnNames = mailpoetColumns.map(function (el) {
|
data: data
|
||||||
return el.name.toLowerCase();
|
}).done(function(response) {
|
||||||
|
var new_column_data = {
|
||||||
|
'id': response.data.id,
|
||||||
|
'name': response.data.name,
|
||||||
|
'type': response.data.type,
|
||||||
|
'params': response.data.params,
|
||||||
|
'custom': true
|
||||||
|
};
|
||||||
|
// if this is the first custom column, create an "optgroup"
|
||||||
|
if (mailpoetColumnsSelect2.length === 2) {
|
||||||
|
mailpoetColumnsSelect2.push({
|
||||||
|
'name': MailPoet.I18n.t('userColumns'),
|
||||||
|
'children': []
|
||||||
});
|
});
|
||||||
isDuplicateColumnName =
|
}
|
||||||
(name && columnNames.indexOf(name.toLowerCase()) > -1)
|
mailpoetColumnsSelect2[2].children.push(new_column_data);
|
||||||
? true
|
mailpoetColumns.push(new_column_data);
|
||||||
: false;
|
jQuery('select.mailpoet_subscribers_column_data_match')
|
||||||
if (name === '') {
|
.each(function () {
|
||||||
jQuery('.mailpoet_validation_error[data-error="name_required"]')
|
jQuery(this)
|
||||||
.show();
|
.html('')
|
||||||
} else {
|
.select2('destroy')
|
||||||
jQuery('.mailpoet_validation_error[data-error="name_required"]')
|
.select2({
|
||||||
.hide();
|
data: mailpoetColumnsSelect2,
|
||||||
}
|
width: '15em',
|
||||||
if (type === '') {
|
templateResult: function (item) {
|
||||||
jQuery('.mailpoet_validation_error[data-error="type_required"]')
|
return item.name;
|
||||||
.show();
|
},
|
||||||
} else {
|
templateSelection: function (item) {
|
||||||
jQuery('.mailpoet_validation_error[data-error="type_required"]')
|
return item.name;
|
||||||
.hide();
|
|
||||||
}
|
|
||||||
if (isDuplicateColumnName) {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="name_not_unique"]')
|
|
||||||
.show();
|
|
||||||
} else {
|
|
||||||
jQuery('.mailpoet_validation_error[data-error="name_not_unique"]')
|
|
||||||
.hide();
|
|
||||||
}
|
|
||||||
// create new field
|
|
||||||
if (name && type && !isDuplicateColumnName) {
|
|
||||||
MailPoet.Modal
|
|
||||||
.close()
|
|
||||||
.loading(true);
|
|
||||||
MailPoet.Ajax
|
|
||||||
.post({
|
|
||||||
endpoint: 'ImportExport',
|
|
||||||
action: 'addCustomField',
|
|
||||||
data: {
|
|
||||||
name: name,
|
|
||||||
type: type
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.done(function (response) {
|
|
||||||
if (response.result === true) {
|
|
||||||
var new_column_data = {
|
|
||||||
'id': response.customField.id,
|
|
||||||
'name': name,
|
|
||||||
'type': type,
|
|
||||||
'custom': true,
|
|
||||||
};
|
|
||||||
// if this is the first custom column, create an "optgroup"
|
|
||||||
if (mailpoetColumnsSelect2.length === 2) {
|
|
||||||
mailpoetColumnsSelect2.push({
|
|
||||||
'name': MailPoet.I18n.t('userColumns'),
|
|
||||||
'children': []
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
mailpoetColumnsSelect2[2].children.push(new_column_data);
|
})
|
||||||
mailpoetColumns.push(new_column_data);
|
});
|
||||||
jQuery('select.mailpoet_subscribers_column_data_match')
|
jQuery(selectElement).data('column-id', new_column_data.id);
|
||||||
.each(function () {
|
jQuery(selectElement).data('validation-rule', false);
|
||||||
jQuery(this)
|
filterSubscribers();
|
||||||
.html('')
|
// close popup
|
||||||
.select2('destroy')
|
MailPoet.Modal.close();
|
||||||
.select2({
|
}).fail(function(response) {
|
||||||
data: mailpoetColumnsSelect2,
|
if (response.errors.length > 0) {
|
||||||
width: '15em',
|
MailPoet.Notice.error(
|
||||||
templateResult: function (item) {
|
response.errors.map(function(error) { return error.message; }),
|
||||||
return item.name;
|
{ positionAfter: '#field_name' }
|
||||||
},
|
);
|
||||||
templateSelection: function (item) {
|
}
|
||||||
return item.name;
|
});
|
||||||
}
|
return false;
|
||||||
})
|
|
||||||
});
|
|
||||||
jQuery(selectElement).data('column-id', new_column_data.id);
|
|
||||||
filterSubscribers();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('customFieldCreateError'));
|
|
||||||
}
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
})
|
|
||||||
.error(function (error) {
|
|
||||||
MailPoet.Modal.loading(false);
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
MailPoet.I18n.t('serverError') + error.statusText.toLowerCase() + '.'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jQuery('#new_column_cancel').click(function () {
|
|
||||||
MailPoet.Modal.close();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// CHANGE COLUMN
|
// CHANGE COLUMN
|
||||||
@ -890,22 +818,22 @@ define(
|
|||||||
.remove();
|
.remove();
|
||||||
var subscribersClone = jQuery.extend(true, {}, subscribers),
|
var subscribersClone = jQuery.extend(true, {}, subscribers),
|
||||||
preventNextStep = false,
|
preventNextStep = false,
|
||||||
displayedColumnsIds = jQuery.map(
|
displayedColumns = jQuery.map(
|
||||||
jQuery('.mailpoet_subscribers_column_data_match'), function (data) {
|
jQuery('.mailpoet_subscribers_column_data_match'), function (element, elementIndex) {
|
||||||
var columnId = jQuery(data).data('column-id');
|
var columnId = jQuery(element).data('column-id');
|
||||||
jQuery(data).val(columnId).trigger('change');
|
var validationRule = jQuery(element).data('validation-rule');
|
||||||
return columnId;
|
jQuery(element).val(columnId).trigger('change');
|
||||||
|
return { id: columnId, index: elementIndex, validationRule: validationRule, element: element };
|
||||||
});
|
});
|
||||||
// iterate through the object of mailpoet columns
|
// iterate through the object of mailpoet columns
|
||||||
jQuery.map(mailpoetColumns, function (column) {
|
jQuery.map(mailpoetColumns, function (column, columnIndex) {
|
||||||
// check if the column id matches the selected id of one of the
|
// check if the column id matches the selected id of one of the
|
||||||
// subscriber's data columns
|
// subscriber's data columns
|
||||||
var matchedColumn = jQuery.inArray(column.id, displayedColumnsIds);
|
var matchedColumn = _.find(displayedColumns, function(data) { return data.id === column.id; });
|
||||||
|
// EMAIL filter: if the first value in the column doesn't have a valid
|
||||||
// EMAIL filter: if the last value in the column doesn't have a valid
|
|
||||||
// email, hide the next button
|
// email, hide the next button
|
||||||
if (column.id === "email") {
|
if (column.id === 'email') {
|
||||||
if (!emailRegex.test(subscribersClone.subscribers[0][matchedColumn])) {
|
if (!emailRegex.test(subscribersClone.subscribers[0][matchedColumn.index])) {
|
||||||
preventNextStep = true;
|
preventNextStep = true;
|
||||||
if (!jQuery('[data-id="notice_invalidEmail"]').length) {
|
if (!jQuery('[data-id="notice_invalidEmail"]').length) {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
|
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
|
||||||
@ -921,35 +849,63 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// DATE filter: if column type is date, check if we can recognize it
|
// DATE filter: if column type is date, check if we can recognize it
|
||||||
if (column.type === 'date' && matchedColumn !== -1) {
|
if (column.type === 'date' && matchedColumn) {
|
||||||
jQuery.map(subscribersClone.subscribers, function (data, position) {
|
var allowedDateFormats = [
|
||||||
var rowData = data[matchedColumn];
|
Moment.ISO_8601,
|
||||||
if (position !== fillterPosition) {
|
'YYYY/MM/DD',
|
||||||
// check if date exists
|
'MM/DD/YYYY',
|
||||||
if (rowData.trim() === '') {
|
'DD/MM/YYYY',
|
||||||
data[matchedColumn] =
|
'YYYY/MM/DD',
|
||||||
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
'YYYY/DD/MM',
|
||||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
'MM/YYYY',
|
||||||
+ MailPoet.I18n.t('emptyDate')
|
'YYYY/MM',
|
||||||
+ '</span>';
|
'YYYY'
|
||||||
preventNextStep = true;
|
];
|
||||||
return;
|
var firstRowData = subscribersClone.subscribers[0][matchedColumn.index];
|
||||||
}
|
var validationRule = false;
|
||||||
// check if date is valid and is before today
|
// check if date exists
|
||||||
if (Moment(rowData).isValid() && Moment(rowData).isBefore(Moment())) {
|
if (firstRowData.trim() === '') {
|
||||||
data[matchedColumn] +=
|
subscribersClone.subscribers[0][matchedColumn.index] =
|
||||||
'<span class="mailpoet_data_match" title="'
|
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||||
+ MailPoet.I18n.t('verifyDateMatch') + '">'
|
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||||
+ MailPoet.Date.format(rowData) + '</span>';
|
+ MailPoet.I18n.t('emptyFirstRowDate')
|
||||||
}
|
+ '</span>';
|
||||||
else {
|
preventNextStep = true;
|
||||||
data[matchedColumn] +=
|
}
|
||||||
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
else {
|
||||||
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
for (var format in allowedDateFormats) {
|
||||||
+ MailPoet.I18n.t('dateMatchError') + '</span>';
|
var testedFormat = allowedDateFormats[format]
|
||||||
preventNextStep = true;
|
if (Moment(firstRowData, testedFormat, true).isValid()) {
|
||||||
|
var validationRule = (typeof(testedFormat) === 'function') ?
|
||||||
|
'datetime' :
|
||||||
|
testedFormat
|
||||||
|
// set validation on the column element
|
||||||
|
jQuery(matchedColumn.element).data('validation-rule', validationRule);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (validationRule === 'datetime') validationRule = Moment.ISO_8601;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
jQuery.map(subscribersClone.subscribers, function (data, index) {
|
||||||
|
var rowData = data[matchedColumn.index];
|
||||||
|
if (index === fillerPosition || rowData.trim() === '') return;
|
||||||
|
var date = Moment(rowData, testedFormat, true);
|
||||||
|
// validate date
|
||||||
|
if (date.isValid()) {
|
||||||
|
data[matchedColumn.index] +=
|
||||||
|
'<span class="mailpoet_data_match" title="'
|
||||||
|
+ MailPoet.I18n.t('verifyDateMatch') + '">'
|
||||||
|
+ MailPoet.Date.format(date)
|
||||||
|
+ '</span>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data[matchedColumn.index] +=
|
||||||
|
'<span class="mailpoet_data_match mailpoet_import_error" title="'
|
||||||
|
+ MailPoet.I18n.t('noDateFieldMatch') + '">'
|
||||||
|
+ MailPoet.I18n.t('dateMatchError')
|
||||||
|
+ '</span>';
|
||||||
|
preventNextStep = true;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
|
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidDate'), {
|
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidDate'), {
|
||||||
@ -983,11 +939,11 @@ define(
|
|||||||
nextStepButton.addClass(disabled);
|
nextStepButton.addClass(disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
previousStepButton.off().click(function () {
|
previousStepButton.off().on('click', function () {
|
||||||
router.navigate('step1', {trigger: true});
|
router.navigate('step1', { trigger: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
nextStepButton.off().click(function () {
|
nextStepButton.off().on('click', function () {
|
||||||
if (jQuery(this).hasClass('button-disabled')) {
|
if (jQuery(this).hasClass('button-disabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1019,44 +975,41 @@ define(
|
|||||||
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
_.each(jQuery('select.mailpoet_subscribers_column_data_match'),
|
||||||
function (column, columnIndex) {
|
function (column, columnIndex) {
|
||||||
var columnId = jQuery(column).data('column-id');
|
var columnId = jQuery(column).data('column-id');
|
||||||
|
var validationRule = jQuery(column).data('validation-rule');
|
||||||
if (columnId === 'ignore') {
|
if (columnId === 'ignore') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
columns[columnId] = columnIndex;
|
columns[columnId] = { index: columnIndex, validation_rule: validationRule };
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each(subscribers, function () {
|
_.each(subscribers, function () {
|
||||||
queue.add(function (queue) {
|
queue.add(function(queue) {
|
||||||
queue.pause();
|
queue.pause();
|
||||||
MailPoet.Ajax
|
MailPoet.Ajax.post({
|
||||||
.post({
|
endpoint: 'ImportExport',
|
||||||
endpoint: 'ImportExport',
|
action: 'processImport',
|
||||||
action: 'processImport',
|
data: JSON.stringify({
|
||||||
data: JSON.stringify({
|
columns: columns,
|
||||||
columns: columns,
|
subscribers: subscribers[batchNumber],
|
||||||
subscribers: subscribers[batchNumber],
|
timestamp: timestamp,
|
||||||
timestamp: timestamp,
|
segments: segmentSelectElement.val(),
|
||||||
segments: segmentSelectElement.val(),
|
updateSubscribers: (jQuery(':radio[name="subscriber_update_option"]:checked').val() === 'yes') ? true : false
|
||||||
updateSubscribers: (jQuery(':radio[name="subscriber_update_option"]:checked').val() === 'yes') ? true : false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.done(function (response) {
|
}).done(function(response) {
|
||||||
if (response.result === false) {
|
importResults.created = response.data.created;
|
||||||
importResults.errors.push(response.errors);
|
importResults.updated = response.data.updated;
|
||||||
} else {
|
importResults.segments = response.data.segments;
|
||||||
importResults.created = response.data.created;
|
importResults.added_to_segment_with_welcome_notification = response.data.added_to_segment_with_welcome_notification;
|
||||||
importResults.updated = response.data.updated;
|
queue.run();
|
||||||
importResults.segments = response.data.segments;
|
}).fail(function(response) {
|
||||||
importResults.added_to_segment_with_welcome_notification = response.data.added_to_segment_with_welcome_notification;
|
MailPoet.Modal.loading(false);
|
||||||
}
|
if (response.errors.length > 0) {
|
||||||
queue.run();
|
MailPoet.Notice.error(
|
||||||
})
|
response.errors.map(function(error) { return error.message; }),
|
||||||
.error(function (error) {
|
{ scroll: true }
|
||||||
importResults.errors.push(
|
|
||||||
MailPoet.I18n.t('serverError') + error.statusText.toLowerCase() + '.'
|
|
||||||
);
|
);
|
||||||
queue.run();
|
}
|
||||||
});
|
});
|
||||||
batchNumber++;
|
batchNumber++;
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -37,59 +37,50 @@ const columns = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash: function(response) {
|
onTrash: (response) => {
|
||||||
if (response) {
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
if (~~response === 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('oneSubscriberTrashed')
|
|
||||||
);
|
|
||||||
} else if (~~response > 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('multipleSubscribersTrashed')
|
|
||||||
).replace('%$1d', (~~response).toLocaleString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message !== null) {
|
if (count === 1) {
|
||||||
MailPoet.Notice.success(message);
|
message = (
|
||||||
}
|
MailPoet.I18n.t('oneSubscriberTrashed')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleSubscribersTrashed')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onDelete: function(response) {
|
onDelete: (response) => {
|
||||||
if (response) {
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
if (~~response === 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('oneSubscriberDeleted')
|
|
||||||
);
|
|
||||||
} else if (~~response > 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('multipleSubscribersDeleted')
|
|
||||||
).replace('%$1d', ~~response);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message !== null) {
|
if (count === 1) {
|
||||||
MailPoet.Notice.success(message);
|
message = (
|
||||||
}
|
MailPoet.I18n.t('oneSubscriberDeleted')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleSubscribersDeleted')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
},
|
},
|
||||||
onRestore: function(response) {
|
onRestore: (response) => {
|
||||||
if (response) {
|
const count = ~~response.meta.count;
|
||||||
var message = null;
|
let message = null;
|
||||||
if (~~response === 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('oneSubscriberRestored')
|
|
||||||
);
|
|
||||||
} else if (~~response > 1) {
|
|
||||||
message = (
|
|
||||||
MailPoet.I18n.t('multipleSubscribersRestored')
|
|
||||||
).replace('%$1d', (~~response).toLocaleString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message !== null) {
|
if (count === 1) {
|
||||||
MailPoet.Notice.success(message);
|
message = (
|
||||||
}
|
MailPoet.I18n.t('oneSubscriberRestored')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleSubscribersRestored')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
}
|
}
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,8 +111,8 @@ const bulk_actions = [
|
|||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
MailPoet.I18n.t('multipleSubscribersMovedToList')
|
MailPoet.I18n.t('multipleSubscribersMovedToList')
|
||||||
.replace('%$1d', (~~(response.subscribers)).toLocaleString())
|
.replace('%$1d', (~~(response.meta.count)).toLocaleString())
|
||||||
.replace('%$2s', response.segment)
|
.replace('%$2s', response.meta.segment)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -151,8 +142,8 @@ const bulk_actions = [
|
|||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
MailPoet.I18n.t('multipleSubscribersAddedToList')
|
MailPoet.I18n.t('multipleSubscribersAddedToList')
|
||||||
.replace('%$1d', (~~response.subscribers).toLocaleString())
|
.replace('%$1d', (~~response.meta.count).toLocaleString())
|
||||||
.replace('%$2s', response.segment)
|
.replace('%$2s', response.meta.segment)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -182,8 +173,8 @@ const bulk_actions = [
|
|||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
MailPoet.I18n.t('multipleSubscribersRemovedFromList')
|
MailPoet.I18n.t('multipleSubscribersRemovedFromList')
|
||||||
.replace('%$1d', (~~response.subscribers).toLocaleString())
|
.replace('%$1d', (~~response.meta.count).toLocaleString())
|
||||||
.replace('%$2s', response.segment)
|
.replace('%$2s', response.meta.segment)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -193,7 +184,7 @@ const bulk_actions = [
|
|||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
MailPoet.I18n.t('multipleSubscribersRemovedFromAllLists')
|
MailPoet.I18n.t('multipleSubscribersRemovedFromAllLists')
|
||||||
.replace('%$1d', (~~response).toLocaleString())
|
.replace('%$1d', (~~response.meta.count).toLocaleString())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -203,7 +194,7 @@ const bulk_actions = [
|
|||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
MailPoet.I18n.t('multipleConfirmationEmailsSent')
|
MailPoet.I18n.t('multipleConfirmationEmailsSent')
|
||||||
.replace('%$1d', (~~response).toLocaleString())
|
.replace('%$1d', (~~response.meta.count).toLocaleString())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -330,16 +321,23 @@ const SubscriberList = React.createClass({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onGetItems: function(count) {
|
|
||||||
jQuery('#mailpoet_export_button')[(count > 0) ? 'show' : 'hide']();
|
|
||||||
},
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1 className="title">
|
<h1 className="title">
|
||||||
{MailPoet.I18n.t('pageTitle')} <Link className="page-title-action" to="/new">{MailPoet.I18n.t('new')}</Link>
|
{MailPoet.I18n.t('pageTitle')} <Link
|
||||||
<a className="page-title-action" href="?page=mailpoet-import#step1">{MailPoet.I18n.t('import')}</a>
|
className="page-title-action"
|
||||||
<a id="mailpoet_export_button" className="page-title-action" href="?page=mailpoet-export">{MailPoet.I18n.t('export')}</a>
|
to="/new"
|
||||||
|
>{MailPoet.I18n.t('new')}</Link>
|
||||||
|
<a
|
||||||
|
className="page-title-action"
|
||||||
|
href="?page=mailpoet-import#step1"
|
||||||
|
>{MailPoet.I18n.t('import')}</a>
|
||||||
|
<a
|
||||||
|
id="mailpoet_export_button"
|
||||||
|
className="page-title-action"
|
||||||
|
href="?page=mailpoet-export"
|
||||||
|
>{MailPoet.I18n.t('export')}</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<Listing
|
<Listing
|
||||||
@ -352,7 +350,6 @@ const SubscriberList = React.createClass({
|
|||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
item_actions={ item_actions }
|
item_actions={ item_actions }
|
||||||
messages={ messages }
|
messages={ messages }
|
||||||
onGetItems={ this.onGetItems }
|
|
||||||
sort_by={ 'created_at' }
|
sort_by={ 'created_at' }
|
||||||
sort_order={ 'desc' }
|
sort_order={ 'desc' }
|
||||||
/>
|
/>
|
||||||
|
3
build.sh
@ -16,6 +16,9 @@ npm install
|
|||||||
# Production libraries.
|
# Production libraries.
|
||||||
./composer.phar install --no-dev
|
./composer.phar install --no-dev
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
./do makepot
|
||||||
|
|
||||||
# Copy release folders.
|
# Copy release folders.
|
||||||
cp -Rf lang $plugin_name
|
cp -Rf lang $plugin_name
|
||||||
cp -RfL assets $plugin_name
|
cp -RfL assets $plugin_name
|
||||||
|
61
circle.yml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
machine:
|
||||||
|
timezone:
|
||||||
|
UTC
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
mailpoet.loc: 127.0.0.1
|
||||||
|
|
||||||
|
## Customize dependencies
|
||||||
|
dependencies:
|
||||||
|
pre:
|
||||||
|
# install PHP dependencies for WordPress
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get --assume-yes install php5-mysql
|
||||||
|
# configure Apache
|
||||||
|
- sudo cp ./.circle_ci/apache/mailpoet.loc.conf /etc/apache2/sites-available
|
||||||
|
- sudo a2ensite mailpoet.loc
|
||||||
|
- sudo a2enmod rewrite
|
||||||
|
- sudo service apache2 restart
|
||||||
|
# install Phoenix dependencies
|
||||||
|
- composer install
|
||||||
|
- ./do install
|
||||||
|
# Set up Wordpress
|
||||||
|
# No password is required for the MySQL user `ubuntu`
|
||||||
|
- mysql -u ubuntu -e "create database wordpress"
|
||||||
|
# Use cURL to fetch WP-CLI
|
||||||
|
- curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
||||||
|
# Make sure WP-CLI is executable
|
||||||
|
- chmod +x wp-cli.phar
|
||||||
|
# Download WordPress into `wordpress` directory
|
||||||
|
- ./wp-cli.phar core download --allow-root --path=wordpress
|
||||||
|
# Generate `wp-config.php` file
|
||||||
|
- echo "define(\"WP_DEBUG\", true);" | ./wp-cli.phar core config --allow-root --dbname=wordpress --dbuser=ubuntu --dbhost=127.0.0.1:3306 --path=wordpress --extra-php
|
||||||
|
# Install WordPress
|
||||||
|
- ./wp-cli.phar core install --allow-root --admin_name=admin --admin_password=admin --admin_email=admin@mailpoet.loc --url=http://mailpoet.loc:8080 --title=WordPress --path=wordpress
|
||||||
|
# Softlink MailPoet to plugin path
|
||||||
|
- ln -s ../../.. wordpress/wp-content/plugins/mailpoet
|
||||||
|
# Activate MailPoet
|
||||||
|
- ./wp-cli.phar plugin activate mailpoet --path=wordpress
|
||||||
|
# Create .env file with correct path to WP installation
|
||||||
|
- echo "WP_TEST_PATH=\"/home/ubuntu/mailpoet/wordpress\"" > .env
|
||||||
|
|
||||||
|
# Enable XDebug for coverage reports.
|
||||||
|
# Comment out if not running PHP coverage reports, for performance
|
||||||
|
#- sed -i 's/^;//' /opt/circleci/php/$(phpenv global)/etc/conf.d/xdebug.ini
|
||||||
|
|
||||||
|
## tests override
|
||||||
|
test:
|
||||||
|
override:
|
||||||
|
# Run JS tests
|
||||||
|
- mkdir $CIRCLE_TEST_REPORTS/mocha
|
||||||
|
- ./do t:j $CIRCLE_TEST_REPORTS/mocha/junit.xml
|
||||||
|
|
||||||
|
# Run PHP tests
|
||||||
|
- ./do t:u --xml
|
||||||
|
# Uncomment to run coverage tests instead
|
||||||
|
#- ./do t:c --xml
|
||||||
|
# Copy the report
|
||||||
|
- mkdir $CIRCLE_TEST_REPORTS/codeception
|
||||||
|
- cp tests/_output/report.xml $CIRCLE_TEST_REPORTS/codeception/report.xml
|
||||||
|
# Uncomment to copy PHP coverage report
|
||||||
|
#- cp tests/_output/coverage.xml $CIRCLE_TEST_REPORTS/codeception/coverage.xml
|
@ -10,6 +10,7 @@ settings:
|
|||||||
colors: true
|
colors: true
|
||||||
memory_limit: 1024M
|
memory_limit: 1024M
|
||||||
log: true
|
log: true
|
||||||
|
strict_xml: true
|
||||||
extensions:
|
extensions:
|
||||||
enabled:
|
enabled:
|
||||||
- Codeception\Extension\RunFailed
|
- Codeception\Extension\RunFailed
|
||||||
|
264
composer.lock
generated
@ -407,12 +407,12 @@
|
|||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/mailpoet/html2text.git",
|
"url": "https://github.com/mailpoet/html2text.git",
|
||||||
"reference": "6e6c48d07a542f4b4ae24341cc6ab92335c32922"
|
"reference": "5ba872ab9a96c7b74fdaffbb42c78ee8dc12745a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/mailpoet/html2text/zipball/6e6c48d07a542f4b4ae24341cc6ab92335c32922",
|
"url": "https://api.github.com/repos/mailpoet/html2text/zipball/5ba872ab9a96c7b74fdaffbb42c78ee8dc12745a",
|
||||||
"reference": "6e6c48d07a542f4b4ae24341cc6ab92335c32922",
|
"reference": "5ba872ab9a96c7b74fdaffbb42c78ee8dc12745a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -452,7 +452,7 @@
|
|||||||
"email": "support@jevon.org",
|
"email": "support@jevon.org",
|
||||||
"source": "https://github.com/mailpoet/html2text/tree/master"
|
"source": "https://github.com/mailpoet/html2text/tree/master"
|
||||||
},
|
},
|
||||||
"time": "2016-06-13 18:24:35"
|
"time": "2016-07-28 01:09:53"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sunra/php-simple-html-dom-parser",
|
"name": "sunra/php-simple-html-dom-parser",
|
||||||
@ -499,23 +499,23 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "swiftmailer/swiftmailer",
|
"name": "swiftmailer/swiftmailer",
|
||||||
"version": "v5.4.2",
|
"version": "v5.4.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||||
"reference": "d8db871a54619458a805229a057ea2af33c753e8"
|
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8",
|
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
|
||||||
"reference": "d8db871a54619458a805229a057ea2af33c753e8",
|
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mockery/mockery": "~0.9.1,<0.9.4"
|
"mockery/mockery": "~0.9.1"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
@ -548,7 +548,7 @@
|
|||||||
"mail",
|
"mail",
|
||||||
"mailer"
|
"mailer"
|
||||||
],
|
],
|
||||||
"time": "2016-05-01 08:45:47"
|
"time": "2016-07-08 11:51:25"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
@ -611,16 +611,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/translation",
|
"name": "symfony/translation",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/translation.git",
|
"url": "https://github.com/symfony/translation.git",
|
||||||
"reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1"
|
"reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/translation/zipball/8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1",
|
"url": "https://api.github.com/repos/symfony/translation/zipball/00334ef0b9317e5d7c7641a2b56671a1df23b7a0",
|
||||||
"reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1",
|
"reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -671,7 +671,7 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Translation Component",
|
"description": "Symfony Translation Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:11:27"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "tburry/pquery",
|
"name": "tburry/pquery",
|
||||||
@ -848,16 +848,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/codeception",
|
"name": "codeception/codeception",
|
||||||
"version": "2.2.2",
|
"version": "2.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Codeception/Codeception.git",
|
"url": "https://github.com/Codeception/Codeception.git",
|
||||||
"reference": "8d80bb4ec7470e8df5de0e4c401785bc3fa1f4f6"
|
"reference": "34c268ae5872105c0c218296487650ab08e3991b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/8d80bb4ec7470e8df5de0e4c401785bc3fa1f4f6",
|
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/34c268ae5872105c0c218296487650ab08e3991b",
|
||||||
"reference": "8d80bb4ec7470e8df5de0e4c401785bc3fa1f4f6",
|
"reference": "34c268ae5872105c0c218296487650ab08e3991b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -935,20 +935,20 @@
|
|||||||
"functional testing",
|
"functional testing",
|
||||||
"unit testing"
|
"unit testing"
|
||||||
],
|
],
|
||||||
"time": "2016-06-29 00:59:28"
|
"time": "2016-07-24 19:31:22"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/verify",
|
"name": "codeception/verify",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Codeception/Verify.git",
|
"url": "https://github.com/Codeception/Verify.git",
|
||||||
"reference": "d3721cfc668d96b41acbda3ecd01d3499381db64"
|
"reference": "dc19c8722f3756341e5b0ce0590f09fda1d63719"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Codeception/Verify/zipball/d3721cfc668d96b41acbda3ecd01d3499381db64",
|
"url": "https://api.github.com/repos/Codeception/Verify/zipball/dc19c8722f3756341e5b0ce0590f09fda1d63719",
|
||||||
"reference": "d3721cfc668d96b41acbda3ecd01d3499381db64",
|
"reference": "dc19c8722f3756341e5b0ce0590f09fda1d63719",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@ -968,7 +968,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "BDD assertion library for PHPUnit",
|
"description": "BDD assertion library for PHPUnit",
|
||||||
"time": "2015-11-26 23:23:25"
|
"time": "2016-07-13 09:34:15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codegyre/robo",
|
"name": "codegyre/robo",
|
||||||
@ -1125,27 +1125,27 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "6.2.0",
|
"version": "6.2.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/guzzle.git",
|
"url": "https://github.com/guzzle/guzzle.git",
|
||||||
"reference": "d094e337976dff9d8e2424e8485872194e768662"
|
"reference": "3f808fba627f2c5b69e2501217bf31af349c1427"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662",
|
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427",
|
||||||
"reference": "d094e337976dff9d8e2424e8485872194e768662",
|
"reference": "3f808fba627f2c5b69e2501217bf31af349c1427",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/promises": "~1.0",
|
"guzzlehttp/promises": "^1.0",
|
||||||
"guzzlehttp/psr7": "~1.1",
|
"guzzlehttp/psr7": "^1.3.1",
|
||||||
"php": ">=5.5.0"
|
"php": ">=5.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"phpunit/phpunit": "~4.0",
|
"phpunit/phpunit": "^4.0",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "^1.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
@ -1183,7 +1183,7 @@
|
|||||||
"rest",
|
"rest",
|
||||||
"web service"
|
"web service"
|
||||||
],
|
],
|
||||||
"time": "2016-03-21 20:02:09"
|
"time": "2016-07-15 17:22:37"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/promises",
|
"name": "guzzlehttp/promises",
|
||||||
@ -1605,16 +1605,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||||
"reference": "900370c81280cc0d942ffbc5912d80464eaee7e9"
|
"reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/900370c81280cc0d942ffbc5912d80464eaee7e9",
|
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5f3f7e736d6319d5f1fc402aff8b026da26709a3",
|
||||||
"reference": "900370c81280cc0d942ffbc5912d80464eaee7e9",
|
"reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1623,7 +1623,7 @@
|
|||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
"phpunit/php-token-stream": "^1.4.2",
|
"phpunit/php-token-stream": "^1.4.2",
|
||||||
"sebastian/code-unit-reverse-lookup": "~1.0",
|
"sebastian/code-unit-reverse-lookup": "~1.0",
|
||||||
"sebastian/environment": "^1.3.2",
|
"sebastian/environment": "^1.3.2 || ^2.0",
|
||||||
"sebastian/version": "~1.0|~2.0"
|
"sebastian/version": "~1.0|~2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@ -1664,7 +1664,7 @@
|
|||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2016-06-03 05:03:56"
|
"time": "2016-07-26 14:39:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-file-iterator",
|
"name": "phpunit/php-file-iterator",
|
||||||
@ -1849,16 +1849,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "5.4.6",
|
"version": "5.4.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "2f1fc94b77ea6418bd6a06c64a1dac0645fbce59"
|
"reference": "3132365e1430c091f208e120b8845d39c25f20e6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2f1fc94b77ea6418bd6a06c64a1dac0645fbce59",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3132365e1430c091f208e120b8845d39c25f20e6",
|
||||||
"reference": "2f1fc94b77ea6418bd6a06c64a1dac0645fbce59",
|
"reference": "3132365e1430c091f208e120b8845d39c25f20e6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1870,7 +1870,7 @@
|
|||||||
"myclabs/deep-copy": "~1.3",
|
"myclabs/deep-copy": "~1.3",
|
||||||
"php": "^5.6 || ^7.0",
|
"php": "^5.6 || ^7.0",
|
||||||
"phpspec/prophecy": "^1.3.1",
|
"phpspec/prophecy": "^1.3.1",
|
||||||
"phpunit/php-code-coverage": "^4.0",
|
"phpunit/php-code-coverage": "^4.0.1",
|
||||||
"phpunit/php-file-iterator": "~1.4",
|
"phpunit/php-file-iterator": "~1.4",
|
||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
"phpunit/php-timer": "^1.0.6",
|
"phpunit/php-timer": "^1.0.6",
|
||||||
@ -1923,7 +1923,7 @@
|
|||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2016-06-16 06:01:15"
|
"time": "2016-07-26 14:48:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit-mock-objects",
|
"name": "phpunit/phpunit-mock-objects",
|
||||||
@ -2599,16 +2599,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "squizlabs/php_codesniffer",
|
"name": "squizlabs/php_codesniffer",
|
||||||
"version": "2.6.1",
|
"version": "2.6.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||||
"reference": "fb72ed32f8418db5e7770be1653e62e0d6f5dd3d"
|
"reference": "4edb770cb853def6e60c93abb088ad5ac2010c83"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/fb72ed32f8418db5e7770be1653e62e0d6f5dd3d",
|
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4edb770cb853def6e60c93abb088ad5ac2010c83",
|
||||||
"reference": "fb72ed32f8418db5e7770be1653e62e0d6f5dd3d",
|
"reference": "4edb770cb853def6e60c93abb088ad5ac2010c83",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2673,20 +2673,20 @@
|
|||||||
"phpcs",
|
"phpcs",
|
||||||
"standards"
|
"standards"
|
||||||
],
|
],
|
||||||
"time": "2016-05-30 22:24:32"
|
"time": "2016-07-13 23:29:13"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/browser-kit",
|
"name": "symfony/browser-kit",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/browser-kit.git",
|
"url": "https://github.com/symfony/browser-kit.git",
|
||||||
"reference": "b645a9b23d6c0eeba5ac823fa87bf010db9aff22"
|
"reference": "dcf41ed026b0499254385b5c88f03247b2ba010b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/b645a9b23d6c0eeba5ac823fa87bf010db9aff22",
|
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/dcf41ed026b0499254385b5c88f03247b2ba010b",
|
||||||
"reference": "b645a9b23d6c0eeba5ac823fa87bf010db9aff22",
|
"reference": "dcf41ed026b0499254385b5c88f03247b2ba010b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2730,20 +2730,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony BrowserKit Component",
|
"description": "Symfony BrowserKit Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-03-04 07:56:56"
|
"time": "2016-06-29 05:41:56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/config",
|
"name": "symfony/config",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/config.git",
|
"url": "https://github.com/symfony/config.git",
|
||||||
"reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05"
|
"reference": "0926e69411eba491803dbafb9f1f233e2ced58d0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/config/zipball/a2edd59c2163c65747fc3f35d132b5a39266bd05",
|
"url": "https://api.github.com/repos/symfony/config/zipball/0926e69411eba491803dbafb9f1f233e2ced58d0",
|
||||||
"reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05",
|
"reference": "0926e69411eba491803dbafb9f1f233e2ced58d0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2783,20 +2783,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Config Component",
|
"description": "Symfony Config Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:11:27"
|
"time": "2016-06-29 05:31:50"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "64a4d43b045f07055bb197650159769604cb2a92"
|
"reference": "747154aa69b0f83cd02fc9aa554836dee417631a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/64a4d43b045f07055bb197650159769604cb2a92",
|
"url": "https://api.github.com/repos/symfony/console/zipball/747154aa69b0f83cd02fc9aa554836dee417631a",
|
||||||
"reference": "64a4d43b045f07055bb197650159769604cb2a92",
|
"reference": "747154aa69b0f83cd02fc9aa554836dee417631a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2843,20 +2843,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Console Component",
|
"description": "Symfony Console Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-14 11:18:07"
|
"time": "2016-06-29 07:02:31"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/css-selector",
|
"name": "symfony/css-selector",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/css-selector.git",
|
"url": "https://github.com/symfony/css-selector.git",
|
||||||
"reference": "c526d7b3cb4fe1673c6a34e13be2ff63f519df99"
|
"reference": "2851e1932d77ce727776154d659b232d061e816a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/c526d7b3cb4fe1673c6a34e13be2ff63f519df99",
|
"url": "https://api.github.com/repos/symfony/css-selector/zipball/2851e1932d77ce727776154d659b232d061e816a",
|
||||||
"reference": "c526d7b3cb4fe1673c6a34e13be2ff63f519df99",
|
"reference": "2851e1932d77ce727776154d659b232d061e816a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2896,20 +2896,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony CssSelector Component",
|
"description": "Symfony CssSelector Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:42:41"
|
"time": "2016-06-29 05:41:56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dom-crawler",
|
"name": "symfony/dom-crawler",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dom-crawler.git",
|
"url": "https://github.com/symfony/dom-crawler.git",
|
||||||
"reference": "12aa63fd41b060d2bee9a34623d29eda70bc8fe3"
|
"reference": "99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/12aa63fd41b060d2bee9a34623d29eda70bc8fe3",
|
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0",
|
||||||
"reference": "12aa63fd41b060d2bee9a34623d29eda70bc8fe3",
|
"reference": "99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2952,20 +2952,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony DomCrawler Component",
|
"description": "Symfony DomCrawler Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-05-13 15:49:09"
|
"time": "2016-06-29 05:41:56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||||
"reference": "2a6b8713f8bdb582058cfda463527f195b066110"
|
"reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2a6b8713f8bdb582058cfda463527f195b066110",
|
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b180b70439dca70049b6b9b7e21d75e6e5d7aca9",
|
||||||
"reference": "2a6b8713f8bdb582058cfda463527f195b066110",
|
"reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3012,20 +3012,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony EventDispatcher Component",
|
"description": "Symfony EventDispatcher Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:11:27"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/filesystem",
|
"name": "symfony/filesystem",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/filesystem.git",
|
"url": "https://github.com/symfony/filesystem.git",
|
||||||
"reference": "dee379131dceed90a429e951546b33edfe7dccbb"
|
"reference": "7258ddd6f987053f21fa43d03430580ba54e6096"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb",
|
"url": "https://api.github.com/repos/symfony/filesystem/zipball/7258ddd6f987053f21fa43d03430580ba54e6096",
|
||||||
"reference": "dee379131dceed90a429e951546b33edfe7dccbb",
|
"reference": "7258ddd6f987053f21fa43d03430580ba54e6096",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3061,20 +3061,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Filesystem Component",
|
"description": "Symfony Filesystem Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-04-12 18:01:21"
|
"time": "2016-06-29 05:31:50"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/finder.git",
|
"url": "https://github.com/symfony/finder.git",
|
||||||
"reference": "40d17ed287bf51a2f884c4619ce8ff2a1c5cd219"
|
"reference": "8201978de88a9fa0923e18601bb17f1df9c721e7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/finder/zipball/40d17ed287bf51a2f884c4619ce8ff2a1c5cd219",
|
"url": "https://api.github.com/repos/symfony/finder/zipball/8201978de88a9fa0923e18601bb17f1df9c721e7",
|
||||||
"reference": "40d17ed287bf51a2f884c4619ce8ff2a1c5cd219",
|
"reference": "8201978de88a9fa0923e18601bb17f1df9c721e7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3110,20 +3110,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Finder Component",
|
"description": "Symfony Finder Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-05-13 18:06:41"
|
"time": "2016-06-29 05:41:56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/form",
|
"name": "symfony/form",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/form.git",
|
"url": "https://github.com/symfony/form.git",
|
||||||
"reference": "edfb109ac1ebb755ad0ce964f32e43ddbddae7bb"
|
"reference": "fd24c42112a3c434a083c498b9550331bb96eaa3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/form/zipball/edfb109ac1ebb755ad0ce964f32e43ddbddae7bb",
|
"url": "https://api.github.com/repos/symfony/form/zipball/fd24c42112a3c434a083c498b9550331bb96eaa3",
|
||||||
"reference": "edfb109ac1ebb755ad0ce964f32e43ddbddae7bb",
|
"reference": "fd24c42112a3c434a083c498b9550331bb96eaa3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3184,20 +3184,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Form Component",
|
"description": "Symfony Form Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:11:27"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/intl",
|
"name": "symfony/intl",
|
||||||
"version": "v3.0.7",
|
"version": "v3.0.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/intl.git",
|
"url": "https://github.com/symfony/intl.git",
|
||||||
"reference": "96ce72abb3538c4256585ce278cf30ceb1e86f16"
|
"reference": "330c95b92989c1a515794bb87aabfe7492148f61"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/intl/zipball/96ce72abb3538c4256585ce278cf30ceb1e86f16",
|
"url": "https://api.github.com/repos/symfony/intl/zipball/330c95b92989c1a515794bb87aabfe7492148f61",
|
||||||
"reference": "96ce72abb3538c4256585ce278cf30ceb1e86f16",
|
"reference": "330c95b92989c1a515794bb87aabfe7492148f61",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3259,20 +3259,20 @@
|
|||||||
"l10n",
|
"l10n",
|
||||||
"localization"
|
"localization"
|
||||||
],
|
],
|
||||||
"time": "2016-05-13 18:03:36"
|
"time": "2016-06-29 05:40:45"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/options-resolver",
|
"name": "symfony/options-resolver",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/options-resolver.git",
|
"url": "https://github.com/symfony/options-resolver.git",
|
||||||
"reference": "ddad0be20d6f2cb266cded8c349e046731df09b8"
|
"reference": "b6f982782a0624d37b5416c2c96fb99ce5ab74d5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/ddad0be20d6f2cb266cded8c349e046731df09b8",
|
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/b6f982782a0624d37b5416c2c96fb99ce5ab74d5",
|
||||||
"reference": "ddad0be20d6f2cb266cded8c349e046731df09b8",
|
"reference": "b6f982782a0624d37b5416c2c96fb99ce5ab74d5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3313,7 +3313,7 @@
|
|||||||
"configuration",
|
"configuration",
|
||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"time": "2016-05-24 10:00:02"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-icu",
|
"name": "symfony/polyfill-intl-icu",
|
||||||
@ -3375,16 +3375,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "6350e63ed9c232da50e00f00a7e0330f066387a2"
|
"reference": "5c11a1a4d4016662eeaf0f8757958c7de069f9a0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/6350e63ed9c232da50e00f00a7e0330f066387a2",
|
"url": "https://api.github.com/repos/symfony/process/zipball/5c11a1a4d4016662eeaf0f8757958c7de069f9a0",
|
||||||
"reference": "6350e63ed9c232da50e00f00a7e0330f066387a2",
|
"reference": "5c11a1a4d4016662eeaf0f8757958c7de069f9a0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3420,20 +3420,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Process Component",
|
"description": "Symfony Process Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:42:41"
|
"time": "2016-06-29 05:42:25"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/property-access",
|
"name": "symfony/property-access",
|
||||||
"version": "v3.0.7",
|
"version": "v3.0.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/property-access.git",
|
"url": "https://github.com/symfony/property-access.git",
|
||||||
"reference": "6a958de831366005603432ef438c22cd93fad1ef"
|
"reference": "dedc1109b7c4f0454dffb00b7caa449a39a3c5dd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/property-access/zipball/6a958de831366005603432ef438c22cd93fad1ef",
|
"url": "https://api.github.com/repos/symfony/property-access/zipball/dedc1109b7c4f0454dffb00b7caa449a39a3c5dd",
|
||||||
"reference": "6a958de831366005603432ef438c22cd93fad1ef",
|
"reference": "dedc1109b7c4f0454dffb00b7caa449a39a3c5dd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3480,20 +3480,20 @@
|
|||||||
"property path",
|
"property path",
|
||||||
"reflection"
|
"reflection"
|
||||||
],
|
],
|
||||||
"time": "2016-05-29 09:50:11"
|
"time": "2016-06-29 05:40:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/routing",
|
"name": "symfony/routing",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/routing.git",
|
"url": "https://github.com/symfony/routing.git",
|
||||||
"reference": "4cbc81aa378869445fbd2d18c8c8b4a056c632a0"
|
"reference": "cdd298b1d45b9882de0905856e89171bf487c6d5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/routing/zipball/4cbc81aa378869445fbd2d18c8c8b4a056c632a0",
|
"url": "https://api.github.com/repos/symfony/routing/zipball/cdd298b1d45b9882de0905856e89171bf487c6d5",
|
||||||
"reference": "4cbc81aa378869445fbd2d18c8c8b4a056c632a0",
|
"reference": "cdd298b1d45b9882de0905856e89171bf487c6d5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3555,20 +3555,20 @@
|
|||||||
"uri",
|
"uri",
|
||||||
"url"
|
"url"
|
||||||
],
|
],
|
||||||
"time": "2016-05-30 06:57:11"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/twig-bridge",
|
"name": "symfony/twig-bridge",
|
||||||
"version": "v2.8.7",
|
"version": "v2.8.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/twig-bridge.git",
|
"url": "https://github.com/symfony/twig-bridge.git",
|
||||||
"reference": "360f3330e1df67edde1bb5d72fe5aa7c1bc74b9d"
|
"reference": "b2db0187b7b805bb349ffe2714fbc846124c71ba"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/twig-bridge/zipball/360f3330e1df67edde1bb5d72fe5aa7c1bc74b9d",
|
"url": "https://api.github.com/repos/symfony/twig-bridge/zipball/b2db0187b7b805bb349ffe2714fbc846124c71ba",
|
||||||
"reference": "360f3330e1df67edde1bb5d72fe5aa7c1bc74b9d",
|
"reference": "b2db0187b7b805bb349ffe2714fbc846124c71ba",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3636,20 +3636,20 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Twig Bridge",
|
"description": "Symfony Twig Bridge",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-06 11:11:27"
|
"time": "2016-06-29 05:29:29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/yaml",
|
||||||
"version": "v3.1.1",
|
"version": "v3.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
"reference": "c5a7e7fc273c758b92b85dcb9c46149ccda89623"
|
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/c5a7e7fc273c758b92b85dcb9c46149ccda89623",
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
|
||||||
"reference": "c5a7e7fc273c758b92b85dcb9c46149ccda89623",
|
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -3685,7 +3685,7 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Yaml Component",
|
"description": "Symfony Yaml Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-14 11:18:07"
|
"time": "2016-06-29 05:41:56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "twig/extensions",
|
"name": "twig/extensions",
|
||||||
|
@ -1,199 +0,0 @@
|
|||||||
# Copyright (C) 2015
|
|
||||||
# This file is distributed under the same license as the package.
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: \n"
|
|
||||||
"Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
|
|
||||||
"POT-Creation-Date: 2015-07-29 16:59:53+00:00\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"PO-Revision-Date: 2015-07-29 19:00+0100\n"
|
|
||||||
"Last-Translator: MailPoet i18n (https://www.transifex.com/organization/wysija)\n"
|
|
||||||
"Language-Team: MailPoet i18n <https://www.transifex.com/organization/wysija>\n"
|
|
||||||
"X-Generator: Poedit 1.7.4\n"
|
|
||||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"X-Poedit-SourceCharset: UTF-8\n"
|
|
||||||
"X-Poedit-Basepath: ../\n"
|
|
||||||
"X-Textdomain-Support: yes\n"
|
|
||||||
"Language: en\n"
|
|
||||||
"X-Poedit-SearchPath-0: .\n"
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:91
|
|
||||||
msgid "Year, month, day"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:92
|
|
||||||
msgid "Year, month"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:93
|
|
||||||
msgid "Month (January, February,...)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:94 lib/form/renderer.php:519
|
|
||||||
msgid "Year"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:108
|
|
||||||
msgid "January"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:109
|
|
||||||
msgid "February"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:110
|
|
||||||
msgid "March"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:111
|
|
||||||
msgid "April"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:112
|
|
||||||
msgid "May"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:113
|
|
||||||
msgid "June"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:114
|
|
||||||
msgid "July"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:115
|
|
||||||
msgid "August"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:116
|
|
||||||
msgid "September"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:117
|
|
||||||
msgid "October"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:118
|
|
||||||
msgid "November"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:119
|
|
||||||
msgid "December"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:509
|
|
||||||
msgid "Day"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:514
|
|
||||||
msgid "Month"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:11
|
|
||||||
msgid "MailPoet Subscription Form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:13
|
|
||||||
msgid "Newsletter subscription form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:36
|
|
||||||
msgid "Subscribe to our Newsletter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:56
|
|
||||||
msgid "Title:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:76
|
|
||||||
msgid "Create a new form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:109
|
|
||||||
msgid "Newsletter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:4 views/form/editor.html:26
|
|
||||||
msgid "Save"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:5
|
|
||||||
msgid "Translatable string with a link %shere%s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:6
|
|
||||||
msgid "deleted one message"
|
|
||||||
msgid_plural "deleted %d messages"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:34
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:42
|
|
||||||
msgid "This form adds subscribers to these lists:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:44
|
|
||||||
msgid "Choose a list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:57
|
|
||||||
msgid "You have to select at least 1 list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:63
|
|
||||||
msgid "After submit..."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:65
|
|
||||||
msgid "Show message"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:69
|
|
||||||
msgid "Go to page"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:76
|
|
||||||
msgid "Check your inbox now to confirm your subscription."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:98
|
|
||||||
msgid "Shortcodes"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:103
|
|
||||||
msgid "You can easily add this form to your theme's in the"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:103
|
|
||||||
msgid "Widgets areas"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:126
|
|
||||||
msgid "[link_html]HTML[/link_html]"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:138
|
|
||||||
msgid "Fields"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:144
|
|
||||||
msgid "Add New Field"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:153
|
|
||||||
msgid "Styles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:157
|
|
||||||
msgid "Preview"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/index.html:4
|
|
||||||
msgid "monvier"
|
|
||||||
msgstr ""
|
|
@ -1,215 +0,0 @@
|
|||||||
# Copyright (C) 2015
|
|
||||||
# This file is distributed under the same license as the package.
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: \n"
|
|
||||||
"Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
|
|
||||||
"POT-Creation-Date: 2015-07-30 14:08:29+00:00\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"PO-Revision-Date: 2015-07-30 16:19+0100\n"
|
|
||||||
"Last-Translator: MailPoet i18n (https://www.transifex.com/organization/wysija)\n"
|
|
||||||
"Language-Team: MailPoet i18n <https://www.transifex.com/organization/wysija>\n"
|
|
||||||
"X-Generator: Poedit 1.7.4\n"
|
|
||||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
|
||||||
"X-Poedit-SourceCharset: UTF-8\n"
|
|
||||||
"X-Poedit-Basepath: ../\n"
|
|
||||||
"X-Textdomain-Support: yes\n"
|
|
||||||
"Language: fr\n"
|
|
||||||
"X-Poedit-SearchPath-0: .\n"
|
|
||||||
|
|
||||||
#: lib/config/initializer.php:259
|
|
||||||
msgid "New form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/config/initializer.php:264
|
|
||||||
msgid "Check your inbox or spam folder now to confirm your subscription."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/config/initializer.php:270 lib/config/initializer.php:275
|
|
||||||
msgid "Email"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/config/initializer.php:280
|
|
||||||
msgid "Submit"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/config/initializer.php:285
|
|
||||||
msgid "Subscribe!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:91
|
|
||||||
msgid "Year, month, day"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:92
|
|
||||||
msgid "Year, month"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:93
|
|
||||||
msgid "Month (January, February,...)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:94 lib/form/renderer.php:519
|
|
||||||
msgid "Year"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:108
|
|
||||||
msgid "January"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:109
|
|
||||||
msgid "February"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:110
|
|
||||||
msgid "March"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:111
|
|
||||||
msgid "April"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:112
|
|
||||||
msgid "May"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:113
|
|
||||||
msgid "June"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:114
|
|
||||||
msgid "July"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:115
|
|
||||||
msgid "August"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:116
|
|
||||||
msgid "September"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:117
|
|
||||||
msgid "October"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:118
|
|
||||||
msgid "November"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:119
|
|
||||||
msgid "December"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:509
|
|
||||||
msgid "Day"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/renderer.php:514
|
|
||||||
msgid "Month"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:11
|
|
||||||
msgid "MailPoet Subscription Form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:13
|
|
||||||
msgid "Newsletter subscription form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:36
|
|
||||||
msgid "Subscribe to our Newsletter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:56
|
|
||||||
msgid "Title:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:76
|
|
||||||
msgid "Create a new form"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/form/widget.php:109
|
|
||||||
msgid "Newsletter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:8
|
|
||||||
msgid "Edit name' "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:23
|
|
||||||
msgid "Save"
|
|
||||||
msgstr "Sauvegarder"
|
|
||||||
|
|
||||||
#: views/form/editor.html:31
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr "Réglages"
|
|
||||||
|
|
||||||
#: views/form/editor.html:39
|
|
||||||
msgid "This form adds subscribers to these lists:"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:41
|
|
||||||
msgid "Choose a list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:46
|
|
||||||
msgid "You have to select at least 1 list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:52
|
|
||||||
msgid "After submit..."
|
|
||||||
msgstr "Après l'inscription"
|
|
||||||
|
|
||||||
#: views/form/editor.html:54
|
|
||||||
msgid "Show message"
|
|
||||||
msgstr "Afficher le message"
|
|
||||||
|
|
||||||
#: views/form/editor.html:58
|
|
||||||
msgid "Go to page"
|
|
||||||
msgstr "Aller à la page"
|
|
||||||
|
|
||||||
#: views/form/editor.html:65
|
|
||||||
msgid "Check your inbox now to confirm your subscription."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:85
|
|
||||||
msgid "Shortcodes"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:90
|
|
||||||
msgid "You can easily add this form to your theme's in the %sWidgets area%s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:96
|
|
||||||
msgid "%sHTML%s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:119
|
|
||||||
msgid "Fields"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:125
|
|
||||||
msgid "Add New Field"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:134
|
|
||||||
msgid "Styles"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/form/editor.html:138
|
|
||||||
msgid "Preview"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/index.html:5
|
|
||||||
msgid "Translatable string with a link %shere%s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: views/index.html:6 views/index.html:7
|
|
||||||
msgid "deleted one message"
|
|
||||||
msgid_plural "deleted %d messages"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
183
lib/API/API.php
@ -1,83 +1,132 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\API;
|
namespace MailPoet\API;
|
||||||
|
|
||||||
use MailPoet\Util\Helpers;
|
use \MailPoet\Util\Security;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class API {
|
class API {
|
||||||
public $api_request;
|
function __construct() {
|
||||||
public $endpoint;
|
|
||||||
public $action;
|
|
||||||
public $data;
|
|
||||||
const NAME = 'mailpoet_api';
|
|
||||||
const ENDPOINT_NAMESPACE = '\MailPoet\API\Endpoints\\';
|
|
||||||
const RESPONSE_ERROR = 404;
|
|
||||||
|
|
||||||
function __construct($api_data = false) {
|
|
||||||
$api_data = ($api_data) ? $api_data : $_GET;
|
|
||||||
$this->api_request = isset($api_data[self::NAME]);
|
|
||||||
$this->endpoint = isset($api_data['endpoint']) ?
|
|
||||||
Helpers::underscoreToCamelCase($api_data['endpoint']) :
|
|
||||||
false;
|
|
||||||
$this->action = isset($api_data['action']) ?
|
|
||||||
Helpers::underscoreToCamelCase($api_data['action']) :
|
|
||||||
false;
|
|
||||||
$this->data = isset($api_data['data']) ?
|
|
||||||
self::decodeRequestData($api_data['data']) :
|
|
||||||
false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$endpoint = self::ENDPOINT_NAMESPACE . ucfirst($this->endpoint);
|
// security token
|
||||||
if(!$this->api_request) return;
|
add_action(
|
||||||
if(!$this->endpoint || !class_exists($endpoint)) {
|
'admin_head',
|
||||||
$this->terminateRequest(self::RESPONSE_ERROR, __('Invalid API endpoint.'));
|
array($this, 'setToken')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Admin API (Ajax only)
|
||||||
|
add_action(
|
||||||
|
'wp_ajax_mailpoet',
|
||||||
|
array($this, 'setupAdmin')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Public API (Ajax)
|
||||||
|
add_action(
|
||||||
|
'wp_ajax_nopriv_mailpoet',
|
||||||
|
array($this, 'setupPublic')
|
||||||
|
);
|
||||||
|
// Public API (Post)
|
||||||
|
add_action(
|
||||||
|
'admin_post_nopriv_mailpoet',
|
||||||
|
array($this, 'setupPublic')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupAdmin() {
|
||||||
|
if($this->checkToken() === false) {
|
||||||
|
$error_response = new ErrorResponse(
|
||||||
|
array(
|
||||||
|
Error::UNAUTHORIZED => __('You need to specify a valid API token.')
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
Response::STATUS_UNAUTHORIZED
|
||||||
|
);
|
||||||
|
$error_response->send();
|
||||||
}
|
}
|
||||||
$this->callEndpoint(
|
|
||||||
$endpoint,
|
|
||||||
$this->action,
|
|
||||||
$this->data
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function callEndpoint($endpoint, $action, $data) {
|
if($this->checkPermissions() === false) {
|
||||||
if(!method_exists($endpoint, $action)) {
|
$error_response = new ErrorResponse(
|
||||||
$this->terminateRequest(self::RESPONSE_ERROR, __('Invalid API action.'));
|
array(
|
||||||
|
Error::FORBIDDEN => __('You do not have the required permissions.')
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
Response::STATUS_FORBIDDEN
|
||||||
|
);
|
||||||
|
$error_response->send();
|
||||||
}
|
}
|
||||||
call_user_func(
|
|
||||||
array(
|
$this->processRoute();
|
||||||
$endpoint,
|
}
|
||||||
$action
|
|
||||||
),
|
function setupPublic() {
|
||||||
$data
|
if($this->checkToken() === false) {
|
||||||
|
$error_response = new ErrorResponse(
|
||||||
|
array(
|
||||||
|
Error::UNAUTHORIZED => __('You need to specify a valid API token.')
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
Response::STATUS_UNAUTHORIZED
|
||||||
|
);
|
||||||
|
$error_response->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->processRoute();
|
||||||
|
}
|
||||||
|
|
||||||
|
function processRoute() {
|
||||||
|
$class = ucfirst($_POST['endpoint']);
|
||||||
|
$endpoint = __NAMESPACE__ . "\\Endpoints\\" . $class;
|
||||||
|
$method = $_POST['method'];
|
||||||
|
|
||||||
|
$doing_ajax = (bool)(defined('DOING_AJAX') && DOING_AJAX);
|
||||||
|
|
||||||
|
if($doing_ajax) {
|
||||||
|
$data = isset($_POST['data']) ? stripslashes_deep($_POST['data']) : array();
|
||||||
|
} else {
|
||||||
|
$data = $_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_array($data) && !empty($data)) {
|
||||||
|
// filter out reserved keywords from data
|
||||||
|
$reserved_keywords = array(
|
||||||
|
'token',
|
||||||
|
'endpoint',
|
||||||
|
'method',
|
||||||
|
'mailpoet_redirect'
|
||||||
|
);
|
||||||
|
$data = array_diff_key($data, array_flip($reserved_keywords));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$endpoint = new $endpoint();
|
||||||
|
$response = $endpoint->$method($data);
|
||||||
|
$response->send();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$error_response = new ErrorResponse(
|
||||||
|
array($e->getCode() => $e->getMessage())
|
||||||
|
);
|
||||||
|
$error_response->send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setToken() {
|
||||||
|
$global = '<script type="text/javascript">';
|
||||||
|
$global .= 'var mailpoet_token = "'.Security::generateToken().'";';
|
||||||
|
$global .= '</script>';
|
||||||
|
echo $global;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPermissions() {
|
||||||
|
return current_user_can('manage_options');
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkToken() {
|
||||||
|
return (
|
||||||
|
isset($_POST['token'])
|
||||||
|
&&
|
||||||
|
wp_verify_nonce($_POST['token'], 'mailpoet_token')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function decodeRequestData($data) {
|
|
||||||
$data = base64_decode($data);
|
|
||||||
return (is_serialized($data)) ?
|
|
||||||
unserialize($data) :
|
|
||||||
self::terminateRequest(self::RESPONSE_ERROR, __('Invalid API data format.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
static function encodeRequestData($data) {
|
|
||||||
return rtrim(base64_encode(serialize($data)), '=');
|
|
||||||
}
|
|
||||||
|
|
||||||
static function buildRequest($endpoint, $action, $data) {
|
|
||||||
$data = self::encodeRequestData($data);
|
|
||||||
$params = array(
|
|
||||||
self::NAME => '',
|
|
||||||
'endpoint' => $endpoint,
|
|
||||||
'action' => $action,
|
|
||||||
'data' => $data
|
|
||||||
);
|
|
||||||
return add_query_arg($params, home_url());
|
|
||||||
}
|
|
||||||
|
|
||||||
function terminateRequest($code, $message) {
|
|
||||||
status_header($code, $message);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
33
lib/API/Endpoint.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
abstract class Endpoint {
|
||||||
|
|
||||||
|
function successResponse(
|
||||||
|
$data = array(), $meta = array(), $status = Response::STATUS_OK
|
||||||
|
) {
|
||||||
|
return new SuccessResponse($data, $meta, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorResponse(
|
||||||
|
$errors = array(), $meta = array(), $status = Response::STATUS_NOT_FOUND
|
||||||
|
) {
|
||||||
|
if(empty($errors)) {
|
||||||
|
$errors = array(
|
||||||
|
Error::UNKNOWN => __('An unknown error occurred.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new ErrorResponse($errors, $meta, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function badRequest($errors = array(), $meta = array()) {
|
||||||
|
if(empty($errors)) {
|
||||||
|
$errors = array(
|
||||||
|
Error::BAD_REQUEST => __('Invalid request parameters.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new ErrorResponse($errors, $meta, Response::STATUS_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
77
lib/API/Endpoints/AutomatedLatestContent.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class AutomatedLatestContent extends APIEndpoint {
|
||||||
|
public $ALC;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
$this->ALC = new \MailPoet\Newsletter\AutomatedLatestContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPostTypes() {
|
||||||
|
return $this->successResponse(
|
||||||
|
get_post_types(array(), 'objects')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTaxonomies($data = array()) {
|
||||||
|
$post_type = (isset($data['postType'])) ? $data['postType'] : 'post';
|
||||||
|
return $this->successResponse(
|
||||||
|
get_object_taxonomies($post_type, 'objects')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTerms($data = array()) {
|
||||||
|
$taxonomies = (isset($data['taxonomies'])) ? $data['taxonomies'] : array();
|
||||||
|
$search = (isset($data['search'])) ? $data['search'] : '';
|
||||||
|
$limit = (isset($data['limit'])) ? (int)$data['limit'] : 10;
|
||||||
|
$page = (isset($data['page'])) ? (int)$data['page'] : 1;
|
||||||
|
|
||||||
|
return $this->successResponse(
|
||||||
|
get_terms(
|
||||||
|
$taxonomies,
|
||||||
|
array(
|
||||||
|
'hide_empty' => false,
|
||||||
|
'search' => $search,
|
||||||
|
'number' => $limit,
|
||||||
|
'offset' => $limit * ($page - 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosts($data = array()) {
|
||||||
|
return $this->successResponse(
|
||||||
|
$this->ALC->getPosts($data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTransformedPosts($data = array()) {
|
||||||
|
$posts = $this->ALC->getPosts($data);
|
||||||
|
return $this->successResponse(
|
||||||
|
$this->ALC->transformPosts($data, $posts)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBulkTransformedPosts($data = array()) {
|
||||||
|
$alc = new \MailPoet\Newsletter\AutomatedLatestContent();
|
||||||
|
|
||||||
|
$used_posts = array();
|
||||||
|
$rendered_posts = array();
|
||||||
|
|
||||||
|
foreach($data['blocks'] as $block) {
|
||||||
|
$posts = $alc->getPosts($block, $used_posts);
|
||||||
|
$rendered_posts[] = $alc->transformPosts($block, $posts);
|
||||||
|
|
||||||
|
foreach($posts as $post) {
|
||||||
|
$used_posts[] = $post->ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse($rendered_posts);
|
||||||
|
}
|
||||||
|
}
|
57
lib/API/Endpoints/CustomFields.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
use \MailPoet\Models\CustomField;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class CustomFields extends APIEndpoint {
|
||||||
|
function getAll() {
|
||||||
|
$collection = CustomField::findMany();
|
||||||
|
$custom_fields = array_map(function($custom_field) {
|
||||||
|
return $custom_field->asArray();
|
||||||
|
}, $collection);
|
||||||
|
|
||||||
|
return $this->successResponse($custom_fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : null);
|
||||||
|
$custom_field = CustomField::findOne($id);
|
||||||
|
if($custom_field === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This custom field does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$custom_field->delete();
|
||||||
|
|
||||||
|
return $this->successResponse($custom_field->asArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($data = array()) {
|
||||||
|
$custom_field = CustomField::createOrUpdate($data);
|
||||||
|
$errors = $custom_field->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
CustomField::findOne($custom_field->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : null);
|
||||||
|
$custom_field = CustomField::findOne($id);
|
||||||
|
if($custom_field === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This custom field does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse($custom_field->asArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
289
lib/API/Endpoints/Forms.php
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
use \MailPoet\Models\Form;
|
||||||
|
use \MailPoet\Models\StatisticsForms;
|
||||||
|
use \MailPoet\Form\Renderer as FormRenderer;
|
||||||
|
use \MailPoet\Listing;
|
||||||
|
use \MailPoet\Form\Util;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Forms extends APIEndpoint {
|
||||||
|
function get($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse($form->asArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listing($data = array()) {
|
||||||
|
$listing = new Listing\Handler(
|
||||||
|
'\MailPoet\Models\Form',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
$listing_data = $listing->get();
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach($listing_data['items'] as $form) {
|
||||||
|
$form = $form->asArray();
|
||||||
|
|
||||||
|
$form['signups'] = StatisticsForms::getTotalSignups($form['id']);
|
||||||
|
|
||||||
|
$form['segments'] = (
|
||||||
|
!empty($form['settings']['segments'])
|
||||||
|
? $form['settings']['segments']
|
||||||
|
: array()
|
||||||
|
);
|
||||||
|
|
||||||
|
$data[] = $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse($data, array(
|
||||||
|
'count' => $listing_data['count'],
|
||||||
|
'filters' => $listing_data['filters'],
|
||||||
|
'groups' => $listing_data['groups']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function create() {
|
||||||
|
// create new form
|
||||||
|
$form_data = array(
|
||||||
|
'name' => __('New form'),
|
||||||
|
'body' => array(
|
||||||
|
array(
|
||||||
|
'id' => 'email',
|
||||||
|
'name' => __('Email'),
|
||||||
|
'type' => 'text',
|
||||||
|
'static' => true,
|
||||||
|
'params' => array(
|
||||||
|
'label' => __('Email'),
|
||||||
|
'required' => true
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'id' => 'submit',
|
||||||
|
'name' => __('Submit'),
|
||||||
|
'type' => 'submit',
|
||||||
|
'static' => true,
|
||||||
|
'params' => array(
|
||||||
|
'label' => __('Subscribe!')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'settings' => array(
|
||||||
|
'on_success' => 'message',
|
||||||
|
'success_message' => __('Check your inbox or spam folder to confirm your subscription.'),
|
||||||
|
'segments' => null,
|
||||||
|
'segments_selected_by' => 'admin'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->save($form_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($data = array()) {
|
||||||
|
$form = Form::createOrUpdate($data);
|
||||||
|
$errors = $form->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Form::findOne($form->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function previewEditor($data = array()) {
|
||||||
|
// html
|
||||||
|
$html = FormRenderer::renderHTML($data);
|
||||||
|
|
||||||
|
// convert shortcodes
|
||||||
|
$html = do_shortcode($html);
|
||||||
|
|
||||||
|
// styles
|
||||||
|
$css = new Util\Styles(FormRenderer::getStyles($data));
|
||||||
|
|
||||||
|
return $this->successResponse(array(
|
||||||
|
'html' => $html,
|
||||||
|
'css' => $css->render()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportsEditor($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$exports = Util\Export::getAll($form->asArray());
|
||||||
|
return $this->successResponse($exports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveEditor($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
|
||||||
|
$form_id = (isset($data['id']) ? (int)$data['id'] : 0);
|
||||||
|
$name = (isset($data['name']) ? $data['name'] : __('New form'));
|
||||||
|
$body = (isset($data['body']) ? $data['body'] : array());
|
||||||
|
$settings = (isset($data['settings']) ? $data['settings'] : array());
|
||||||
|
$styles = (isset($data['styles']) ? $data['styles'] : '');
|
||||||
|
|
||||||
|
// check if the form is used as a widget
|
||||||
|
$is_widget = false;
|
||||||
|
$widgets = get_option('widget_mailpoet_form');
|
||||||
|
if(!empty($widgets)) {
|
||||||
|
foreach($widgets as $widget) {
|
||||||
|
if(isset($widget['form']) && (int)$widget['form'] === $form_id) {
|
||||||
|
$is_widget = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the user gets to pick his own lists
|
||||||
|
// or if it's selected by the admin
|
||||||
|
$has_segment_selection = false;
|
||||||
|
|
||||||
|
foreach($body as $i => $block) {
|
||||||
|
if($block['type'] === 'segment') {
|
||||||
|
$has_segment_selection = true;
|
||||||
|
if(!empty($block['params']['values'])) {
|
||||||
|
$list_selection = array_filter(
|
||||||
|
array_map(function($segment) {
|
||||||
|
return (isset($segment['id'])
|
||||||
|
? (int)$segment['id']
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}, $block['params']['values'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check list selection
|
||||||
|
if($has_segment_selection === true) {
|
||||||
|
$settings['segments_selected_by'] = 'user';
|
||||||
|
} else {
|
||||||
|
$settings['segments_selected_by'] = 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = Form::createOrUpdate(array(
|
||||||
|
'id' => $form_id,
|
||||||
|
'name' => $name,
|
||||||
|
'body' => $body,
|
||||||
|
'settings' => $settings,
|
||||||
|
'styles' => $styles
|
||||||
|
));
|
||||||
|
|
||||||
|
$errors = $form->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Form::findOne($form->id)->asArray(),
|
||||||
|
array('is_widget' => $is_widget)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restore($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$form->restore();
|
||||||
|
return $this->successResponse(
|
||||||
|
Form::findOne($form->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function trash($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$form->trash();
|
||||||
|
return $this->successResponse(
|
||||||
|
Form::findOne($form->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$form->delete();
|
||||||
|
return $this->successResponse(null, array('count' => 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function duplicate($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$form = Form::findOne($id);
|
||||||
|
|
||||||
|
if($form === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This form does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$data = array(
|
||||||
|
'name' => sprintf(__('Copy of %s'), $form->name)
|
||||||
|
);
|
||||||
|
$duplicate = $form->duplicate($data);
|
||||||
|
$errors = $duplicate->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Form::findOne($duplicate->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bulkAction($data = array()) {
|
||||||
|
try {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Form',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
$meta = $bulk_action->apply();
|
||||||
|
return $this->successResponse(null, $meta);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
77
lib/API/Endpoints/ImportExport.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
use MailPoet\Subscribers\ImportExport\Import\MailChimp;
|
||||||
|
use MailPoet\Models\CustomField;
|
||||||
|
use MailPoet\Models\Segment;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class ImportExport extends APIEndpoint {
|
||||||
|
function getMailChimpLists($data) {
|
||||||
|
try {
|
||||||
|
$mailChimp = new MailChimp($data['api_key']);
|
||||||
|
$lists = $mailChimp->getLists();
|
||||||
|
return $this->successResponse($lists);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMailChimpSubscribers($data) {
|
||||||
|
try {
|
||||||
|
$mailChimp = new MailChimp($data['api_key']);
|
||||||
|
$subscribers = $mailChimp->getSubscribers($data['lists']);
|
||||||
|
return $this->successResponse($subscribers);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSegment($data) {
|
||||||
|
$segment = Segment::createOrUpdate($data);
|
||||||
|
$errors = $segment->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Segment::findOne($segment->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processImport($data) {
|
||||||
|
try {
|
||||||
|
$import = new \MailPoet\Subscribers\ImportExport\Import\Import(
|
||||||
|
json_decode($data, true)
|
||||||
|
);
|
||||||
|
$process = $import->process();
|
||||||
|
return $this->successResponse($process);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processExport($data) {
|
||||||
|
try {
|
||||||
|
$export = new \MailPoet\Subscribers\ImportExport\Export\Export(
|
||||||
|
json_decode($data, true)
|
||||||
|
);
|
||||||
|
$process = $export->process();
|
||||||
|
return $this->successResponse($process);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
lib/API/Endpoints/Mailer.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Mailer extends APIEndpoint {
|
||||||
|
function send($data = array()) {
|
||||||
|
try {
|
||||||
|
$mailer = new \MailPoet\Mailer\Mailer(
|
||||||
|
(isset($data['mailer'])) ? $data['mailer'] : false,
|
||||||
|
(isset($data['sender'])) ? $data['sender'] : false,
|
||||||
|
(isset($data['reply_to'])) ? $data['reply_to'] : false
|
||||||
|
);
|
||||||
|
$result = $mailer->send($data['newsletter'], $data['subscriber']);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::BAD_REQUEST => __("The email could not be sent. Please check your settings.")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
lib/API/Endpoints/NewsletterTemplates.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
use MailPoet\Models\NewsletterTemplate;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class NewsletterTemplates extends APIEndpoint {
|
||||||
|
function get($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$template = NewsletterTemplate::findOne($id);
|
||||||
|
if($template === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This template does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
$template->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$collection = NewsletterTemplate::findMany();
|
||||||
|
$templates = array_map(function($item) {
|
||||||
|
return $item->asArray();
|
||||||
|
}, $collection);
|
||||||
|
|
||||||
|
return $this->successResponse($templates);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($data = array()) {
|
||||||
|
$template = NewsletterTemplate::createOrUpdate($data);
|
||||||
|
$errors = $template->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
NewsletterTemplate::findOne($template->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$template = NewsletterTemplate::findOne($id);
|
||||||
|
if($template === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This template does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$template->delete();
|
||||||
|
return $this->successResponse(null, array('count' => 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
415
lib/API/Endpoints/Newsletters.php
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
use MailPoet\Listing;
|
||||||
|
use MailPoet\Models\Newsletter;
|
||||||
|
use MailPoet\Models\SendingQueue;
|
||||||
|
use MailPoet\Models\Setting;
|
||||||
|
use MailPoet\Models\NewsletterTemplate;
|
||||||
|
use MailPoet\Models\NewsletterSegment;
|
||||||
|
use MailPoet\Models\NewsletterOptionField;
|
||||||
|
use MailPoet\Models\NewsletterOption;
|
||||||
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Newsletter\Renderer\Renderer;
|
||||||
|
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||||
|
use MailPoet\Newsletter\Url as NewsletterUrl;
|
||||||
|
use MailPoet\Util\Helpers;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||||
|
|
||||||
|
class Newsletters extends APIEndpoint {
|
||||||
|
function get($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
$newsletter
|
||||||
|
->withSegments()
|
||||||
|
->withOptions()
|
||||||
|
->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($data = array()) {
|
||||||
|
$segment_ids = array();
|
||||||
|
if(isset($data['segments'])) {
|
||||||
|
$segment_ids = $data['segments'];
|
||||||
|
unset($data['segments']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = array();
|
||||||
|
if(isset($data['options'])) {
|
||||||
|
$options = $data['options'];
|
||||||
|
unset($data['options']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newsletter = Newsletter::createOrUpdate($data);
|
||||||
|
$errors = $newsletter->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
if(!empty($segment_ids)) {
|
||||||
|
NewsletterSegment::where('newsletter_id', $newsletter->id)
|
||||||
|
->deleteMany();
|
||||||
|
|
||||||
|
foreach($segment_ids as $segment_id) {
|
||||||
|
$relation = NewsletterSegment::create();
|
||||||
|
$relation->segment_id = $segment_id;
|
||||||
|
$relation->newsletter_id = $newsletter->id;
|
||||||
|
$relation->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($options)) {
|
||||||
|
NewsletterOption::where('newsletter_id', $newsletter->id)
|
||||||
|
->deleteMany();
|
||||||
|
|
||||||
|
$option_fields = NewsletterOptionField::where(
|
||||||
|
'newsletter_type',
|
||||||
|
$data['type']
|
||||||
|
)->findArray();
|
||||||
|
|
||||||
|
foreach($option_fields as $option_field) {
|
||||||
|
if(isset($options[$option_field['name']])) {
|
||||||
|
$relation = NewsletterOption::create();
|
||||||
|
$relation->newsletter_id = $newsletter->id;
|
||||||
|
$relation->option_field_id = $option_field['id'];
|
||||||
|
$relation->value = $options[$option_field['name']];
|
||||||
|
$relation->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatus($data = array()) {
|
||||||
|
$status = (isset($data['status']) ? $data['status'] : null);
|
||||||
|
|
||||||
|
if(!$status) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST => __('You need to specify a status.')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (isset($data['id'])) ? (int)$data['id'] : false;
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$newsletter->setStatus($status);
|
||||||
|
$errors = $newsletter->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restore($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$newsletter->restore();
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function trash($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$newsletter->trash();
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$newsletter->delete();
|
||||||
|
return $this->successResponse(null, array('count' => 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function duplicate($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$data = array(
|
||||||
|
'subject' => sprintf(__('Copy of %s'), $newsletter->subject)
|
||||||
|
);
|
||||||
|
$duplicate = $newsletter->duplicate($data);
|
||||||
|
$errors = $duplicate->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($duplicate->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPreview($data = array()) {
|
||||||
|
if(empty($data['body'])) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST => __('Newsletter data is missing.')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (isset($data['id'])) ? (int)$data['id'] : false;
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$newsletter->body = $data['body'];
|
||||||
|
$newsletter->save();
|
||||||
|
$subscriber = Subscriber::getCurrentWPUser();
|
||||||
|
$preview_url = NewsletterUrl::getViewInBrowserUrl(
|
||||||
|
$data, $subscriber, $queue = false, $preview = true
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray(),
|
||||||
|
array('preview_url' => $preview_url)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPreview($data = array()) {
|
||||||
|
if(empty($data['subscriber'])) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST => __('Please specify receiver information.')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (isset($data['id'])) ? (int)$data['id'] : false;
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$newsletter = $newsletter->asArray();
|
||||||
|
|
||||||
|
$renderer = new Renderer($newsletter, $preview = true);
|
||||||
|
$rendered_newsletter = $renderer->render();
|
||||||
|
$divider = '***MailPoet***';
|
||||||
|
$data_for_shortcodes = array_merge(
|
||||||
|
array($newsletter['subject']),
|
||||||
|
$rendered_newsletter
|
||||||
|
);
|
||||||
|
|
||||||
|
$body = implode($divider, $data_for_shortcodes);
|
||||||
|
|
||||||
|
$subscriber = Subscriber::getCurrentWPUser();
|
||||||
|
$subscriber = ($subscriber) ? $subscriber->asArray() : false;
|
||||||
|
|
||||||
|
$shortcodes = new \MailPoet\Newsletter\Shortcodes\Shortcodes(
|
||||||
|
$newsletter,
|
||||||
|
$subscriber
|
||||||
|
);
|
||||||
|
list(
|
||||||
|
$newsletter['subject'],
|
||||||
|
$newsletter['body']['html'],
|
||||||
|
$newsletter['body']['text']
|
||||||
|
) = explode($divider, $shortcodes->replace($body));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$mailer = new \MailPoet\Mailer\Mailer(
|
||||||
|
$mailer = false,
|
||||||
|
$sender = false,
|
||||||
|
$reply_to = false
|
||||||
|
);
|
||||||
|
$mailer->send($newsletter, $data['subscriber']);
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($id)->asArray()
|
||||||
|
);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listing($data = array()) {
|
||||||
|
$listing = new Listing\Handler(
|
||||||
|
'\MailPoet\Models\Newsletter',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
$listing_data = $listing->get();
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach($listing_data['items'] as $newsletter) {
|
||||||
|
$queue = false;
|
||||||
|
|
||||||
|
if($newsletter->type === Newsletter::TYPE_STANDARD) {
|
||||||
|
$newsletter
|
||||||
|
->withSegments()
|
||||||
|
->withSendingQueue()
|
||||||
|
->withStatistics();
|
||||||
|
} else if($newsletter->type === Newsletter::TYPE_WELCOME) {
|
||||||
|
$newsletter
|
||||||
|
->withOptions()
|
||||||
|
->withTotalSent()
|
||||||
|
->withStatistics();
|
||||||
|
} else if($newsletter->type === Newsletter::TYPE_NOTIFICATION) {
|
||||||
|
$newsletter
|
||||||
|
->withOptions()
|
||||||
|
->withSegments()
|
||||||
|
->withChildrenCount();
|
||||||
|
} else if($newsletter->type === Newsletter::TYPE_NOTIFICATION_HISTORY) {
|
||||||
|
$newsletter
|
||||||
|
->withSegments()
|
||||||
|
->withSendingQueue()
|
||||||
|
->withStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($newsletter->status === Newsletter::STATUS_SENT ||
|
||||||
|
$newsletter->status === Newsletter::STATUS_SENDING
|
||||||
|
) {
|
||||||
|
$queue = $newsletter->getQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get preview url
|
||||||
|
$subscriber = Subscriber::getCurrentWPUser();
|
||||||
|
$newsletter->preview_url = NewsletterUrl::getViewInBrowserUrl(
|
||||||
|
$newsletter, $subscriber, $queue, $preview = true);
|
||||||
|
|
||||||
|
$data[] = $newsletter->asArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse($data, array(
|
||||||
|
'count' => $listing_data['count'],
|
||||||
|
'filters' => $listing_data['filters'],
|
||||||
|
'groups' => $listing_data['groups']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function bulkAction($data = array()) {
|
||||||
|
try {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Newsletter',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
$meta = $bulk_action->apply();
|
||||||
|
return $this->successResponse(null, $meta);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function create($data = array()) {
|
||||||
|
$options = array();
|
||||||
|
if(isset($data['options'])) {
|
||||||
|
$options = $data['options'];
|
||||||
|
unset($data['options']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newsletter = Newsletter::createOrUpdate($data);
|
||||||
|
$errors = $newsletter->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
// try to load template data
|
||||||
|
$template_id = (isset($data['template']) ? (int)$data['template'] : false);
|
||||||
|
$template = NewsletterTemplate::findOne($template_id);
|
||||||
|
if($template === false) {
|
||||||
|
$newsletter->body = array();
|
||||||
|
} else {
|
||||||
|
$newsletter->body = $template->body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$newsletter->save();
|
||||||
|
$errors = $newsletter->getErrors();
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
if(!empty($options)) {
|
||||||
|
$option_fields = NewsletterOptionField::where(
|
||||||
|
'newsletter_type', $newsletter->type
|
||||||
|
)->findArray();
|
||||||
|
|
||||||
|
foreach($option_fields as $option_field) {
|
||||||
|
if(isset($options[$option_field['name']])) {
|
||||||
|
$relation = NewsletterOption::create();
|
||||||
|
$relation->newsletter_id = $newsletter->id;
|
||||||
|
$relation->option_field_id = $option_field['id'];
|
||||||
|
$relation->value = $options[$option_field['name']];
|
||||||
|
$relation->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
empty($data['id'])
|
||||||
|
&&
|
||||||
|
isset($data['type'])
|
||||||
|
&&
|
||||||
|
$data['type'] === Newsletter::TYPE_NOTIFICATION
|
||||||
|
) {
|
||||||
|
Scheduler::processPostNotificationSchedule($newsletter->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse(
|
||||||
|
Newsletter::findOne($newsletter->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace MailPoet\API\Endpoints;
|
|
||||||
|
|
||||||
use MailPoet\Cron\Daemon;
|
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
|
||||||
|
|
||||||
class Queue {
|
|
||||||
const ENDPOINT = 'queue';
|
|
||||||
const ACTION_RUN = 'run';
|
|
||||||
|
|
||||||
static function run($data) {
|
|
||||||
$queue = new Daemon($data);
|
|
||||||
$queue->run();
|
|
||||||
}
|
|
||||||
}
|
|
163
lib/API/Endpoints/Segments.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
|
use \MailPoet\Models\Segment;
|
||||||
|
use \MailPoet\Models\SubscriberSegment;
|
||||||
|
use \MailPoet\Models\SegmentFilter;
|
||||||
|
use \MailPoet\Listing;
|
||||||
|
use \MailPoet\Segments\WP;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Segments extends APIEndpoint {
|
||||||
|
function get($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$segment = Segment::findOne($id);
|
||||||
|
if($segment === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This list does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return $this->successResponse($segment->asArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listing($data = array()) {
|
||||||
|
$listing = new Listing\Handler(
|
||||||
|
'\MailPoet\Models\Segment',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
$listing_data = $listing->get();
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach($listing_data['items'] as $segment) {
|
||||||
|
$segment->subscribers_url = admin_url(
|
||||||
|
'admin.php?page=mailpoet-subscribers#/filter[segment='.$segment->id.']'
|
||||||
|
);
|
||||||
|
|
||||||
|
$data[] = $segment
|
||||||
|
->withSubscribersCount()
|
||||||
|
->asArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse($data, array(
|
||||||
|
'count' => $listing_data['count'],
|
||||||
|
'filters' => $listing_data['filters'],
|
||||||
|
'groups' => $listing_data['groups']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($data = array()) {
|
||||||
|
$segment = Segment::createOrUpdate($data);
|
||||||
|
$errors = $segment->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Segment::findOne($segment->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restore($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$segment = Segment::findOne($id);
|
||||||
|
if($segment === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This list does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$segment->restore();
|
||||||
|
return $this->successResponse(
|
||||||
|
Segment::findOne($segment->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function trash($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$segment = Segment::findOne($id);
|
||||||
|
if($segment === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This list does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$segment->trash();
|
||||||
|
return $this->successResponse(
|
||||||
|
Segment::findOne($segment->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$segment = Segment::findOne($id);
|
||||||
|
if($segment === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This list does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$segment->delete();
|
||||||
|
return $this->successResponse(null, array('count' => 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function duplicate($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
$segment = Segment::findOne($id);
|
||||||
|
|
||||||
|
if($segment === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This list does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$data = array(
|
||||||
|
'name' => sprintf(__('Copy of %s'), $segment->name)
|
||||||
|
);
|
||||||
|
$duplicate = $segment->duplicate($data);
|
||||||
|
$errors = $duplicate->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->errorResponse($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Segment::findOne($duplicate->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function synchronize() {
|
||||||
|
try {
|
||||||
|
WP::synchronizeUsers();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->successResponse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bulkAction($data = array()) {
|
||||||
|
try {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Segment',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
$meta = $bulk_action->apply();
|
||||||
|
return $this->successResponse(null, $meta);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Router;
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
use MailPoet\Models\Newsletter;
|
use MailPoet\Models\Newsletter;
|
||||||
@ -14,65 +16,41 @@ use MailPoet\Util\Helpers;
|
|||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class SendingQueue {
|
class SendingQueue extends APIEndpoint {
|
||||||
function add($data) {
|
function add($data = array()) {
|
||||||
|
$newsletter_id = (isset($data['newsletter_id'])
|
||||||
|
? (int)$data['newsletter_id']
|
||||||
|
: false
|
||||||
|
);
|
||||||
|
|
||||||
|
// check that the newsletter exists
|
||||||
|
$newsletter = Newsletter::filter('filterWithOptions')
|
||||||
|
->findOne($newsletter_id);
|
||||||
|
|
||||||
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// check that the sending method has been configured properly
|
// check that the sending method has been configured properly
|
||||||
try {
|
try {
|
||||||
new Mailer(false);
|
new Mailer(false);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return array(
|
return $this->errorResponse(array(
|
||||||
'result' => false,
|
$e->getCode() => $e->getMessage()
|
||||||
'errors' => array($e->getMessage())
|
));
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the newsletter exists
|
|
||||||
$newsletter = Newsletter::filter('filterWithOptions')
|
|
||||||
->findOne($data['newsletter_id']);
|
|
||||||
|
|
||||||
if($newsletter === false) {
|
|
||||||
return array(
|
|
||||||
'result' => false,
|
|
||||||
'errors' => array(__('This newsletter does not exist.'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($newsletter->type === Newsletter::TYPE_WELCOME) {
|
|
||||||
// set welcome email active
|
|
||||||
$result = $newsletter->setStatus(Newsletter::STATUS_ACTIVE);
|
|
||||||
$errors = $result->getErrors();
|
|
||||||
|
|
||||||
if(!empty($errors)) {
|
|
||||||
return array(
|
|
||||||
'result' => false,
|
|
||||||
'errors' => $errors
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return array(
|
|
||||||
'result' => true,
|
|
||||||
'data' => array(
|
|
||||||
'message' => __('Your welcome email has been activated.')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if($newsletter->type === Newsletter::TYPE_NOTIFICATION) {
|
|
||||||
// Post Notifications
|
|
||||||
$newsletter = Scheduler::processPostNotificationSchedule($newsletter->id);
|
|
||||||
Scheduler::createPostNotificationQueue($newsletter);
|
|
||||||
|
|
||||||
// set post notification active
|
|
||||||
$newsletter->setStatus(Newsletter::STATUS_ACTIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add newsletter to the sending queue
|
||||||
$queue = SendingQueueModel::whereNull('status')
|
$queue = SendingQueueModel::whereNull('status')
|
||||||
->where('newsletter_id', $newsletter->id)
|
->where('newsletter_id', $newsletter->id)
|
||||||
->findOne();
|
->findOne();
|
||||||
|
|
||||||
if(!empty($queue)) {
|
if(!empty($queue)) {
|
||||||
return array(
|
return $this->errorResponse(array(
|
||||||
'result' => false,
|
APIError::NOT_FOUND => __('This newsletter is already being sent.')
|
||||||
'errors' => array(__('This newsletter is already being sent.'))
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$queue = SendingQueueModel::where('newsletter_id', $newsletter->id)
|
$queue = SendingQueueModel::where('newsletter_id', $newsletter->id)
|
||||||
@ -83,18 +61,6 @@ class SendingQueue {
|
|||||||
$queue->newsletter_id = $newsletter->id;
|
$queue->newsletter_id = $newsletter->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($newsletter->type === Newsletter::TYPE_NOTIFICATION) {
|
|
||||||
$queue->scheduled_at = Scheduler::getNextRunDate($newsletter->schedule);
|
|
||||||
$queue->status = SendingQueueModel::STATUS_SCHEDULED;
|
|
||||||
$queue->save();
|
|
||||||
return array(
|
|
||||||
'result' => true,
|
|
||||||
'data' => array(
|
|
||||||
'message' => __('Your post notification has been activated.')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((bool)$newsletter->isScheduled) {
|
if((bool)$newsletter->isScheduled) {
|
||||||
// set newsletter status
|
// set newsletter status
|
||||||
$newsletter->setStatus(Newsletter::STATUS_SCHEDULED);
|
$newsletter->setStatus(Newsletter::STATUS_SCHEDULED);
|
||||||
@ -106,8 +72,6 @@ class SendingQueue {
|
|||||||
);
|
);
|
||||||
$queue->subscribers = null;
|
$queue->subscribers = null;
|
||||||
$queue->count_total = $queue->count_to_process = 0;
|
$queue->count_total = $queue->count_to_process = 0;
|
||||||
|
|
||||||
$message = __('The newsletter has been scheduled.');
|
|
||||||
} else {
|
} else {
|
||||||
$segments = $newsletter->segments()->findArray();
|
$segments = $newsletter->segments()->findArray();
|
||||||
$segment_ids = array_map(function($segment) {
|
$segment_ids = array_map(function($segment) {
|
||||||
@ -118,10 +82,9 @@ class SendingQueue {
|
|||||||
$subscribers = Helpers::arrayColumn($subscribers, 'subscriber_id');
|
$subscribers = Helpers::arrayColumn($subscribers, 'subscriber_id');
|
||||||
$subscribers = array_unique($subscribers);
|
$subscribers = array_unique($subscribers);
|
||||||
if(!count($subscribers)) {
|
if(!count($subscribers)) {
|
||||||
return array(
|
return $this->errorResponse(array(
|
||||||
'result' => false,
|
APIError::UNKNOWN => __('There are no subscribers in that list!')
|
||||||
'errors' => array(__('There are no subscribers.'))
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
$queue->status = null;
|
$queue->status = null;
|
||||||
$queue->scheduled_at = null;
|
$queue->scheduled_at = null;
|
||||||
@ -134,58 +97,69 @@ class SendingQueue {
|
|||||||
|
|
||||||
// set newsletter status
|
// set newsletter status
|
||||||
$newsletter->setStatus(Newsletter::STATUS_SENDING);
|
$newsletter->setStatus(Newsletter::STATUS_SENDING);
|
||||||
|
|
||||||
$message = __('The newsletter is being sent...');
|
|
||||||
}
|
}
|
||||||
$queue->save();
|
$queue->save();
|
||||||
|
|
||||||
$errors = $queue->getErrors();
|
$errors = $queue->getErrors();
|
||||||
if(!empty($errors)) {
|
if(!empty($errors)) {
|
||||||
return array(
|
return $this->errorResponse($errors);
|
||||||
'result' => false,
|
|
||||||
'errors' => $errors
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return array(
|
return $this->successResponse(
|
||||||
'result' => true,
|
$newsletter->getQueue()->asArray()
|
||||||
'data' => array(
|
|
||||||
'message' => $message
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pause($newsletter_id) {
|
function pause($data = array()) {
|
||||||
|
$newsletter_id = (isset($data['newsletter_id'])
|
||||||
|
? (int)$data['newsletter_id']
|
||||||
|
: false
|
||||||
|
);
|
||||||
$newsletter = Newsletter::findOne($newsletter_id);
|
$newsletter = Newsletter::findOne($newsletter_id);
|
||||||
$result = false;
|
|
||||||
|
|
||||||
if($newsletter !== false) {
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
$queue = $newsletter->getQueue();
|
$queue = $newsletter->getQueue();
|
||||||
|
|
||||||
if($queue !== false) {
|
if($queue === false) {
|
||||||
$result = $queue->pause();
|
return $this->errorResponse(array(
|
||||||
|
APIError::UNKNOWN => __('This newsletter has not been sent yet.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$queue->pause();
|
||||||
|
return $this->successResponse(
|
||||||
|
$newsletter->getQueue()->asArray()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
|
||||||
'result' => $result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resume($newsletter_id) {
|
function resume($data = array()) {
|
||||||
|
$newsletter_id = (isset($data['newsletter_id'])
|
||||||
|
? (int)$data['newsletter_id']
|
||||||
|
: false
|
||||||
|
);
|
||||||
$newsletter = Newsletter::findOne($newsletter_id);
|
$newsletter = Newsletter::findOne($newsletter_id);
|
||||||
$result = false;
|
if($newsletter === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
if($newsletter !== false) {
|
APIError::NOT_FOUND => __('This newsletter does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
$queue = $newsletter->getQueue();
|
$queue = $newsletter->getQueue();
|
||||||
|
|
||||||
if($queue !== false) {
|
if($queue === false) {
|
||||||
$result = $queue->resume();
|
return $this->errorResponse(array(
|
||||||
|
APIError::UNKNOWN => __('This newsletter has not been sent yet.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$queue->resume();
|
||||||
|
return $this->successResponse(
|
||||||
|
$newsletter->getQueue()->asArray()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
|
||||||
'result' => $result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
27
lib/API/Endpoints/Settings.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
use \MailPoet\Models\Setting;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Settings extends APIEndpoint {
|
||||||
|
function get() {
|
||||||
|
return $this->successResponse(Setting::getAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
function set($settings = array()) {
|
||||||
|
if(empty($settings)) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST =>
|
||||||
|
__("You have not specified any settings to be saved.")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
foreach($settings as $name => $value) {
|
||||||
|
Setting::setValue($name, $value);
|
||||||
|
}
|
||||||
|
return $this->successResponse(Setting::getAll());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
lib/API/Endpoints/Setup.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\Config\Activator;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Setup extends APIEndpoint {
|
||||||
|
function reset() {
|
||||||
|
try {
|
||||||
|
$activator = new Activator();
|
||||||
|
$activator->deactivate();
|
||||||
|
$activator->activate();
|
||||||
|
return $this->successResponse();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Router;
|
namespace MailPoet\API\Endpoints;
|
||||||
|
use \MailPoet\API\Endpoint as APIEndpoint;
|
||||||
|
use \MailPoet\API\Error as APIError;
|
||||||
|
|
||||||
use MailPoet\Listing;
|
use MailPoet\Listing;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
@ -13,19 +15,22 @@ use MailPoet\Util\Url;
|
|||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Subscribers {
|
class Subscribers extends APIEndpoint {
|
||||||
function __construct() {
|
function get($data = array()) {
|
||||||
}
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
|
|
||||||
function get($id = null) {
|
|
||||||
$subscriber = Subscriber::findOne($id);
|
$subscriber = Subscriber::findOne($id);
|
||||||
if($subscriber !== false) {
|
if($subscriber === false) {
|
||||||
$subscriber = $subscriber
|
return $this->errorResponse(array(
|
||||||
->withCustomFields()
|
APIError::NOT_FOUND => __('This subscriber does not exist.')
|
||||||
->withSubscriptions()
|
));
|
||||||
->asArray();
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
$subscriber
|
||||||
|
->withCustomFields()
|
||||||
|
->withSubscriptions()
|
||||||
|
->asArray()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return $subscriber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function listing($data = array()) {
|
function listing($data = array()) {
|
||||||
@ -36,30 +41,18 @@ class Subscribers {
|
|||||||
|
|
||||||
$listing_data = $listing->get();
|
$listing_data = $listing->get();
|
||||||
|
|
||||||
// fetch segments relations for each returned item
|
$data = array();
|
||||||
foreach($listing_data['items'] as $key => $subscriber) {
|
foreach($listing_data['items'] as $subscriber) {
|
||||||
$listing_data['items'][$key] = $subscriber
|
$data[] = $subscriber
|
||||||
->withSubscriptions()
|
->withSubscriptions()
|
||||||
->asArray();
|
->asArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $listing_data;
|
return $this->successResponse($data, array(
|
||||||
}
|
'count' => $listing_data['count'],
|
||||||
|
'filters' => $listing_data['filters'],
|
||||||
function save($data = array()) {
|
'groups' => $listing_data['groups']
|
||||||
$subscriber = Subscriber::createOrUpdate($data);
|
));
|
||||||
$errors = $subscriber->getErrors();
|
|
||||||
|
|
||||||
if(!empty($errors)) {
|
|
||||||
return array(
|
|
||||||
'result' => false,
|
|
||||||
'errors' => $errors
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return array(
|
|
||||||
'result' => true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribe($data = array()) {
|
function subscribe($data = array()) {
|
||||||
@ -69,7 +62,7 @@ class Subscribers {
|
|||||||
$form = Form::findOne($data['form_id']);
|
$form = Form::findOne($data['form_id']);
|
||||||
unset($data['form_id']);
|
unset($data['form_id']);
|
||||||
if($form === false || !$form->id()) {
|
if($form === false || !$form->id()) {
|
||||||
$errors[] = __('This form does not exist.');
|
$errors[] = __('This form does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$segment_ids = (!empty($data['segments'])
|
$segment_ids = (!empty($data['segments'])
|
||||||
@ -148,37 +141,76 @@ class Subscribers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function restore($id) {
|
function save($data = array()) {
|
||||||
|
$subscriber = Subscriber::createOrUpdate($data);
|
||||||
|
$errors = $subscriber->getErrors();
|
||||||
|
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $this->badRequest($errors);
|
||||||
|
} else {
|
||||||
|
return $this->successResponse(
|
||||||
|
Subscriber::findOne($subscriber->id)->asArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restore($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
$subscriber = Subscriber::findOne($id);
|
$subscriber = Subscriber::findOne($id);
|
||||||
if($subscriber !== false) {
|
if($subscriber === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This subscriber does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
$subscriber->restore();
|
$subscriber->restore();
|
||||||
|
return $this->successResponse(
|
||||||
|
Subscriber::findOne($subscriber->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ($subscriber->getErrors() === false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function trash($id) {
|
function trash($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
$subscriber = Subscriber::findOne($id);
|
$subscriber = Subscriber::findOne($id);
|
||||||
if($subscriber !== false) {
|
if($subscriber === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This subscriber does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
$subscriber->trash();
|
$subscriber->trash();
|
||||||
|
return $this->successResponse(
|
||||||
|
Subscriber::findOne($subscriber->id)->asArray(),
|
||||||
|
array('count' => 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ($subscriber->getErrors() === false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete($id) {
|
function delete($data = array()) {
|
||||||
|
$id = (isset($data['id']) ? (int)$data['id'] : false);
|
||||||
$subscriber = Subscriber::findOne($id);
|
$subscriber = Subscriber::findOne($id);
|
||||||
if($subscriber !== false) {
|
if($subscriber === false) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
APIError::NOT_FOUND => __('This subscriber does not exist.')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
$subscriber->delete();
|
$subscriber->delete();
|
||||||
return 1;
|
return $this->successResponse(null, array('count' => 1));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function bulkAction($data = array()) {
|
function bulkAction($data = array()) {
|
||||||
$bulk_action = new Listing\BulkAction(
|
try {
|
||||||
'\MailPoet\Models\Subscriber',
|
$bulk_action = new Listing\BulkAction(
|
||||||
$data
|
'\MailPoet\Models\Subscriber',
|
||||||
);
|
$data
|
||||||
|
);
|
||||||
return $bulk_action->apply();
|
$meta = $bulk_action->apply();
|
||||||
|
return $this->successResponse(null, $meta);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
return $this->errorResponse(array(
|
||||||
|
$e->getCode() => $e->getMessage()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace MailPoet\API\Endpoints;
|
|
||||||
|
|
||||||
use MailPoet\Subscription as UserSubscription;
|
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
|
||||||
|
|
||||||
class Subscription {
|
|
||||||
const ENDPOINT = 'subscription';
|
|
||||||
|
|
||||||
static function confirm($data) {
|
|
||||||
$subscription = new UserSubscription\Pages('confirm', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function manage($data) {
|
|
||||||
$subscription = new UserSubscription\Pages('manage', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function unsubscribe($data) {
|
|
||||||
$subscription = new UserSubscription\Pages('unsubscribe', $data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace MailPoet\API\Endpoints;
|
|
||||||
|
|
||||||
use MailPoet\Statistics\Track\Clicks;
|
|
||||||
use MailPoet\Statistics\Track\Opens;
|
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
|
||||||
|
|
||||||
class Track {
|
|
||||||
const ENDPOINT = 'track';
|
|
||||||
const ACTION_CLICK = 'click';
|
|
||||||
const ACTION_OPEN = 'open';
|
|
||||||
|
|
||||||
static function click($data) {
|
|
||||||
$clicks = new Clicks($data);
|
|
||||||
$clicks->track();
|
|
||||||
}
|
|
||||||
|
|
||||||
static function open($data) {
|
|
||||||
$opens = new Opens($data);
|
|
||||||
$opens->track();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace MailPoet\API\Endpoints;
|
|
||||||
|
|
||||||
use MailPoet\Newsletter\ViewInBrowser as NewsletterViewInBrowser;
|
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
|
||||||
|
|
||||||
class ViewInBrowser {
|
|
||||||
const ENDPOINT = 'view_in_browser';
|
|
||||||
const ACTION_VIEW = 'view';
|
|
||||||
|
|
||||||
static function view($data) {
|
|
||||||
$viewer = new NewsletterViewInBrowser($data);
|
|
||||||
$viewer->view();
|
|
||||||
}
|
|
||||||
}
|
|
16
lib/API/Error.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
final class Error {
|
||||||
|
const UNKNOWN = 'unknown';
|
||||||
|
const BAD_REQUEST = 'bad_request';
|
||||||
|
const UNAUTHORIZED = 'unauthorized';
|
||||||
|
const FORBIDDEN = 'forbidden';
|
||||||
|
const NOT_FOUND = 'not_found';
|
||||||
|
|
||||||
|
private function __construct() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
34
lib/API/ErrorResponse.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\API;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class ErrorResponse extends Response {
|
||||||
|
public $errors;
|
||||||
|
|
||||||
|
function __construct($errors = array(), $meta = array(), $status = self::STATUS_NOT_FOUND) {
|
||||||
|
parent::__construct($status, $meta);
|
||||||
|
$this->errors = $this->formatErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData() {
|
||||||
|
if(empty($this->errors)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return array(
|
||||||
|
'errors' => $this->errors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatErrors($errors = array()) {
|
||||||
|
$formatted_errors = array();
|
||||||
|
foreach($errors as $error => $message) {
|
||||||
|
$formatted_errors[] = array(
|
||||||
|
'error' => $error,
|
||||||
|
'message' => $message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $formatted_errors;
|
||||||
|
}
|
||||||
|
}
|