- Refactors Mailer class

- Refactors SendingQueue worker class
- Adds Maier router with a send() method + ability to specify sending method
- Updates tests
- Introduces 'stopping' and 'starting' cron states
- Improves cron control mechanism
Closes #276
This commit is contained in:
Vlad
2016-01-05 10:34:57 -05:00
parent 112fe0cd6e
commit f1bf2bb097
30 changed files with 1202 additions and 1433 deletions

View File

@ -15,10 +15,10 @@ define(
status: 'loading' status: 'loading'
}; };
}, },
getDaemonData: function() { getCronData: function() {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
endpoint: 'cron', endpoint: 'cron',
action: 'getDaemonStatus' action: 'getStatus'
}) })
.done(function(response) { .done(function(response) {
jQuery('.button-primary') jQuery('.button-primary')
@ -32,25 +32,23 @@ define(
}, },
componentDidMount: function() { componentDidMount: function() {
if(this.isMounted()) { if(this.isMounted()) {
this.getDaemonData(); this.getCronData();
setInterval(this.getDaemonData, 5000); setInterval(this.getCronData, 5000);
} }
}, },
controlDaemon: function(action) { controlCron: function(action) {
if (jQuery('.button-primary').hasClass('disabled')) {
return;
}
jQuery('.button-primary') jQuery('.button-primary')
.addClass('disabled'); .addClass('disabled');
MailPoet.Ajax.post({ MailPoet.Ajax.post({
endpoint: 'cron', endpoint: 'cron',
action: 'controlDaemon', action: action,
data: {
'action': action
}
}) })
.done(function(response) { .done(function(response) {
if(!response.result) { if(!response.result) {
//this.replaceState(); MailPoet.Notice.error(MailPoetI18n.daemonControlError);
} else {
//this.setState(response);
} }
}.bind(this)); }.bind(this));
}, },
@ -71,19 +69,25 @@ define(
<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.controlCron.bind(null, 'stop')}>Stop</a>
<a href="#" className="button-primary" onClick={this.controlDaemon.bind(null, 'pause')}>Pause</a> </div>
);
break;
case 'starting':
case 'stopping':
return(
<div>
Daemon is {this.state.status}
</div> </div>
); );
break; break;
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.controlCron.bind(null, 'start')}>Start</a>
</div> </div>
); );
break; break;

View File

