Bugfixes on sending

- added checks to prevent adding to the queue useless items
- fixed issue with mta settings (duplicated "host" input / renamed duplicate to "domain" for MailGun)
- fixed namespace issue on cron daemon/supervisor
- fixed typo in migration preventing the newsletter_templates table to be created.
- partially fixed cron.jsx
This commit is contained in:
Jonathan Labreuille
2015-12-07 13:29:42 +01:00
parent c0ba218949
commit 268dabdc9f
8 changed files with 132 additions and 108 deletions

View File

@@ -1,98 +1,102 @@
define( define(
[ [
'react', 'react',
'react-dom', 'react-dom',
'mailpoet' 'mailpoet'
], ],
function ( function(
React, React,
ReactDOM, ReactDOM,
MailPoet MailPoet
) { ) {
var CronControl = React.createClass({ var CronControl = React.createClass({
getInitialState: function () { getInitialState: function() {
return (cronDaemon) ? cronDaemon : null; return {
}, status: 'loading'
getDaemonData: function () { };
MailPoet.Ajax.post({ },
endpoint: 'cron', getDaemonData: function() {
action: 'getDaemonStatus' MailPoet.Ajax.post({
}).done(function (response) { endpoint: 'cron',
jQuery('.button-primary').removeClass('disabled'); action: 'getDaemonStatus'
if (!response) { })
this.replaceState(); .done(function(response) {
} else { jQuery('.button-primary')
this.setState(response); .removeClass('disabled');
} if(response.status !== undefined) {
}.bind(this)); this.setState(response);
}, } else {
componentDidMount: function componentDidMount() { this.replaceState();
if (this.isMounted()) { }
this.getDaemonData; }.bind(this));
setInterval(this.getDaemonData, 5000); },
} componentDidMount: function() {
}, if(this.isMounted()) {
controlDaemon: function (action) { this.getDaemonData();
jQuery('.button-primary').addClass('disabled'); setInterval(this.getDaemonData, 5000);
MailPoet.Ajax.post({ }
endpoint: 'cron', },
action: 'controlDaemon', controlDaemon: function(action) {
data: {'action': action} jQuery('.button-primary')
}).done(function (response) { .addClass('disabled');
if (!response) { MailPoet.Ajax.post({
this.replaceState(); endpoint: 'cron',
} else { action: 'controlDaemon',
this.setState(response); data: {
} 'action': action
}.bind(this)); }
}, })
render: function () { .done(function(response) {
if (!this.state) { if(!response.result) {
return //this.replaceState();
<div> } else {
Woops, daemon is not running ;\ //this.setState(response);
</div> }
} }.bind(this));
switch (this.state.status) { },
case 'started': render: function() {
return ( if(this.state.status === 'loading') {
return(<div>Loading daemon status...</div>);
}
switch(this.state.status) {
case 'started':
return(
<div> <div>
<div> Cron daemon is running.
Cron daemon is running. <br/>
<br/> <br/>
<br/> It was started
It was started <strong> {this.state.timeSinceStart} </strong> and last executed
<strong> {this.state.timeSinceStart} </strong> and last executed <strong> {this.state.timeSinceUpdate} </strong> for a total of
<strong> {this.state.timeSinceUpdate} </strong> for a total of <strong> {this.state.counter} </strong> times (once every 30 seconds, unless it was interrupted and restarted).
<strong> {this.state.counter} </strong> times (once every 30 seconds, unless it was interrupted and restarted). <br />
<br /> <br />
<br /> <a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'stop')}>Stop</a>&nbsp;&nbsp;
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'stop')}>Stop</a>&nbsp;&nbsp; <a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'pause')}>Pause</a>
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'pause')}>Pause</a>
</div>
</div> </div>
); );
break; break;
case 'paused': case 'paused':
case 'stopped': case 'stopped':
return ( return(
<div> <div>
Daemon is {this.state.status} Daemon is {this.state.status}
<br /> <br />
<br /> <br />
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'start')}>Start</a> <a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'start')}>Start</a>
</div> </div>
) );
break; break;
} }
} }
}); });
let container = document.getElementById('cron_container');
if (container) { const container = document.getElementById('cron_container');
ReactDOM.render(
if(container) {
ReactDOM.render(
<CronControl />, <CronControl />,
document.getElementById('cron_status') container
) );
} }
} });
);

