Status update of newsletters completed
- duplicate newsletter now includes options as well - fixed NaN issue in statistics when newsletter is being sent - use constant for scheduled (and put it as the sendingQueue Model level)
This commit is contained in:
@ -94,12 +94,12 @@ const bulk_actions = [
|
||||
}
|
||||
];
|
||||
|
||||
const item_actions = [
|
||||
const newsletter_actions = [
|
||||
{
|
||||
name: 'view',
|
||||
link: function(item) {
|
||||
link: function(newsletter) {
|
||||
return (
|
||||
<a href={ item.preview_url } target="_blank">
|
||||
<a href={ newsletter.preview_url } target="_blank">
|
||||
{MailPoet.I18n.t('preview')}
|
||||
</a>
|
||||
);
|
||||
@ -107,9 +107,9 @@ const item_actions = [
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
link: function(item) {
|
||||
link: function(newsletter) {
|
||||
return (
|
||||
<a href={ `?page=mailpoet-newsletter-editor&id=${ item.id }` }>
|
||||
<a href={ `?page=mailpoet-newsletter-editor&id=${ newsletter.id }` }>
|
||||
{MailPoet.I18n.t('edit')}
|
||||
</a>
|
||||
);
|
||||
@ -118,11 +118,11 @@ const item_actions = [
|
||||
{
|
||||
name: 'duplicate',
|
||||
label: MailPoet.I18n.t('duplicate'),
|
||||
onClick: function(item, refresh) {
|
||||
onClick: function(newsletter, refresh) {
|
||||
return MailPoet.Ajax.post({
|
||||
endpoint: 'newsletters',
|
||||
action: 'duplicate',
|
||||
data: item.id
|
||||
data: newsletter.id
|
||||
}).done(function(response) {
|
||||
if (response !== false && response.subject !== undefined) {
|
||||
MailPoet.Notice.success(
|
||||
@ -141,77 +141,77 @@ const item_actions = [
|
||||
];
|
||||
|
||||
const NewsletterListStandard = React.createClass({
|
||||
pauseSending: function(item) {
|
||||
pauseSending: function(newsletter) {
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'sendingQueue',
|
||||
action: 'pause',
|
||||
data: item.id
|
||||
data: newsletter.id
|
||||
}).done(function() {
|
||||
jQuery('#resume_'+item.id).show();
|
||||
jQuery('#pause_'+item.id).hide();
|
||||
jQuery('#resume_'+newsletter.id).show();
|
||||
jQuery('#pause_'+newsletter.id).hide();
|
||||
});
|
||||
},
|
||||
resumeSending: function(item) {
|
||||
resumeSending: function(newsletter) {
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'sendingQueue',
|
||||
action: 'resume',
|
||||
data: item.id
|
||||
data: newsletter.id
|
||||
}).done(function() {
|
||||
jQuery('#pause_'+item.id).show();
|
||||
jQuery('#resume_'+item.id).hide();
|
||||
jQuery('#pause_'+newsletter.id).show();
|
||||
jQuery('#resume_'+newsletter.id).hide();
|
||||
});
|
||||
},
|
||||
renderStatus: function(item) {
|
||||
if(!item.queue) {
|
||||
renderStatus: function(newsletter) {
|
||||
if (!newsletter.queue) {
|
||||
return (
|
||||
<span>{MailPoet.I18n.t('notSentYet')}</span>
|
||||
);
|
||||
} else {
|
||||
if (item.queue.status === 'scheduled') {
|
||||
if (newsletter.queue.status === 'scheduled') {
|
||||
return (
|
||||
<span>{MailPoet.I18n.t('scheduledFor')} { MailPoet.Date.format(item.queue.scheduled_at) } </span>
|
||||
<span>{MailPoet.I18n.t('scheduledFor')} { MailPoet.Date.format(newsletter.queue.scheduled_at) } </span>
|
||||
)
|
||||
}
|
||||
const progressClasses = classNames(
|
||||
'mailpoet_progress',
|
||||
{ 'mailpoet_progress_complete': item.queue.status === 'completed'}
|
||||
{ 'mailpoet_progress_complete': newsletter.queue.status === 'completed'}
|
||||
);
|
||||
|
||||
// calculate percentage done
|
||||
const percentage = Math.round(
|
||||
(item.queue.count_processed * 100) / (item.queue.count_total)
|
||||
(newsletter.queue.count_processed * 100) / (newsletter.queue.count_total)
|
||||
);
|
||||
|
||||
let label;
|
||||
|
||||
if(item.queue.status === 'completed') {
|
||||
if (newsletter.queue.status === 'completed') {
|
||||
label = (
|
||||
<span>
|
||||
{
|
||||
MailPoet.I18n.t('newsletterQueueCompleted')
|
||||
.replace("%$1d", item.queue.count_processed - item.queue.count_failed)
|
||||
.replace("%$2d", item.queue.count_total)
|
||||
.replace("%$1d", newsletter.queue.count_processed - newsletter.queue.count_failed)
|
||||
.replace("%$2d", newsletter.queue.count_total)
|
||||
}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
label = (
|
||||
<span>
|
||||
{ item.queue.count_processed } / { item.queue.count_total }
|
||||
{ newsletter.queue.count_processed } / { newsletter.queue.count_total }
|
||||
|
||||
<a
|
||||
id={ 'resume_'+item.id }
|
||||
id={ 'resume_'+newsletter.id }
|
||||
className="button"
|
||||
style={{ display: (item.queue.status === 'paused') ? 'inline-block': 'none' }}
|
||||
style={{ display: (newsletter.queue.status === 'paused') ? 'inline-block': 'none' }}
|
||||
href="javascript:;"
|
||||
onClick={ this.resumeSending.bind(null, item) }
|
||||
onClick={ this.resumeSending.bind(null, newsletter) }
|
||||
>{MailPoet.I18n.t('resume')}</a>
|
||||
<a
|
||||
id={ 'pause_'+item.id }
|
||||
id={ 'pause_'+newsletter.id }
|
||||
className="button mailpoet_pause"
|
||||
style={{ display: (item.queue.status === null) ? 'inline-block': 'none' }}
|
||||
style={{ display: (newsletter.queue.status === null) ? 'inline-block': 'none' }}
|
||||
href="javascript:;"
|
||||
onClick={ this.pauseSending.bind(null, item) }
|
||||
onClick={ this.pauseSending.bind(null, newsletter) }
|
||||
>{MailPoet.I18n.t('pause')}</a>
|
||||
</span>
|
||||
);
|
||||
@ -240,17 +240,24 @@ const NewsletterListStandard = React.createClass({
|
||||
return;
|
||||
}
|
||||
|
||||
if(newsletter.statistics && newsletter.queue && newsletter.queue.status !== 'scheduled') {
|
||||
if (newsletter.statistics && newsletter.queue && newsletter.queue.status !== 'scheduled') {
|
||||
const total_sent = ~~(newsletter.queue.count_processed);
|
||||
const percentage_clicked = Math.round(
|
||||
(~~(newsletter.statistics.clicked) * 100) / total_sent
|
||||
);
|
||||
const percentage_opened = Math.round(
|
||||
(~~(newsletter.statistics.opened) * 100) / total_sent
|
||||
);
|
||||
const percentage_unsubscribed = Math.round(
|
||||
(~~(newsletter.statistics.unsubscribed) * 100) / total_sent
|
||||
);
|
||||
|
||||
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>
|
||||
@ -318,7 +325,7 @@ const NewsletterListStandard = React.createClass({
|
||||
onRenderItem={this.renderItem}
|
||||
columns={columns}
|
||||
bulk_actions={ bulk_actions }
|
||||
item_actions={ item_actions }
|
||||
item_actions={ newsletter_actions }
|
||||
messages={ messages }
|
||||
auto_refresh={ true }
|
||||
/>
|
||||
|
@ -105,8 +105,9 @@ define(
|
||||
}
|
||||
}).done((response) => {
|
||||
this.setState({ loading: false });
|
||||
|
||||
if(response.result === true) {
|
||||
this.context.router.push('/');
|
||||
this.context.router.push(`/${ this.state.item.type || '' }`);
|
||||
MailPoet.Notice.success(response.data.message);
|
||||
} else {
|
||||
if(response.errors) {
|
||||
@ -133,7 +134,7 @@ define(
|
||||
this.setState({ loading: false });
|
||||
|
||||
if(response.result === true) {
|
||||
this.context.router.push('/');
|
||||
this.context.router.push(`/${ this.state.item.type || '' }`);
|
||||
MailPoet.Notice.success(
|
||||
MailPoet.I18n.t('newsletterUpdated')
|
||||
);
|
||||
|
@ -322,6 +322,10 @@ class SendingQueue {
|
||||
if(!$queue->count_to_process) {
|
||||
$queue->processed_at = current_time('mysql');
|
||||
$queue->status = SendingQueueModel::STATUS_COMPLETED;
|
||||
|
||||
// set newsletter status to sent
|
||||
$newsletter = Newsletter::findOne($queue->newsletter_id);
|
||||
$newsletter->setStatus(Newsletter::STATUS_SENT);
|
||||
}
|
||||
$queue->subscribers = serialize((array) $queue->subscribers);
|
||||
$queue->save();
|
||||
|
@ -86,12 +86,24 @@ class Newsletter extends Model {
|
||||
foreach($segments as $segment) {
|
||||
$relation = NewsletterSegment::create();
|
||||
$relation->segment_id = $segment['id'];
|
||||
$relation->newsletter_id = $duplicate->id();
|
||||
$result = $relation->save();
|
||||
$relation->newsletter_id = $duplicate->id;
|
||||
$relation->save();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: duplicate options (if need be)
|
||||
// duplicate options
|
||||
$options = NewsletterOption::where('newsletter_id', $this->id)
|
||||
->findArray();
|
||||
|
||||
if(!empty($options)) {
|
||||
foreach($options as $option) {
|
||||
$relation = NewsletterOption::create();
|
||||
$relation->newsletter_id = $duplicate->id;
|
||||
$relation->option_field_id = $option['option_field_id'];
|
||||
$relation->value = $option['value'];
|
||||
$relation->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $duplicate;
|
||||
|
@ -7,6 +7,8 @@ class SendingQueue extends Model {
|
||||
public static $_table = MP_SENDING_QUEUES_TABLE;
|
||||
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
const STATUS_SCHEDULED = 'scheduled';
|
||||
const STATUS_PAUSED = 'paused';
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
@ -16,7 +18,7 @@ class SendingQueue extends Model {
|
||||
if($this->count_processed === $this->count_total) {
|
||||
return false;
|
||||
} else {
|
||||
$this->set('status', 'paused');
|
||||
$this->set('status', STATUS_PAUSED);
|
||||
$this->save();
|
||||
return ($this->getErrors() === false && $this->id() > 0);
|
||||
}
|
||||
@ -26,14 +28,14 @@ class SendingQueue extends Model {
|
||||
if($this->count_processed === $this->count_total) {
|
||||
return $this->complete();
|
||||
} else {
|
||||
$this->set_expr('status', 'NULL');
|
||||
$this->setExpr('status', 'NULL');
|
||||
$this->save();
|
||||
return ($this->getErrors() === false && $this->id() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
function complete() {
|
||||
$this->set('status', 'completed');
|
||||
$this->set('status', self::STATUS_COMPLETED);
|
||||
$this->save();
|
||||
return ($this->getErrors() === false && $this->id() > 0);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ class Scheduler {
|
||||
if($existing_queue) return;
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $newsletter->id;
|
||||
$queue->status = 'scheduled';
|
||||
$queue->status = self::STATUS_SCHEDULED;
|
||||
$queue->scheduled_at = $next_run_date;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
|
@ -9,12 +9,14 @@ use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
use MailPoet\Models\SendingQueue as SendingQueueModel;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingQueue {
|
||||
function add($data) {
|
||||
// check that the sending method has been configured properly
|
||||
try {
|
||||
new Mailer(false);
|
||||
} catch(\Exception $e) {
|
||||
@ -24,59 +26,81 @@ class SendingQueue {
|
||||
);
|
||||
}
|
||||
|
||||
// check that the newsletter exists
|
||||
$newsletter = Newsletter::filter('filterWithOptions')
|
||||
->findOne($data['newsletter_id']);
|
||||
if(!$newsletter) {
|
||||
|
||||
if($newsletter === false) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'errors' => array(__('Newsletter does not exist.'))
|
||||
'errors' => array(__('This newsletter does not exist.'))
|
||||
);
|
||||
}
|
||||
|
||||
if($newsletter->type === Newsletter::TYPE_WELCOME) {
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'message' => __('Your welcome notification is activated.')
|
||||
)
|
||||
);
|
||||
// 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);
|
||||
}
|
||||
|
||||
$queue = \MailPoet\Models\SendingQueue::whereNull('status')
|
||||
$queue = SendingQueueModel::whereNull('status')
|
||||
->where('newsletter_id', $newsletter->id)
|
||||
->findOne();
|
||||
|
||||
if(!empty($queue)) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'errors' => array(__('Send operation is already in progress.'))
|
||||
'errors' => array(__('This newsletter is already being sent.'))
|
||||
);
|
||||
}
|
||||
|
||||
$queue = \MailPoet\Models\SendingQueue::where('status', 'scheduled')
|
||||
->where('newsletter_id', $newsletter->id)
|
||||
$queue = SendingQueueModel::where('newsletter_id', $newsletter->id)
|
||||
->where('status', SendingQueueModel::STATUS_SCHEDULED)
|
||||
->findOne();
|
||||
if(!$queue) {
|
||||
$queue = \MailPoet\Models\SendingQueue::create();
|
||||
$queue = SendingQueueModel::create();
|
||||
$queue->newsletter_id = $newsletter->id;
|
||||
}
|
||||
|
||||
if($newsletter->type === 'notification') {
|
||||
if($newsletter->type === Newsletter::TYPE_NOTIFICATION) {
|
||||
$queue->scheduled_at = Scheduler::getNextRunDate($newsletter->schedule);
|
||||
$queue->status = 'scheduled';
|
||||
$queue->status = SendingQueueModel::STATUS_SCHEDULED;
|
||||
$queue->save();
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'message' => __('Your post notifications are activated.')
|
||||
'message' => __('Your post notification has been activated.')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ((bool)$newsletter->isScheduled) {
|
||||
$queue->status = 'scheduled';
|
||||
if((bool)$newsletter->isScheduled) {
|
||||
// set newsletter status
|
||||
$newsletter->setStatus(Newsletter::STATUS_SCHEDULED);
|
||||
|
||||
// set queue status
|
||||
$queue->status = SendingQueueModel::STATUS_SCHEDULED;
|
||||
$queue->scheduled_at = Scheduler::scheduleFromTimestamp(
|
||||
$newsletter->scheduledAt
|
||||
);
|
||||
@ -104,6 +128,9 @@ class SendingQueue {
|
||||
);
|
||||
$queue->count_total = $queue->count_to_process = count($subscribers);
|
||||
|
||||
// set newsletter status
|
||||
$newsletter->setStatus(Newsletter::STATUS_SENDING);
|
||||
|
||||
$message = __('The newsletter is being sent...');
|
||||
}
|
||||
$queue->save();
|
||||
|
Reference in New Issue
Block a user