@ -16,7 +16,7 @@ define(
Breadcrumb Breadcrumb
) { ) {
var settings = window.mailpoet_settings || {}; var settings = window.mailpoet_settings || {};
var fields = [ var fields = [
{ {
@ -24,14 +24,17 @@ define(
label: 'Subject line', label: 'Subject line',
tip: "Be creative! It's the first thing your subscribers see."+ tip: "Be creative! It's the first thing your subscribers see."+
"Tempt them to open your email.", "Tempt them to open your email.",
type: 'text' type: 'text',
validation: {
'data-parsley-required': true
}
}, },
{ {
name: 'segments', name: 'segments',
label: 'Lists', label: 'Segments',
tip: "The subscriber list that will be used for this campaign.", tip: "The subscriber segment that will be used for this campaign.",
type: 'selection', type: 'selection',
placeholder: "Select a list", placeholder: "Select a segment",
id: "mailpoet_segments", id: "mailpoet_segments",
endpoint: "segments", endpoint: "segments",
multiple: true, multiple: true,
@ -111,12 +114,19 @@ define(
action: 'add', action: 'add',
data: { data: {
newsletter_id: this.props.params.id, newsletter_id: this.props.params.id,
segments: jQuery('#mailpoet_segments').val() segments: jQuery('#mailpoet_segments').val(),
sender: {
'name': jQuery('#mailpoet_newsletter [name="sender_name"]').val(),
'address': jQuery('#mailpoet_newsletter [name="sender_address"]').val()
},
reply_to: {
'name': jQuery('#mailpoet_newsletter [name="reply_to_name"]').val(),
'address': jQuery('#mailpoet_newsletter [name="reply_to_address"]').val()
}
} }
}).done(function(response) { }).done(function(response) {
if(response.result === true) { if(response.result === true) {
this.history.pushState(null, '/'); this.history.pushState(null, '/');
MailPoet.Notice.success( MailPoet.Notice.success(
'The newsletter is being sent...' 'The newsletter is being sent...'
); );

View File

@ -75,7 +75,7 @@ class Initializer {
define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field); define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
define('MP_NEWSLETTER_OPTION_FIELDS_TABLE', $newsletter_option_fields); define('MP_NEWSLETTER_OPTION_FIELDS_TABLE', $newsletter_option_fields);
define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option); define('MP_NEWSLETTER_OPTION_TABLE', $newsletter_option);
define('MP_SENDING_QUEUE_TABLE', $sending_queues); define('MP_SENDING_QUEUES_TABLE', $sending_queues);
define('MP_NEWSLETTER_STATISTICS_TABLE', $newsletter_statistics); define('MP_NEWSLETTER_STATISTICS_TABLE', $newsletter_statistics);
} }
@ -113,7 +113,6 @@ class Initializer {
} }
function setupAnalytics() { function setupAnalytics() {
$widget = new Analytics(); $widget = new Analytics();
$widget->init(); $widget->init();
} }
@ -143,10 +142,12 @@ class Initializer {
} }
function runQueueSupervisor() { function runQueueSupervisor() {
if (php_sapi_name() === 'cli') return;
try { try {
$supervisor = new Supervisor(); $supervisor = new Supervisor();
$supervisor->checkDaemon(); $supervisor->checkDaemon();
} catch (\Exception $e) {} } catch (\Exception $e) {
}
} }
function setupImages() { function setupImages() {

View File

@ -8,14 +8,14 @@ if(!defined('ABSPATH')) exit;
class PublicAPI { class PublicAPI {
function __construct() { function __construct() {
# http://example.com/?mailpoet-api&section=&action=&payload= # http://example.com/?mailpoet-api&section=&action=&request_payload=
$this->api = isset($_GET['mailpoet-api']) ? true : false; $this->api = isset($_GET['mailpoet-api']) ? true : false;
$this->section = isset($_GET['section']) ? $_GET['section'] : false; $this->section = isset($_GET['section']) ? $_GET['section'] : false;
$this->action = isset($_GET['action']) ? $this->action = isset($_GET['action']) ?
Helpers::underscoreToCamelCase($_GET['action']) : Helpers::underscoreToCamelCase($_GET['action']) :
false; false;
$this->payload = isset($_GET['payload']) ? $this->requestPayload = isset($_GET['request_payload']) ?
json_decode(urldecode($_GET['payload']), true) : json_decode(urldecode($_GET['request_payload']), true) :
false; false;
} }
@ -26,10 +26,9 @@ class PublicAPI {
function queue() { function queue() {
try { try {
$queue = new Daemon($this->payload); $queue = new Daemon($this->requestPayload);
$this->_checkAndCallMethod($queue, $this->action); $this->_checkAndCallMethod($queue, $this->action);
} catch(\Exception $e) { } catch(\Exception $e) {
// mailer configuration error
} }
} }

View File

@ -10,18 +10,18 @@ require_once(ABSPATH . 'wp-includes/pluggable.php');
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Daemon { class Daemon {
function __construct($payload = array()) { function __construct($requestPayload = array()) {
set_time_limit(0); set_time_limit(0);
ignore_user_abort(); ignore_user_abort();
list ($this->daemon, $this->daemonData) = $this->getDaemon(); list ($this->daemon, $this->daemonData) = $this->getDaemon();
$this->refreshedToken = $this->refreshToken(); $this->refreshedToken = $this->refreshToken();
$this->payload = $payload; $this->requestPayload = $requestPayload;
$this->timer = microtime(true); $this->timer = microtime(true);
} }
function start() { function start() {
if(!isset($this->payload['session'])) { if(!isset($this->requestPayload['session'])) {
$this->abortWithError('missing session ID'); $this->abortWithError(__('Missing session ID.'));
} }
$this->manageSession('start'); $this->manageSession('start');
$daemon = $this->daemon; $daemon = $this->daemon;
@ -30,58 +30,63 @@ class Daemon {
$daemon = Setting::create(); $daemon = Setting::create();
$daemon->name = 'cron_daemon'; $daemon->name = 'cron_daemon';
$daemonData = array( $daemonData = array(
'status' => null, 'status' => 'starting',
'counter' => 0 'counter' => 0
); );
$daemon->value = json_encode($daemonData); $daemon->value = json_encode($daemonData);
$daemon->save(); $daemon->save();
} }
if($daemonData['status'] !== 'started') { if($daemonData['status'] === 'started') {
$_SESSION['cron_daemon'] = array(
'result' => false,
'errors' => array(__('Daemon already running.'))
);
}
if($daemonData['status'] === 'starting') {
$_SESSION['cron_daemon'] = 'started'; $_SESSION['cron_daemon'] = 'started';
$_SESSION['cron_daemon'] = array('result' => true);
$daemonData['status'] = 'started'; $daemonData['status'] = 'started';
$daemonData['token'] = $this->refreshedToken; $daemonData['token'] = $this->refreshedToken;
$_SESSION['cron_daemon'] = array('result' => true);
$this->manageSession('end'); $this->manageSession('end');
$daemon->value = json_encode($daemonData); $daemon->value = json_encode($daemonData);
$daemon->save(); $daemon->save();
$this->callSelf(); $this->callSelf();
} else {
$_SESSION['cron_daemon'] = array(
'result' => false,
'error' => 'already started'
);
} }
$this->manageSession('end'); $this->manageSession('end');
} }
function run() { function run() {
if(!$this->daemon || $this->daemonData['status'] !== 'started') { $allowedStatuses = array(
$this->abortWithError('not running'); 'stopping',
'starting',
'started'
);
if(!$this->daemon || !in_array($this->daemonData['status'], $allowedStatuses)) {
$this->abortWithError(__('Invalid daemon status.'));
} }
if(!isset($this->payload['token']) || if(!isset($this->requestPayload['token']) ||
$this->payload['token'] !== $this->daemonData['token'] $this->requestPayload['token'] !== $this->daemonData['token']
) { ) {
$this->abortWithError('invalid token'); $this->abortWithError('Invalid token.');
} }
try { try {
$sendingQueue = new SendingQueue($this->timer); $sendingQueue = new SendingQueue($this->timer);
$sendingQueue->process(); $sendingQueue->process();
} catch(Exception $e) { } catch(Exception $e) {
} }
$elapsedTime = microtime(true) - $this->timer; $elapsedTime = microtime(true) - $this->timer;
if($elapsedTime < 30) { if($elapsedTime < 30) {
sleep(30 - $elapsedTime); sleep(30 - $elapsedTime);
} }
// after each execution, read daemon in case it's status was modified // after each execution, read daemon in case it's status was modified
list($daemon, $daemonData) = $this->getDaemon(); list($daemon, $daemonData) = $this->getDaemon();
$daemonData['counter']++; if($daemonData['status'] === 'stopping') $daemonData['status'] = 'stopped';
if($daemonData['status'] === 'starting') $daemonData['status'] = 'started';
$daemonData['token'] = $this->refreshedToken; $daemonData['token'] = $this->refreshedToken;
$daemonData['counter']++;
$daemon->value = json_encode($daemonData); $daemon->value = json_encode($daemonData);
$daemon->save(); $daemon->save();
if($daemonData['status'] === 'strated') $this->callSelf(); if($daemonData['status'] === 'started') $this->callSelf();
} }
function getDaemon() { function getDaemon() {
@ -103,7 +108,7 @@ class Daemon {
if(session_id()) { if(session_id()) {
session_write_close(); session_write_close();
} }
session_id($this->payload['session']); session_id($this->requestPayload['session']);
session_start(); session_start();
break; break;
case 'end': case 'end':
@ -114,9 +119,8 @@ class Daemon {
function callSelf() { function callSelf() {
$payload = json_encode(array('token' => $this->refreshedToken)); $payload = json_encode(array('token' => $this->refreshedToken));
Supervisor::getRemoteUrl( Supervisor::accessRemoteUrl(
'/?mailpoet-api&section=queue&action=run&payload=' . urlencode($payload) '/?mailpoet-api&section=queue&action=run&request_payload=' . urlencode($payload)
); );
exit; exit;
} }
@ -125,7 +129,7 @@ class Daemon {
wp_send_json( wp_send_json(
array( array(
'result' => false, 'result' => false,
'error' => $error 'errors' => array($error)
)); ));
exit; exit;
} }

View File

@ -11,7 +11,7 @@ class Supervisor {
function __construct($forceStart = false) { function __construct($forceStart = false) {
$this->forceStart = $forceStart; $this->forceStart = $forceStart;
if(!Env::isPluginActivated()) { if(!Env::isPluginActivated()) {
throw new \Exception('Database has not been configured.'); throw new \Exception(__('MailPoet is not activated.'));
} }
list ($this->daemon, $this->daemonData) = $this->getDaemon(); list ($this->daemon, $this->daemonData) = $this->getDaemon();
} }
@ -20,17 +20,24 @@ class Supervisor {
if(!$this->daemon) { if(!$this->daemon) {
return $this->startDaemon(); return $this->startDaemon();
} }
if(!$this->forceStart && $this->daemonData['status'] === 'stopped') { if(!$this->forceStart && (
$this->daemonData['status'] === 'stopped' ||
$this->daemonData['status'] === 'stopping')
) {
return $this->daemonData['status'];
}
$timeSinceLastRun = $this->getDaemonLastRunTime();
if($timeSinceLastRun < 40) {
if(!$this->forceStart) {
return; return;
} }
$currentTime = Carbon::now('UTC'); if($this->daemonData['status'] === 'stopping' ||
$lastUpdateTime = Carbon::createFromFormat( $this->daemonData['status'] === 'starting'
'Y-m-d H:i:s', ) {
$this->daemon->updated_at, 'UTC' return $this->daemonData['status'];
); }
$timeSinceLastStart = $currentTime->diffInSeconds($lastUpdateTime); }
if($timeSinceLastStart < 40) return; $this->daemonData['status'] = 'starting';
$this->daemonData['status'] = null;
$this->daemon->value = json_encode($this->daemonData); $this->daemon->value = json_encode($this->daemonData);
$this->daemon->save(); $this->daemon->save();
return $this->startDaemon(); return $this->startDaemon();
@ -41,9 +48,9 @@ class Supervisor {
$sessionId = session_id(); $sessionId = session_id();
session_write_close(); session_write_close();
$_SESSION['cron_daemon'] = null; $_SESSION['cron_daemon'] = null;
$payload = json_encode(array('session' => $sessionId)); $requestPayload = json_encode(array('session' => $sessionId));
self::getRemoteUrl( self::accessRemoteUrl(
'/?mailpoet-api&section=queue&action=start&payload=' . urlencode($payload) '/?mailpoet-api&section=queue&action=start&request_payload=' . urlencode($requestPayload)
); );
session_start(); session_start();
$daemonStatus = $_SESSION['cron_daemon']; $daemonStatus = $_SESSION['cron_daemon'];
@ -62,10 +69,10 @@ class Supervisor {
); );
} }
static function getRemoteUrl($url) { static function accessRemoteUrl($url) {
$args = array( $args = array(
'timeout' => 1, 'timeout' => 1,
'user-agent' => 'MailPoet (www.mailpoet.com)' 'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
); );
wp_remote_get( wp_remote_get(
self::getSiteUrl() . $url, self::getSiteUrl() . $url,
@ -74,11 +81,28 @@ class Supervisor {
} }
static function getSiteUrl() { static function getSiteUrl() {
if(preg_match('!:\d+/!', site_url())) return site_url(); // additional check for some sites running on a virtual machine or behind
preg_match('!http://(?P<host>.*?):(?P<port>\d+)!', site_url(), $server); // proxy where there could be different ports (e.g., host:8080 => guest:80)
// if the site URL does not contain a port, return the URL
if(!preg_match('!^https?://.*?:\d+!', site_url())) return site_url();
preg_match('!://(?P<host>.*?):(?P<port>\d+)!', site_url(), $server);
// connect to the URL with port
$fp = @fsockopen($server['host'], $server['port'], $errno, $errstr, 1); $fp = @fsockopen($server['host'], $server['port'], $errno, $errstr, 1);
return ($fp) ? if($fp) return site_url();
site_url() : // connect to the URL without port
preg_replace('/(?=:\d+):\d+/', '$1', site_url()); $fp = @fsockopen($server['host'], $server['port'], $errno, $errstr, 1);
if($fp) return preg_replace('!(?=:\d+):\d+!', '$1', site_url());
// throw an error if all connections fail
throw new \Exception(__('Site URL is unreachable.'));
}
function getDaemonLastRunTime() {
$currentTime = Carbon::now('UTC');
$lastUpdateTime = Carbon::createFromFormat(
'Y-m-d H:i:s',
$this->daemon->updated_at, 'UTC'
);
return $currentTime->diffInSeconds($lastUpdateTime);
} }
} }

View File

@ -1,11 +1,11 @@
<?php <?php
namespace MailPoet\Cron\Workers; namespace MailPoet\Cron\Workers;
use MailPoet\Mailer\Mailer;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterStatistics; use MailPoet\Models\NewsletterStatistics;
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
use MailPoet\Newsletter\Renderer\Renderer; use MailPoet\Newsletter\Renderer\Renderer;
use MailPoet\Router\Mailer;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@ -15,75 +15,58 @@ class SendingQueue {
} }
function process() { function process() {
$queues = foreach($this->getQueues() as $queue) {
\MailPoet\Models\SendingQueue::orderByDesc('priority') $newsletter = Newsletter::findOne($queue->newsletter_id)
->whereNull('deleted_at') ->asArray();
->whereNull('status')
->findResultSet();
foreach($queues as $queue) {
$newsletter = Newsletter::findOne($queue->newsletter_id);
if(!$newsletter) { if(!$newsletter) {
continue; continue;
}; };
$newsletter = $newsletter->asArray(); $newsletter = $this->renderNewsletter($newsletter);
$mailer = new Mailer($httpRequest = false); $mailer = $this->configureMailerForNewsletter($newsletter);
if(!empty($newsletter['sender_address']) &&
!empty($newsletter['sender_name'])
) {
$mailer->fromName = $newsletter['sender_name'];
$mailer->fromEmail = $newsletter['sender_address'];
$mailer->fromNameEmail = sprintf(
'%s <%s>',
$mailer->fromName,
$mailer->fromEmail
);
}
if(!empty($newsletter['reply_to_address']) &&
!empty($newsletter['reply_to_name'])
) {
$mailer->replyToName = $newsletter['reply_to_name'];
$mailer->replyToEmail = $newsletter['reply_to_address'];
$mailer->replyToNameEmail = sprintf(
'%s <%s>',
$mailer->replyToName,
$mailer->replyToEmail
);
}
$mailer->mailer = $mailer->buildMailer();
$renderer = new Renderer(json_decode($newsletter['body'], true));
$newsletter = array(
'subject' => $newsletter['subject'],
'id' => $newsletter['id'],
'body' => array(
'html' => $renderer->renderAll(),
'text' => ''
// TODO: add text body
)
);
$subscribers = json_decode($queue->subscribers, true); $subscribers = json_decode($queue->subscribers, true);
$subscribersToProcess = $subscribers['to_process']; $subscribersToProcess = $subscribers['to_process'];
if(!isset($subscribers['failed'])) $subscribers['failed'] = array();
if(!isset($subscribers['processed'])) $subscribers['processed'] = array(); if(!isset($subscribers['processed'])) $subscribers['processed'] = array();
if(!isset($subscribers['failed'])) $subscribers['failed'] = array();
foreach(array_chunk($subscribersToProcess, 200) as $subscriberIds) { foreach(array_chunk($subscribersToProcess, 200) as $subscriberIds) {
$dbSubscribers = Subscriber::whereIn('id', $subscriberIds) $dbSubscribers = Subscriber::whereIn('id', $subscriberIds)
->findArray(); ->findArray();
foreach($dbSubscribers as $i => $dbSubscriber) { foreach($dbSubscribers as $dbSubscriber) {
$this->checkExecutionTimer(); $this->checkExecutionTimer();
// TODO: replace shortcodes in the newsletter $result = $this->sendNewsletter(
$result = $mailer->mailer->send( $mailer,
$newsletter, $this->processNewsletter($newsletter),
$mailer->transformSubscriber($dbSubscriber) $dbSubscriber);
);
$newsletterStatistics = NewsletterStatistics::create();
$newsletterStatistics->subscriber_id = $dbSubscriber['id'];
$newsletterStatistics->newsletter_id = $newsletter['id'];
$newsletterStatistics->queue_id = $queue->id;
$newsletterStatistics->save();
if($result) { if($result) {
$this->updateStatistics($newsletter['id'], $dbSubscriber['id'], $queue->id);
$subscribers['processed'][] = $dbSubscriber['id']; $subscribers['processed'][] = $dbSubscriber['id'];
} else { } else $subscribers['failed'][] = $dbSubscriber['id'];
$subscribers['failed'][] = $dbSubscriber['id']; $this->updateQueue($queue, $subscribers);
} }
}
}
}
function processNewsletter($newsletter) {
// TODO: replace shortcodes, etc..
return $newsletter;
}
function sendNewsletter($mailer, $newsletter, $subscriber) {
return $mailer->mailerInstance->send(
$newsletter,
$mailer->transformSubscriber($subscriber)
);
}
function updateStatistics($newsletterId, $subscriberId, $queueId) {
$newsletterStatistics = NewsletterStatistics::create();
$newsletterStatistics->subscriber_id = $newsletterId;
$newsletterStatistics->newsletter_id = $subscriberId;
$newsletterStatistics->queue_id = $queueId;
$newsletterStatistics->save();
}
function updateQueue($queue, $subscribers) {
$subscribers['to_process'] = array_values( $subscribers['to_process'] = array_values(
array_diff( array_diff(
$subscribers['to_process'], $subscribers['to_process'],
@ -103,12 +86,39 @@ class SendingQueue {
$queue->subscribers = json_encode($subscribers); $queue->subscribers = json_encode($subscribers);
$queue->save(); $queue->save();
} }
}
} function configureMailerForNewsletter($newsletter) {
if(!empty($newsletter['sender_address']) && !empty($newsletter['sender_name'])) {
$sender = array(
'name' => $newsletter['sender_name'],
'address' => $newsletter['sender_address']
);
} else $sender = false;
if(!empty($newsletter['reply_to_address']) && !empty($newsletter['reply_to_name'])) {
$replyTo = array(
'name' => $newsletter['reply_to_name'],
'address' => $newsletter['reply_to_address']
);
} else $replyTo = false;
$mailer = new Mailer($method = false, $sender, $replyTo);
return $mailer;
} }
function checkExecutionTimer() { function checkExecutionTimer() {
$elapsedTime = microtime(true) - $this->timer; $elapsedTime = microtime(true) - $this->timer;
if($elapsedTime >= 28) throw new \Exception('Maximum execution time reached.'); if($elapsedTime >= 30) throw new \Exception('Maximum execution time reached.');
}
function getQueues() {
return \MailPoet\Models\SendingQueue::orderByDesc('priority')
->whereNull('deleted_at')
->whereNull('status')
->findResultSet();
}
function renderNewsletter($newsletter) {
$renderer = new Renderer(json_decode($newsletter['body'], true));
$newsletter['body'] = $renderer->renderAll();
return $newsletter;
} }
} }

141
lib/Mailer/Mailer.php Normal file
View File

@ -0,0 +1,141 @@
<?php
namespace MailPoet\Mailer;
use MailPoet\Models\Setting;
require_once(ABSPATH . 'wp-includes/pluggable.php');
if(!defined('ABSPATH')) exit;
class Mailer {
function __construct($mailer = false, $sender = false, $reply_to = false) {
$this->mailer = $this->getMailer($mailer);
$this->sender = $this->getSender($sender);
$this->replyTo = $this->getReplyTo($reply_to);
$this->mailerInstance = $this->buildMailer();
}
function send($newsletter, $subscriber) {
$subscriber = $this->transformSubscriber($subscriber);
return $this->mailerInstance->send($newsletter, $subscriber);
}
function buildMailer() {
switch($this->mailer['method']) {
case 'AmazonSES':
$mailerInstance = new $this->mailer['class'](
$this->mailer['region'],
$this->mailer['access_key'],
$this->mailer['secret_key'],
$this->sender['fromNameEmail']
);
break;
case 'ElasticEmail':
$mailerInstance = new $this->mailer['class'](
$this->mailer['api_key'],
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
case 'MailGun':
$mailerInstance = new $this->mailer['class'](
$this->mailer['domain'],
$this->mailer['api_key'],
$this->sender['fromNameEmail']
);
break;
case 'MailPoet':
$mailerInstance = new $this->mailer['class'](
$this->mailer['mailpoet_api_key'],
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
case 'Mandrill':
$mailerInstance = new $this->mailer['class'](
$this->mailer['api_key'],
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
case 'SendGrid':
$mailerInstance = new $this->mailer['class'](
$this->mailer['api_key'],
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
case 'WPMail':
$mailerInstance = new $this->mailer['class'](
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
case 'SMTP':
$mailerInstance = new $this->mailer['class'](
$this->mailer['host'],
$this->mailer['port'],
$this->mailer['authentication'],
$this->mailer['login'],
$this->mailer['password'],
$this->mailer['encryption'],
$this->sender['fromEmail'],
$this->sender['fromName']
);
break;
default:
throw new \Exception(__('Mailing method does not exist.'));
break;
}
return $mailerInstance;
}
function getMailer($mailer = false) {
if(!$mailer) {
$mailer = Setting::getValue('mta', null);
if(!$mailer || !isset($mailer['method'])) throw new \Exception(__('Mailer is not configured.'));
}
$mailer['class'] = 'MailPoet\\Mailer\\Methods\\' . $mailer['method'];
return $mailer;
}
function getSender($sender = false) {
if(!$sender) {
$sender = Setting::getValue('sender', null);
if(!$sender) throw new \Exception(__('Sender name and email are not configured.'));
}
return array(
'fromName' => $sender['name'],
'fromEmail' => $sender['address'],
'fromNameEmail' => sprintf('%s <%s>', $sender['name'], $sender['address'])
);
}
function getReplyTo($replyTo = false) {
if(!$replyTo) {
$replyTo = Setting::getValue('replyTo', null);
if(!$replyTo) {
$replyTo = array(
'name' => $this->sender['fromName'],
'address' => $this->sender['fromEmail']
);
}
}
return array(
'replyToName' => $replyTo['name'],
'replyToEmail' => $replyTo['address'],
'replyToNameEmail' => sprintf('%s <%s>', $replyTo['name'], $replyTo['address'])
);
}
function transformSubscriber($subscriber) {
if(!is_array($subscriber)) return $subscriber;
if(isset($subscriber['address'])) $subscriber['email'] = $subscriber['address'];
$first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : '';
$last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : '';
if(!$first_name && !$last_name) return $subscriber['email'];
$subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']);
$subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber));
return $subscriber;
}
}

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer\API; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer\API; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer\API; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer\API; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace MailPoet\Mailer\API; namespace MailPoet\Mailer\Methods;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -1,5 +1,6 @@
<?php <?php
namespace MailPoet\Mailer; namespace MailPoet\Mailer\Methods;
require_once(ABSPATH . 'wp-includes/pluggable.php'); require_once(ABSPATH . 'wp-includes/pluggable.php');
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -4,7 +4,7 @@ namespace MailPoet\Models;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class SendingQueue extends Model { class SendingQueue extends Model {
public static $_table = MP_SENDING_QUEUE_TABLE; public static $_table = MP_SENDING_QUEUES_TABLE;
function __construct() { function __construct() {
parent::__construct(); parent::__construct();

View File

@ -1,36 +1,29 @@
<?php <?php
namespace MailPoet\Router; namespace MailPoet\Router;
use MailPoet\Models\Segment; use MailPoet\Cron\Daemon;
use MailPoet\Models\SendingQueue; use MailPoet\Cron\Supervisor;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Cron { class Cron {
function controlDaemon($data) { function start() {
switch($data['action']) { $supervisor = new Supervisor($forceStart = true);
case 'start':
$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;
case 'stop':
$status = 'stopped';
break;
default:
$status = 'paused';
break;
} }
$daemon = new \MailPoet\Cron\Daemon();
if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') { function stop() {
$daemon = new Daemon();
if(!$daemon->daemon ||
$daemon->daemonData['status'] !== 'started'
) {
$result = false; $result = false;
} else { } else {
$daemon->daemonData['status'] = $status; $daemon->daemonData['status'] = 'stopping';
$daemon->daemon->value = json_encode($daemon->daemonData); $daemon->daemon->value = json_encode($daemon->daemonData);
$result = $daemon->daemon->save(); $result = $daemon->daemon->save();
} }
@ -41,153 +34,8 @@ class Cron {
); );
} }
function getDaemonStatus() { function getStatus() {
$daemon = new \MailPoet\Cron\BootStrapMenu(); $daemon = new \MailPoet\Cron\BootStrapMenu();
wp_send_json($daemon->bootStrap()); wp_send_json($daemon->bootStrap());
} }
function addQueue($data) {
$queue = SendingQueue::where('newsletter_id', $data['newsletter_id'])
->whereNull('status')
->findArray();
!d($queue);
exit;
$queue = SendingQueue::create();
$queue->newsletter_id = $data['newsletter_id'];
$subscriber_ids = array();
$segments = Segment::whereIn('id', $data['segments'])
->findMany();
foreach($segments as $segment) {
$subscriber_ids = array_merge($subscriber_ids, Helpers::arrayColumn(
$segment->subscribers()
->findArray(),
'id'
));
}
$subscriber_ids = array_unique($subscriber_ids);
$queue->subscribers = json_encode(
array(
'to_process' => $subscriber_ids
)
);
$queue->count_total = $queue->count_to_process = count($subscriber_ids);
$queue->save();
wp_send_json(
!$queue->save() ?
array(
'result' => false,
'error' => 'Queue could not be created.'
) :
array(
'result' => true,
'data' => array($queue->id)
)
);
}
function addQueues($data) {
$result = array_map(function ($queueData) {
$queue = SendingQueue::create();
$queue->newsletter_id = $queueData['newsletter_id'];
$queue->subscribers = json_encode(
array(
'to_process' => $queueData['subscribers']
)
);
$queue->count_total = $queue->count_to_process = count($queueData['subscribers']);
$queue->save();
return array(
'newsletter_id' => $queue->newsletter_id,
'queue_id' => $queue->id
);
}, $data);
$result = Helpers::arrayColumn($result, 'queue_id', 'newsletter_id');
wp_send_json(
count($data) != count($result) ?
array(
'result' => false,
'error' => __('Some queues could not be created.'),
'data' => $result
) :
array(
'result' => true,
'data' => $result
)
);
}
function deleteQueue($data) {
$queue = SendingQueue::whereNull('deleted_at')
->findOne($data['queue_id']);
if(!$queue) {
wp_send_json(
array(
'result' => false,
'error' => __('Queue not found.')
)
);
}
$queue->deleted_at = 'Y-m-d H:i:s';
$queue->save();
wp_send_json(array('result' => true));
}
function deleteQueues($data) {
$queues = SendingQueue::whereNull('deleted_at')
->whereIn('id', $data['queue_ids'])
->findResultSet();
if(!$queues->count()) {
wp_send_json(
array(
'result' => false,
'error' => __('Queues not found.')
)
);
}
foreach($queues as $queue) {
$queue->deleted_at = 'Y-m-d H:i:s';
$queue->save();
}
wp_send_json(array('result' => true));
}
function getQueueStatus($data) {
$queue = SendingQueue::whereNull('deleted_at')
->findOne($data['queue_id'])
->asArray();
wp_send_json(
!$queue ?
array(
'result' => false,
'error' => __('Queue not found.')
) :
array(
'result' => true,
'data' => $queue
)
);
}
function getQueuesStatus($data) {
$queues = SendingQueue::whereNull('deleted_at')
->whereIn('id', $data['queue_ids'])
->findArray();
wp_send_json(
!$queues ?
array(
'result' => false,
'error' => __('Queue not found.')
) :
array(
'result' => true,
'data' => $queues
)
);
}
} }

View File

@ -1,191 +1,20 @@
<?php <?php
namespace MailPoet\Router; namespace MailPoet\Router;
use MailPoet\Models\Setting;
require_once(ABSPATH . 'wp-includes/pluggable.php');
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Mailer { class Mailer {
function __construct($httpRequest = true) {
$this->mailerType = array(
'AmazonSES' => 'API',
'ElasticEmail' => 'API',
'MailGun' => 'API',
'Mandrill' => 'API',
'SendGrid' => 'API',
'MailPoet' => null,
'SMTP' => null,
'WPMail' => null
);
if(!$httpRequest) {
list($this->fromName, $this->fromEmail, $this->fromNameEmail)
= $this->getSetting('sender');
$this->mailer = $this->getSetting('mailer');
}
}
function send($data) { function send($data) {
$subscriber = $this->transformSubscriber($data['subscriber']); $mailer = new \MailPoet\Mailer\Mailer(
list($fromName, $fromEmail, $fromNameEmail) (isset($data['mailer'])) ? $data['mailer'] : false,
= $this->getSetting('sender'); (isset($data['sender'])) ? $data['sender'] : false,
if(!$fromName && !$fromEmail) { (isset($data['reply_to'])) ? $data['reply_to'] : false
wp_send_json(
array(
'result' => false,
'errors' => array(__('Please configure your name and e-mail address.'))
)
); );
} $result = $mailer->send($data['newsletter'], $data['subscriber']);
$data['mailer']['class'] = 'MailPoet\\Mailer\\' .
(($this->mailerType[$data['mailer']['method']]) ?
$this->mailerType[$data['mailer']['method']] . '\\' . $data['mailer']['method'] :
$data['mailer']['method']
);
$mailer = $this->buildMailer(
$data['mailer'],
$fromName,
$fromEmail,
$fromNameEmail
);
if(!empty($newsletter['sender_address']) &&
!empty($newsletter['sender_name'])
) {
$mailer->fromName = $newsletter['sender_name'];
$mailer->fromEmail = $newsletter['sender_address'];
$mailer->fromNameEmail = sprintf(
'%s <%s>',
$mailer->fromName,
$mailer->fromEmail
);
}
if(!empty($newsletter['reply_to_address']) &&
!empty($newsletter['reply_to_name'])
) {
$mailer->replyToName = $newsletter['reply_to_name'];
$mailer->replyToEmail = $newsletter['reply_to_address'];
$mailer->replyToNameEmail = sprintf(
'%s <%s>',
$mailer->replyToName,
$mailer->replyToEmail
);
}
$result = $mailer->send($data['newsletter'], $subscriber);
wp_send_json( wp_send_json(
array( array(
'result' => ($result) ? true : false 'result' => ($result) ? true : false
) )
); );
} }
function buildMailer($mailer = false, $fromName = false, $fromEmail = false, $fromNameEmail = false) {
if(!$mailer) $mailer = $this->mailer;
if(!$fromName) $fromName = $this->fromName;
if(!$fromEmail) $fromEmail = $this->fromEmail;
if(!$fromNameEmail) $fromNameEmail = $this->fromNameEmail;
switch($mailer['method']) {
case 'AmazonSES':
$mailerInstance = new $mailer['class'](
$mailer['region'],
$mailer['access_key'],
$mailer['secret_key'],
$fromNameEmail
);
break;
case 'ElasticEmail':
$mailerInstance = new $mailer['class'](
$mailer['api_key'],
$fromEmail, $fromName
);
break;
case 'MailGun':
$mailerInstance = new $mailer['class'](
$mailer['domain'],
$mailer['api_key'],
$fromNameEmail
);
break;
case 'MailPoet':
$mailerInstance = new $mailer['class'](
$mailer['mailpoet_api_key'],
$fromEmail,
$fromName
);
break;
case 'Mandrill':
$mailerInstance = new $mailer['class'](
$mailer['api_key'],
$fromEmail, $fromName
);
break;
case 'SendGrid':
$mailerInstance = new $mailer['class'](
$mailer['api_key'],
$fromEmail,
$fromName
);
break;
case 'WPMail':
$mailerInstance = new $mailer['class'](
$fromEmail,
$fromName
);
break;
case 'SMTP':
$mailerInstance = new $mailer['class'](
$mailer['host'],
$mailer['port'],
$mailer['authentication'],
$mailer['login'],
$mailer['password'],
$mailer['encryption'],
$fromEmail,
$fromName
);
break;
default:
throw new \Exception('Mailing method does not exist.');
break;
}
return $mailerInstance;
}
function transformSubscriber($subscriber) {
if(!is_array($subscriber)) return $subscriber;
if(isset($subscriber['address'])) $subscriber['email'] = $subscriber['address'];
$first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : '';
$last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : '';
if(!$first_name && !$last_name) return $subscriber['email'];
$subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']);
$subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber));
return $subscriber;
}
function getSetting($setting) {
switch($setting) {
case 'mailer':
$mailer = Setting::getValue('mta', null);
if(!$mailer || !isset($mailer['method'])) throw new \Exception('Mailing method is not configured.');
$mailer['class'] = 'MailPoet\\Mailer\\' .
(($this->mailerType[$mailer['method']]) ?
$this->mailerType[$mailer['method']] . '\\' . $mailer['method'] :
$mailer['method']
);
return $mailer;
break;
case 'sender':
$sender = Setting::getValue($setting, null);
if(!$sender) throw new \Exception('Sender name and email are not configured.');
return array(
$sender['name'],
$sender['address'],
sprintf('%s <%s>', $sender['name'], $sender['address'])
);
break;
default:
return Setting::getValue($setting, null);
break;
}
}
} }

View File

@ -1,196 +0,0 @@
<?php
namespace MailPoet\Router;
use MailPoet\Models\Segment;
use MailPoet\Models\SendingQueue;
use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit;
class Queue {
function controlDaemon($data) {
switch($data['action']) {
case 'start':
$supervisor = new Supervisor($forceStart = true);
wp_send_json(
array(
'result' => $supervisor->checkDaemon() ?
true :
false
)
);
break;
case 'stop':
$status = 'stopped';
break;
default:
$status = 'paused';
break;
}
$daemon = new Daemon();
if(!$daemon->daemon || $daemon->daemonData['status'] !== 'started') {
$result = false;
} else {
$daemon->daemonData['status'] = $status;
$daemon->daemon->value = json_encode($daemon->daemonData);
$result = $daemon->daemon->save();
}
wp_send_json(
array(
'result' => $result
)
);
}
function getDaemonStatus() {
$daemon = new \MailPoet\Cron\BootStrapMenu();
wp_send_json($daemon->bootStrap());
}
function addQueue($data) {
$queue = SendingQueue::where('newsletter_id', $data['newsletter_id'])
->whereNull('status')
->findArray();
!d($queue);
exit;
$queue = SendingQueue::create();
$queue->newsletter_id = $data['newsletter_id'];
$subscriber_ids = array();
$segments = Segment::whereIn('id', $data['segments'])
->findMany();
foreach($segments as $segment) {
$subscriber_ids = array_merge($subscriber_ids, Helpers::arrayColumn(
$segment->subscribers()
->findArray(),
'id'
));
}
$subscriber_ids = array_unique($subscriber_ids);
$queue->subscribers = json_encode(
array(
'to_process' => $subscriber_ids
)
);
$queue->count_total = $queue->count_to_process = count($subscriber_ids);
$queue->save();
wp_send_json(
!$queue->save() ?
array(
'result' => false,
'error' => 'Queue could not be created.'
) :
array(
'result' => true,
'data' => array($queue->id)
)
);
}
function addQueues($data) {
$result = array_map(function ($queueData) {
$queue = SendingQueue::create();
$queue->newsletter_id = $queueData['newsletter_id'];
$queue->subscribers = json_encode(
array(
'to_process' => $queueData['subscribers']
)
);
$queue->count_total = $queue->count_to_process = count($queueData['subscribers']);
$queue->save();
return array(
'newsletter_id' => $queue->newsletter_id,
'queue_id' => $queue->id
);
}, $data);
$result = Helpers::arrayColumn($result, 'queue_id', 'newsletter_id');
wp_send_json(
count($data) != count($result) ?
array(
'result' => false,
'error' => __('Some queues could not be created.'),
'data' => $result
) :
array(
'result' => true,
'data' => $result
)
);
}
function deleteQueue($data) {
$queue = SendingQueue::whereNull('deleted_at')
->findOne($data['queue_id']);
if(!$queue) {
wp_send_json(
array(
'result' => false,
'error' => __('Queue not found.')
)
);
}
$queue->deleted_at = 'Y-m-d H:i:s';
$queue->save();
wp_send_json(array('result' => true));
}
function deleteQueues($data) {
$queues = SendingQueue::whereNull('deleted_at')
->whereIn('id', $data['queue_ids'])
->findResultSet();
if(!$queues->count()) {
wp_send_json(
array(
'result' => false,
'error' => __('Queues not found.')
)
);
}
foreach($queues as $queue) {
$queue->deleted_at = 'Y-m-d H:i:s';
$queue->save();
}
wp_send_json(array('result' => true));
}
function getQueueStatus($data) {
$queue = SendingQueue::whereNull('deleted_at')
->findOne($data['queue_id'])
->asArray();
wp_send_json(
!$queue ?
array(
'result' => false,
'error' => __('Queue not found.')
) :
array(
'result' => true,
'data' => $queue
)
);
}
function getQueuesStatus($data) {
$queues = SendingQueue::whereNull('deleted_at')
->whereIn('id', $data['queue_ids'])
->findArray();
wp_send_json(
!$queues ?
array(
'result' => false,
'error' => __('Queue not found.')
) :
array(
'result' => true,
'data' => $queues
)
);
}
}

View File

@ -19,7 +19,6 @@ class SendingQueue {
'errors' => array($e->getMessage()) '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'])

View File

@ -0,0 +1,100 @@
<?php
use MailPoet\Mailer\Mailer;
class MailerCest {
function _before() {
$this->sender = array(
'name' => 'Sender',
'address' => 'staff@mailinator.com'
);
$this->replyTo = array(
'name' => 'Reply To',
'address' => 'staff@mailinator.com'
);
$this->mailer = array(
'method' => 'MailPoet',
'mailpoet_api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing Mailer',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itRequiresMailerMethod() {
try {
$mailer = new Mailer();
} catch (Exception $e) {
expect($e->getMessage())->equals('Mailer is not configured.');
}
}
function itRequiresSender() {
try {
$mailer = new Mailer($mailer = $this->mailer);
} catch (Exception $e) {
expect($e->getMessage())->equals('Sender name and email are not configured.');
}
}
function itCanConstruct() {
$mailer = new Mailer($this->mailer, $this->sender, $this->replyTo);
expect($mailer->sender['fromName'])->equals($this->sender['name']);
expect($mailer->sender['fromEmail'])->equals($this->sender['address']);
expect($mailer->replyTo['replyToName'])->equals($this->replyTo['name']);
expect($mailer->replyTo['replyToEmail'])->equals($this->replyTo['address']);
}
function itCanBuildMailerInstance() {
$mailer = new Mailer($this->mailer, $this->sender);
expect(get_class($mailer->mailerInstance))
->equals('MailPoet\Mailer\Methods\MailPoet');
}
function itCanAbortWhenMethodDoesNotExist() {
try {
$mailer = new Mailer(array('method' => 'test'), $this->sender);
} catch (Exception $e) {
expect($e->getMessage())->equals('Mailing method does not exist.');
}
}
function itCanTransformSubscriber() {
$mailer = new Mailer($this->mailer, $this->sender, $this->replyTo);
expect($mailer->transformSubscriber('test@email.com'))
->equals('test@email.com');
expect($mailer->transformSubscriber(
array(
'email' => 'test@email.com'
))
)->equals('test@email.com');
expect($mailer->transformSubscriber(
array(
'first_name' => 'First',
'email' => 'test@email.com'
))
)->equals('First <test@email.com>');
expect($mailer->transformSubscriber(
array(
'last_name' => 'Last',
'email' => 'test@email.com'
))
)->equals('Last <test@email.com>');
expect($mailer->transformSubscriber(
array(
'first_name' => 'First',
'last_name' => 'Last',
'email' => 'test@email.com'
))
)->equals('First Last <test@email.com>');
}
function itCanSend() {
$mailer = new Mailer($this->mailer, $this->sender, $this->replyTo);
expect($mailer->send($this->newsletter, $this->subscriber))->true();
}
}

View File

@ -1,12 +1,11 @@
<?php <?php
use MailPoet\Mailer\API\AmazonSES; use MailPoet\Mailer\Methods\AmazonSES;
class AmazonSESCest { class AmazonSESCest {
function _before() { function _before() {
$this->settings = array( $this->settings = array(
'method' => 'AmazonSES', 'method' => 'AmazonSES',
'type' => 'API',
'access_key' => 'AKIAJM6Y5HMGXBLDNSRA', 'access_key' => 'AKIAJM6Y5HMGXBLDNSRA',
'secret_key' => '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', 'secret_key' => 'P3EbTbVx7U0LXKQ9nTm2eIrP+9aPiLyvaRDsFxXh',
'region' => 'us-east-1', 'region' => 'us-east-1',

View File

@ -1,12 +1,11 @@
<?php <?php
use MailPoet\Mailer\API\ElasticEmail; use MailPoet\Mailer\Methods\ElasticEmail;
class ElasticEmailCest { class ElasticEmailCest {
function _before() { function _before() {
$this->settings = array( $this->settings = array(
'method' => 'ElasticEmail', 'method' => 'ElasticEmail',
'type' => 'API',
'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa' 'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa'
); );
$this->fromEmail = 'staff@mailpoet.com'; $this->fromEmail = 'staff@mailpoet.com';

View File

@ -1,12 +1,11 @@
<?php <?php
use MailPoet\Mailer\API\MailGun; use MailPoet\Mailer\Methods\MailGun;
class MailGunCest { class MailGunCest {
function _before() { function _before() {
$this->settings = array( $this->settings = array(
'method' => 'MailGun', 'method' => 'MailGun',
'type' => 'API',
'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2', 'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2',
'domain' => 'mrcasual.com' 'domain' => 'mrcasual.com'
); );

View File

@ -1,6 +1,6 @@
<?php <?php
use MailPoet\Mailer\MailPoet; use MailPoet\Mailer\Methods\MailPoet;
class MailPoetCest { class MailPoetCest {
function _before() { function _before() {

View File

@ -1,12 +1,11 @@
<?php <?php
use MailPoet\Mailer\API\Mandrill; use MailPoet\Mailer\Methods\Mandrill;
class MandrillCest { class MandrillCest {
function _before() { function _before() {
$this->settings = array( $this->settings = array(
'method' => 'Mandrill', 'method' => 'Mandrill',
'type' => 'API',
'api_key' => '692ys1B7REEoZN7R-dYwNA' 'api_key' => '692ys1B7REEoZN7R-dYwNA'
); );
$this->fromEmail = 'staff@mailpoet.com'; $this->fromEmail = 'staff@mailpoet.com';

View File

@ -1,6 +1,6 @@
<?php <?php
use MailPoet\Mailer\SMTP; use MailPoet\Mailer\Methods\SMTP;
class SMTPCest { class SMTPCest {
function _before() { function _before() {

View File

@ -1,12 +1,11 @@
<?php <?php
use MailPoet\Mailer\API\SendGrid; use MailPoet\Mailer\Methods\SendGrid;
class SendGridCest { class SendGridCest {
function _before() { function _before() {
$this->settings = array( $this->settings = array(
'method' => 'SendGrid', 'method' => 'SendGrid',
'type' => 'API',
'api_key' => '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' 'api_key' => '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'
); );
$this->fromEmail = 'staff@mailpoet.com'; $this->fromEmail = 'staff@mailpoet.com';

View File

@ -1,6 +1,6 @@
<?php <?php
use MailPoet\Mailer\WPMail; use MailPoet\Mailer\Methods\WPMail;
class WPMailCest { class WPMailCest {
function _before() { function _before() {