View File

@@ -381,8 +381,6 @@ class Menu {
} }
function cron() { function cron() {
$daemon = new \MailPoet\Cron\BootStrapMenu(); echo $this->renderer->render('cron.html');
$data['daemon'] = json_encode($daemon->bootstrap());
echo $this->renderer->render('cron.html', $data);
} }
} }

View File

@@ -105,7 +105,7 @@ class Migrator {
'description varchar(250) NOT NULL,', 'description varchar(250) NOT NULL,',
'body LONGTEXT,', 'body LONGTEXT,',
'thumbnail LONGTEXT,', 'thumbnail LONGTEXT,',
'readonly TINYINT(1) DEFAULT 0', 'readonly TINYINT(1) DEFAULT 0,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)' 'PRIMARY KEY (id)'

View File

@@ -25,8 +25,12 @@ class PublicAPI {
} }
function queue() { function queue() {
$queue = new Daemon($this->payload); try {
$this->_checkAndCallMethod($queue, $this->action); $queue = new Daemon($this->payload);
$this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) {
// mailer configuration error
}
} }
private function _checkAndCallMethod($class, $method, $terminate = false) { private function _checkAndCallMethod($class, $method, $terminate = false) {

View File

@@ -11,14 +11,13 @@ class Cron {
function controlDaemon($data) { function controlDaemon($data) {
switch($data['action']) { switch($data['action']) {
case 'start': case 'start':
$supervisor = new Supervisor($forceStart = true); $supervisor = new \MailPoet\Cron\Supervisor($forceStart = true);
wp_send_json( wp_send_json(
array( array(
'result' => $supervisor->checkDaemon() ? 'result' => $supervisor->checkDaemon()
true :
false
) )
); );
exit;
break; break;
case 'stop': case 'stop':
$status = 'stopped'; $status = 'stopped';
@@ -27,7 +26,7 @@ class Cron {
$status = 'paused'; $status = 'paused';
break; break;
} }
$daemon = new Daemon(); $daemon = new \MailPoet\Cron\Daemon();
if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') { if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') {
$result = false; $result = false;
} else { } else {

View File

@@ -9,6 +9,19 @@ if(!defined('ABSPATH')) exit;
class SendingQueue { class SendingQueue {
function add($data) { function add($data) {
// check if mailer is properly configured
try {
new Mailer(false);
} catch(\Exception $e) {
wp_send_json(
array(
'result' => false,
'errors' => array($e->getMessage())
)
);
exit;
}
$queue = \MailPoet\Models\SendingQueue::where('newsletter_id', $data['newsletter_id']) $queue = \MailPoet\Models\SendingQueue::where('newsletter_id', $data['newsletter_id'])
->whereNull('status') ->whereNull('status')
->findArray(); ->findArray();
@@ -34,6 +47,17 @@ class SendingQueue {
'id' 'id'
)); ));
} }
if(empty($subscriber_ids)) {
wp_send_json(
array(
'result' => false,
'errors' => array(__('There are no subscribers.'))
)
);
exit;
}
$subscriber_ids = array_unique($subscriber_ids); $subscriber_ids = array_unique($subscriber_ids);
$queue->subscribers = json_encode( $queue->subscribers = json_encode(
array( array(

View File

@@ -1,10 +1,5 @@
<% extends 'layout.html' %> <% extends 'layout.html' %>
<% block content %> <% block content %>
<div id="cron_container"> <div id="cron_container"></div>
<div id="cron_status"></div>
</div>
<script>
var cronDaemon = <%= daemon|raw %>
</script>
<% endblock %> <% endblock %>

View File

@@ -492,9 +492,9 @@
<input <input
type="text" type="text"
class="regular-text" class="regular-text"
id="settings[mta_host]" id="settings[mta_domain]"
name="mta[host]" name="mta[domain]"
value="<%= settings.mta.host %>" /> value="<%= settings.mta.domain %>" />
</td> </td>
</tr> </tr>