Merge pull request #1505 from mailpoet/sending-erros-levels
Multiple Sending Error Levels [MAILPOET-1154]
This commit is contained in:
@ -21,10 +21,7 @@ class Mailer extends APIEndpoint {
|
|||||||
(isset($data['sender'])) ? $data['sender'] : false,
|
(isset($data['sender'])) ? $data['sender'] : false,
|
||||||
(isset($data['reply_to'])) ? $data['reply_to'] : false
|
(isset($data['reply_to'])) ? $data['reply_to'] : false
|
||||||
);
|
);
|
||||||
$extra_params = array(
|
$result = $mailer->send($data['newsletter'], $data['subscriber']);
|
||||||
'test_email' => true
|
|
||||||
);
|
|
||||||
$result = $mailer->send($data['newsletter'], $data['subscriber'], $extra_params);
|
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return $this->errorResponse(array(
|
return $this->errorResponse(array(
|
||||||
$e->getCode() => $e->getMessage()
|
$e->getCode() => $e->getMessage()
|
||||||
@ -34,7 +31,7 @@ class Mailer extends APIEndpoint {
|
|||||||
if($result['response'] === false) {
|
if($result['response'] === false) {
|
||||||
$error = sprintf(
|
$error = sprintf(
|
||||||
__('The email could not be sent: %s', 'mailpoet'),
|
__('The email could not be sent: %s', 'mailpoet'),
|
||||||
$result['error_message']
|
$result['error']->getMessage()
|
||||||
);
|
);
|
||||||
return $this->errorResponse(array(APIError::BAD_REQUEST => $error));
|
return $this->errorResponse(array(APIError::BAD_REQUEST => $error));
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,6 +131,8 @@ class Migrator {
|
|||||||
'task_id int(11) unsigned NOT NULL,',
|
'task_id int(11) unsigned NOT NULL,',
|
||||||
'subscriber_id int(11) unsigned NOT NULL,',
|
'subscriber_id int(11) unsigned NOT NULL,',
|
||||||
'processed int(1) NOT NULL,',
|
'processed int(1) NOT NULL,',
|
||||||
|
'failed int(1) NOT NULL,',
|
||||||
|
'error text NULL,',
|
||||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||||
'PRIMARY KEY (task_id, subscriber_id),',
|
'PRIMARY KEY (task_id, subscriber_id),',
|
||||||
'KEY subscriber_id (subscriber_id)'
|
'KEY subscriber_id (subscriber_id)'
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace MailPoet\Cron;
|
namespace MailPoet\Cron;
|
||||||
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\Migration as MigrationWorker;
|
use MailPoet\Cron\Workers\SendingQueue\Migration as MigrationWorker;
|
||||||
|
use MailPoet\Cron\Workers\SendingQueue\SendingErrorHandler;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||||
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
||||||
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
|
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||||
@ -91,7 +92,7 @@ class Daemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function executeQueueWorker() {
|
function executeQueueWorker() {
|
||||||
$queue = new SendingQueueWorker($this->timer);
|
$queue = new SendingQueueWorker(new SendingErrorHandler(), $this->timer);
|
||||||
return $queue->process();
|
return $queue->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
lib/Cron/Workers/SendingQueue/SendingErrorHandler.php
Normal file
36
lib/Cron/Workers/SendingQueue/SendingErrorHandler.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Cron\Workers\SendingQueue;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\MailerLog;
|
||||||
|
use MailPoet\Tasks\Sending as SendingTask;
|
||||||
|
|
||||||
|
class SendingErrorHandler {
|
||||||
|
function processError(
|
||||||
|
MailerError $error,
|
||||||
|
SendingTask $sending_task,
|
||||||
|
array $prepared_subscribers_ids,
|
||||||
|
array $prepared_subscribers
|
||||||
|
) {
|
||||||
|
if($error->getLevel() === MailerError::LEVEL_HARD) {
|
||||||
|
return $this->processHardError($error);
|
||||||
|
}
|
||||||
|
$this->processSoftError($error, $sending_task, $prepared_subscribers_ids, $prepared_subscribers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processHardError(MailerError $error) {
|
||||||
|
if($error->getRetryInterval() !== null) {
|
||||||
|
MailerLog::processNonBlockingError($error->getOperation(), $error->getMessageWithFailedSubscribers(), $error->getRetryInterval());
|
||||||
|
} else {
|
||||||
|
MailerLog::processError($error->getOperation(), $error->getMessageWithFailedSubscribers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processSoftError(MailerError $error, SendingTask $sending_task, $prepared_subscribers_ids, $prepared_subscribers) {
|
||||||
|
foreach($error->getSubscriberErrors() as $subscriber_error) {
|
||||||
|
$subscriber_id_index = array_search($subscriber_error->getEmail(), $prepared_subscribers);
|
||||||
|
$message = $subscriber_error->getMessage() ?: $error->getMessage();
|
||||||
|
$sending_task->saveSubscriberError($prepared_subscribers_ids[$subscriber_id_index], $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ use MailPoet\Cron\CronHelper;
|
|||||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
|
use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
|
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
use MailPoet\Mailer\MailerLog;
|
use MailPoet\Mailer\MailerLog;
|
||||||
use MailPoet\Models\ScheduledTask as ScheduledTaskModel;
|
use MailPoet\Models\ScheduledTask as ScheduledTaskModel;
|
||||||
use MailPoet\Models\StatisticsNewsletters as StatisticsNewslettersModel;
|
use MailPoet\Models\StatisticsNewsletters as StatisticsNewslettersModel;
|
||||||
@ -23,7 +24,11 @@ class SendingQueue {
|
|||||||
const BATCH_SIZE = 20;
|
const BATCH_SIZE = 20;
|
||||||
const TASK_BATCH_SIZE = 5;
|
const TASK_BATCH_SIZE = 5;
|
||||||
|
|
||||||
function __construct($timer = false, $mailer_task = false, $newsletter_task = false) {
|
/** @var SendingErrorHandler */
|
||||||
|
private $error_handler;
|
||||||
|
|
||||||
|
function __construct(SendingErrorHandler $error_handler, $timer = false, $mailer_task = false, $newsletter_task = false) {
|
||||||
|
$this->error_handler = $error_handler;
|
||||||
$this->mailer_task = ($mailer_task) ? $mailer_task : new MailerTask();
|
$this->mailer_task = ($mailer_task) ? $mailer_task : new MailerTask();
|
||||||
$this->newsletter_task = ($newsletter_task) ? $newsletter_task : new NewsletterTask();
|
$this->newsletter_task = ($newsletter_task) ? $newsletter_task : new NewsletterTask();
|
||||||
$this->timer = ($timer) ? $timer : microtime(true);
|
$this->timer = ($timer) ? $timer : microtime(true);
|
||||||
@ -124,12 +129,12 @@ class SendingQueue {
|
|||||||
'queue_id' => $queue->id
|
'queue_id' => $queue->id
|
||||||
);
|
);
|
||||||
if($processing_method === 'individual') {
|
if($processing_method === 'individual') {
|
||||||
$queue = $this->sendNewsletters(
|
$queue = $this->sendNewsletter(
|
||||||
$queue,
|
$queue,
|
||||||
$prepared_subscribers_ids,
|
$prepared_subscribers_ids[0],
|
||||||
$prepared_newsletters[0],
|
$prepared_newsletters[0],
|
||||||
$prepared_subscribers[0],
|
$prepared_subscribers[0],
|
||||||
$statistics,
|
$statistics[0],
|
||||||
array('unsubscribe_url' => $unsubscribe_urls[0])
|
array('unsubscribe_url' => $unsubscribe_urls[0])
|
||||||
);
|
);
|
||||||
$prepared_newsletters = array();
|
$prepared_newsletters = array();
|
||||||
@ -152,29 +157,64 @@ class SendingQueue {
|
|||||||
return $queue;
|
return $queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendNewsletters(
|
function sendNewsletter(
|
||||||
$queue, $prepared_subscribers_ids, $prepared_newsletters,
|
SendingTask $sending_task, $prepared_subscriber_id, $prepared_newsletter,
|
||||||
$prepared_subscribers, $statistics, $extra_params = array()
|
$prepared_subscriber, $statistics, $extra_params = array()
|
||||||
) {
|
) {
|
||||||
// send newsletter
|
// send newsletter
|
||||||
$send_result = $this->mailer_task->send(
|
$send_result = $this->mailer_task->send(
|
||||||
|
$prepared_newsletter,
|
||||||
|
$prepared_subscriber,
|
||||||
|
$extra_params
|
||||||
|
);
|
||||||
|
return $this->processSendResult(
|
||||||
|
$sending_task,
|
||||||
|
$send_result,
|
||||||
|
[$prepared_subscriber],
|
||||||
|
[$prepared_subscriber_id],
|
||||||
|
[$statistics]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendNewsletters(
|
||||||
|
SendingTask $sending_task, $prepared_subscribers_ids, $prepared_newsletters,
|
||||||
|
$prepared_subscribers, $statistics, $extra_params = array()
|
||||||
|
) {
|
||||||
|
// send newsletters
|
||||||
|
$send_result = $this->mailer_task->sendBulk(
|
||||||
$prepared_newsletters,
|
$prepared_newsletters,
|
||||||
$prepared_subscribers,
|
$prepared_subscribers,
|
||||||
$extra_params
|
$extra_params
|
||||||
);
|
);
|
||||||
|
return $this->processSendResult(
|
||||||
|
$sending_task,
|
||||||
|
$send_result,
|
||||||
|
$prepared_subscribers,
|
||||||
|
$prepared_subscribers_ids,
|
||||||
|
$statistics
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processSendResult(
|
||||||
|
SendingTask $sending_task,
|
||||||
|
$send_result,
|
||||||
|
array $prepared_subscribers,
|
||||||
|
array $prepared_subscribers_ids,
|
||||||
|
array $statistics
|
||||||
|
) {
|
||||||
// log error message and schedule retry/pause sending
|
// log error message and schedule retry/pause sending
|
||||||
if($send_result['response'] === false) {
|
if($send_result['response'] === false) {
|
||||||
if(isset($send_result['retry_interval'])) {
|
$error = $send_result['error'];
|
||||||
MailerLog::processNonBlockingError($send_result['operation'], $send_result['error_message'], $send_result['retry_interval']);
|
assert($error instanceof MailerError);
|
||||||
} else {
|
// Always switch error level to hard until we implement UI for individual subscriber errors
|
||||||
MailerLog::processError($send_result['operation'], $send_result['error_message']);
|
$error->switchLevelToHard();
|
||||||
}
|
$this->error_handler->processError($error, $sending_task, $prepared_subscribers_ids, $prepared_subscribers);
|
||||||
}
|
}
|
||||||
// update processed/to process list
|
// update processed/to process list
|
||||||
if(!$queue->updateProcessedSubscribers($prepared_subscribers_ids)) {
|
if(!$sending_task->updateProcessedSubscribers($prepared_subscribers_ids)) {
|
||||||
MailerLog::processError(
|
MailerLog::processError(
|
||||||
'processed_list_update',
|
'processed_list_update',
|
||||||
sprintf('QUEUE-%d-PROCESSED-LIST-UPDATE', $queue->id),
|
sprintf('QUEUE-%d-PROCESSED-LIST-UPDATE', $sending_task->id),
|
||||||
null,
|
null,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -184,10 +224,10 @@ class SendingQueue {
|
|||||||
// update the sent count
|
// update the sent count
|
||||||
$this->mailer_task->updateSentCount();
|
$this->mailer_task->updateSentCount();
|
||||||
// enforce execution limits if queue is still being processed
|
// enforce execution limits if queue is still being processed
|
||||||
if($queue->status !== ScheduledTaskModel::STATUS_COMPLETED) {
|
if($sending_task->status !== ScheduledTaskModel::STATUS_COMPLETED) {
|
||||||
$this->enforceSendingAndExecutionLimits();
|
$this->enforceSendingAndExecutionLimits();
|
||||||
}
|
}
|
||||||
return $queue;
|
return $sending_task;
|
||||||
}
|
}
|
||||||
|
|
||||||
function enforceSendingAndExecutionLimits() {
|
function enforceSendingAndExecutionLimits() {
|
||||||
|
@ -54,11 +54,25 @@ class Mailer {
|
|||||||
return $this->mailer->formatSubscriberNameAndEmailAddress($subscriber);
|
return $this->mailer->formatSubscriberNameAndEmailAddress($subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($prepared_newsletters, $prepared_subscribers, $extra_params = array()) {
|
function sendBulk($prepared_newsletters, $prepared_subscribers, $extra_params = array()) {
|
||||||
|
if($this->getProcessingMethod() === 'individual') {
|
||||||
|
throw new \LogicException('Trying to send a batch with individual processing method');
|
||||||
|
}
|
||||||
return $this->mailer->mailer_instance->send(
|
return $this->mailer->mailer_instance->send(
|
||||||
$prepared_newsletters,
|
$prepared_newsletters,
|
||||||
$prepared_subscribers,
|
$prepared_subscribers,
|
||||||
$extra_params
|
$extra_params
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function send($prepared_newsletter, $prepared_subscriber, $extra_params = array()) {
|
||||||
|
if($this->getProcessingMethod() === 'bulk') {
|
||||||
|
throw new \LogicException('Trying to send an individual email with a bulk processing method');
|
||||||
|
}
|
||||||
|
return $this->mailer->mailer_instance->send(
|
||||||
|
$prepared_newsletter,
|
||||||
|
$prepared_subscriber,
|
||||||
|
$extra_params
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ class Newsletter {
|
|||||||
return $newsletter;
|
return $newsletter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function preProcessNewsletter($newsletter, $queue) {
|
function preProcessNewsletter(\MailPoet\Models\Newsletter $newsletter, $queue) {
|
||||||
// return the newsletter if it was previously rendered
|
// return the newsletter if it was previously rendered
|
||||||
if(!is_null($queue->getNewsletterRenderedBody())) {
|
if(!is_null($queue->getNewsletterRenderedBody())) {
|
||||||
return (!$queue->validate()) ?
|
return (!$queue->validate()) ?
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Mailer;
|
namespace MailPoet\Mailer;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\PHPMailMapper;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SendGridMapper;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SMTPMapper;
|
||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
@ -42,28 +47,32 @@ class Mailer {
|
|||||||
$this->mailer_config['secret_key'],
|
$this->mailer_config['secret_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new AmazonSESMapper()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case self::METHOD_MAILPOET:
|
case self::METHOD_MAILPOET:
|
||||||
$mailer_instance = new $this->mailer_config['class'](
|
$mailer_instance = new $this->mailer_config['class'](
|
||||||
$this->mailer_config['mailpoet_api_key'],
|
$this->mailer_config['mailpoet_api_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to
|
$this->reply_to,
|
||||||
|
new MailPoetMapper()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case self::METHOD_SENDGRID:
|
case self::METHOD_SENDGRID:
|
||||||
$mailer_instance = new $this->mailer_config['class'](
|
$mailer_instance = new $this->mailer_config['class'](
|
||||||
$this->mailer_config['api_key'],
|
$this->mailer_config['api_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to
|
$this->reply_to,
|
||||||
|
new SendGridMapper()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case self::METHOD_PHPMAIL:
|
case self::METHOD_PHPMAIL:
|
||||||
$mailer_instance = new $this->mailer_config['class'](
|
$mailer_instance = new $this->mailer_config['class'](
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new PHPMailMapper()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case self::METHOD_SMTP:
|
case self::METHOD_SMTP:
|
||||||
@ -76,7 +85,8 @@ class Mailer {
|
|||||||
$this->mailer_config['encryption'],
|
$this->mailer_config['encryption'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new SMTPMapper()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -166,25 +176,16 @@ class Mailer {
|
|||||||
return sprintf('=?utf-8?B?%s?=', base64_encode($name));
|
return sprintf('=?utf-8?B?%s?=', base64_encode($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static function formatMailerConnectionErrorResult($error_message) {
|
static function formatMailerErrorResult(MailerError $error) {
|
||||||
return array(
|
return [
|
||||||
'response' => false,
|
'response' => false,
|
||||||
'operation' => 'connect',
|
'error' => $error,
|
||||||
'error_message' => $error_message
|
];
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function formatMailerSendErrorResult($error_message) {
|
|
||||||
return array(
|
|
||||||
'response' => false,
|
|
||||||
'operation' => 'send',
|
|
||||||
'error_message' => $error_message
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static function formatMailerSendSuccessResult() {
|
static function formatMailerSendSuccessResult() {
|
||||||
return array(
|
return [
|
||||||
'response' => true
|
'response' => true
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
105
lib/Mailer/MailerError.php
Normal file
105
lib/Mailer/MailerError.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer;
|
||||||
|
|
||||||
|
class MailerError {
|
||||||
|
const OPERATION_CONNECT = 'connect';
|
||||||
|
const OPERATION_SEND = 'send';
|
||||||
|
|
||||||
|
const LEVEL_HARD = 'hard';
|
||||||
|
const LEVEL_SOFT = 'soft';
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $operation;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $level;
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $message;
|
||||||
|
|
||||||
|
/** @var int|null */
|
||||||
|
private $retry_interval;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $subscribers_errors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $operation
|
||||||
|
* @param string $level
|
||||||
|
* @param null|string $message
|
||||||
|
* @param int|null $retry_interval
|
||||||
|
* @param array $subscribers_errors
|
||||||
|
*/
|
||||||
|
function __construct($operation, $level, $message = null, $retry_interval = null, array $subscribers_errors = []) {
|
||||||
|
$this->operation = $operation;
|
||||||
|
$this->level = $level;
|
||||||
|
$this->message = $message;
|
||||||
|
$this->retry_interval = $retry_interval;
|
||||||
|
$this->subscribers_errors = $subscribers_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getOperation() {
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getLevel() {
|
||||||
|
return $this->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
function getMessage() {
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
function getRetryInterval() {
|
||||||
|
return $this->retry_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SubscriberError[]
|
||||||
|
*/
|
||||||
|
function getSubscriberErrors() {
|
||||||
|
return $this->subscribers_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary method until we implement UI for subscriber errors
|
||||||
|
*/
|
||||||
|
function switchLevelToHard() {
|
||||||
|
$this->level = self::LEVEL_HARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMessageWithFailedSubscribers() {
|
||||||
|
$message = $this->message ?: '';
|
||||||
|
if(!$this->subscribers_errors) {
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message .= $this->message ? ' ' : '';
|
||||||
|
|
||||||
|
if(count($this->subscribers_errors) === 1) {
|
||||||
|
$message .= __('Unprocessed subscriber:', 'mailpoet') . ' ';
|
||||||
|
} else {
|
||||||
|
$message .= __('Unprocessed subscribers:', 'mailpoet') . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$message .= implode(
|
||||||
|
', ',
|
||||||
|
array_map(function (SubscriberError $subscriber_error) {
|
||||||
|
return "($subscriber_error)";
|
||||||
|
}, $this->subscribers_errors)
|
||||||
|
);
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
namespace MailPoet\Mailer\Methods;
|
namespace MailPoet\Mailer\Methods;
|
||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
@ -28,7 +29,18 @@ class AmazonSES {
|
|||||||
'EU (Ireland)' => 'eu-west-1'
|
'EU (Ireland)' => 'eu-west-1'
|
||||||
);
|
);
|
||||||
|
|
||||||
function __construct($region, $access_key, $secret_key, $sender, $reply_to, $return_path) {
|
/** @var AmazonSESMapper */
|
||||||
|
private $error_mapper;
|
||||||
|
|
||||||
|
function __construct(
|
||||||
|
$region,
|
||||||
|
$access_key,
|
||||||
|
$secret_key,
|
||||||
|
$sender,
|
||||||
|
$reply_to,
|
||||||
|
$return_path,
|
||||||
|
AmazonSESMapper $error_mapper
|
||||||
|
) {
|
||||||
$this->aws_access_key = $access_key;
|
$this->aws_access_key = $access_key;
|
||||||
$this->aws_secret_key = $secret_key;
|
$this->aws_secret_key = $secret_key;
|
||||||
$this->aws_region = (in_array($region, $this->available_regions)) ? $region : false;
|
$this->aws_region = (in_array($region, $this->available_regions)) ? $region : false;
|
||||||
@ -48,6 +60,7 @@ class AmazonSES {
|
|||||||
$this->sender['from_email'];
|
$this->sender['from_email'];
|
||||||
$this->date = gmdate('Ymd\THis\Z');
|
$this->date = gmdate('Ymd\THis\Z');
|
||||||
$this->date_without_time = gmdate('Ymd');
|
$this->date_without_time = gmdate('Ymd');
|
||||||
|
$this->error_mapper = $error_mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($newsletter, $subscriber, $extra_params = array()) {
|
function send($newsletter, $subscriber, $extra_params = array()) {
|
||||||
@ -57,20 +70,17 @@ class AmazonSES {
|
|||||||
$this->request($newsletter, $subscriber, $extra_params)
|
$this->request($newsletter, $subscriber, $extra_params)
|
||||||
);
|
);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return Mailer::formatMailerSendErrorResult($e->getMessage());
|
$error = $this->error_mapper->getErrorFromException($e, $subscriber);
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
}
|
}
|
||||||
if(is_wp_error($result)) {
|
if(is_wp_error($result)) {
|
||||||
return Mailer::formatMailerConnectionErrorResult($result->get_error_message());
|
$error = $this->error_mapper->getConnectionError($result->get_error_message());
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
}
|
}
|
||||||
if(WPFunctions::wpRemoteRetrieveResponseCode($result) !== 200) {
|
if(WPFunctions::wpRemoteRetrieveResponseCode($result) !== 200) {
|
||||||
$response = simplexml_load_string(WPFunctions::wpRemoteRetrieveBody($result));
|
$response = simplexml_load_string(WPFunctions::wpRemoteRetrieveBody($result));
|
||||||
$response = ($response) ?
|
$error = $this->error_mapper->getErrorFromResponse($response, $subscriber);
|
||||||
$response->Error->Message->__toString() :
|
return Mailer::formatMailerErrorResult($error);
|
||||||
sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_AMAZONSES);
|
|
||||||
if(empty($extra_params['test_email'])) {
|
|
||||||
$response .= sprintf(' %s: %s', __('Unprocessed subscriber', 'mailpoet'), $subscriber);
|
|
||||||
}
|
|
||||||
return Mailer::formatMailerSendErrorResult($response);
|
|
||||||
}
|
}
|
||||||
return Mailer::formatMailerSendSuccessResult();
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
}
|
}
|
||||||
|
36
lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php
Normal file
36
lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
|
||||||
|
class AmazonSESMapper {
|
||||||
|
use ConnectionErrorMapperTrait;
|
||||||
|
|
||||||
|
function getErrorFromException(\Exception $e, $subscriber) {
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
if($e instanceof \Swift_RfcComplianceException) {
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
}
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $e->getMessage(), null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://docs.aws.amazon.com/ses/latest/DeveloperGuide/api-error-codes.html
|
||||||
|
* @return MailerError
|
||||||
|
*/
|
||||||
|
function getErrorFromResponse($response, $subscriber) {
|
||||||
|
$message = ($response) ?
|
||||||
|
$response->Error->Message->__toString() :
|
||||||
|
sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_AMAZONSES);
|
||||||
|
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
if($response && $response->Error->Code->__toString() === 'MessageRejected') {
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
}
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $message, null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
|
||||||
|
trait ConnectionErrorMapperTrait {
|
||||||
|
function getConnectionError($message) {
|
||||||
|
return new MailerError(
|
||||||
|
MailerError::OPERATION_CONNECT,
|
||||||
|
MailerError::LEVEL_HARD,
|
||||||
|
$message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
77
lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php
Normal file
77
lib/Mailer/Methods/ErrorMappers/MailPoetMapper.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
use MailPoet\Services\Bridge\API;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class MailPoetMapper {
|
||||||
|
use ConnectionErrorMapperTrait;
|
||||||
|
|
||||||
|
const TEMPORARY_UNAVAILABLE_RETRY_INTERVAL = 300; // seconds
|
||||||
|
|
||||||
|
function getInvalidApiKeyError() {
|
||||||
|
return new MailerError(
|
||||||
|
MailerError::OPERATION_SEND,
|
||||||
|
MailerError::LEVEL_HARD,
|
||||||
|
__('MailPoet API key is invalid!', 'mailpoet')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getErrorForResult(array $result, $subscribers) {
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
$retry_interval = null;
|
||||||
|
$subscribers_errors = [];
|
||||||
|
$result_code = !empty($result['code']) ? $result['code'] : null;
|
||||||
|
|
||||||
|
switch($result_code) {
|
||||||
|
case API::RESPONSE_CODE_NOT_ARRAY:
|
||||||
|
$message = __('JSON input is not an array', 'mailpoet');
|
||||||
|
break;
|
||||||
|
case API::RESPONSE_CODE_PAYLOAD_ERROR:
|
||||||
|
$result_parsed = json_decode($result['message'], true);
|
||||||
|
$message = __('Error while sending.', 'mailpoet');
|
||||||
|
if(!is_array($result_parsed)) {
|
||||||
|
$message .= ' ' . $result['message'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$subscribers_errors = $this->getSubscribersErrors($result_parsed, $subscribers);
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
$message .= ' ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case API::RESPONSE_CODE_TEMPORARY_UNAVAILABLE:
|
||||||
|
$message = __('Email service is temporarily not available, please try again in a few minutes.', 'mailpoet');
|
||||||
|
$retry_interval = self::TEMPORARY_UNAVAILABLE_RETRY_INTERVAL;
|
||||||
|
break;
|
||||||
|
case API::RESPONSE_CODE_KEY_INVALID:
|
||||||
|
case API::RESPONSE_CODE_PAYLOAD_TOO_BIG:
|
||||||
|
default:
|
||||||
|
$message = $result['message'];
|
||||||
|
}
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $message, $retry_interval, $subscribers_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSubscribersErrors($result_parsed, $subscribers) {
|
||||||
|
$errors = [];
|
||||||
|
foreach($result_parsed as $result_error) {
|
||||||
|
if(!is_array($result_error) || !isset($result_error['index']) || !isset($subscribers[$result_error['index']])) {
|
||||||
|
throw new InvalidArgumentException( __('Invalid MSS response format.', 'mailpoet'));
|
||||||
|
}
|
||||||
|
$subscriber_errors = [];
|
||||||
|
if(isset($result_error['errors']) && is_array($result_error['errors'])) {
|
||||||
|
array_walk_recursive($result_error['errors'], function($item) use (&$subscriber_errors) {
|
||||||
|
$subscriber_errors[] = $item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$message = join(', ', $subscriber_errors);
|
||||||
|
$errors[] = new SubscriberError($subscribers[$result_error['index']], $message);
|
||||||
|
}
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
}
|
26
lib/Mailer/Methods/ErrorMappers/PHPMailMapper.php
Normal file
26
lib/Mailer/Methods/ErrorMappers/PHPMailMapper.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
|
||||||
|
class PHPMailMapper {
|
||||||
|
use ConnectionErrorMapperTrait;
|
||||||
|
|
||||||
|
function getErrorFromException(\Exception $e, $subscriber) {
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
if(strpos($e->getMessage(), 'Invalid address') === 0) {
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $e->getMessage(), null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getErrorForSubscriber($subscriber) {
|
||||||
|
$message = sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_PHPMAIL);
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, MailerError::LEVEL_HARD, $message, null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
}
|
40
lib/Mailer/Methods/ErrorMappers/SMTPMapper.php
Normal file
40
lib/Mailer/Methods/ErrorMappers/SMTPMapper.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
|
||||||
|
class SMTPMapper {
|
||||||
|
use ConnectionErrorMapperTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://swiftmailer.symfony.com/docs/sending.html
|
||||||
|
* @return MailerError
|
||||||
|
*/
|
||||||
|
function getErrorFromException(\Exception $e, $subscriber) {
|
||||||
|
// remove redundant information appended by Swift logger to exception messages
|
||||||
|
$message = explode(PHP_EOL, $e->getMessage());
|
||||||
|
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
if($e instanceof \Swift_RfcComplianceException) {
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
}
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $message[0], null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getErrorFromLog($log, $subscriber) {
|
||||||
|
// extract error message from log
|
||||||
|
preg_match('/!! (.*?)>>/ism', $log, $message);
|
||||||
|
if(!empty($message[1])) {
|
||||||
|
$message = $message[1];
|
||||||
|
// remove line breaks from the message due to how logger's dump() method works
|
||||||
|
$message = preg_replace('/\r|\n/', '', $message);
|
||||||
|
} else {
|
||||||
|
$message = sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_SMTP);
|
||||||
|
}
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, MailerError::LEVEL_HARD, $message, null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
}
|
23
lib/Mailer/Methods/ErrorMappers/SendGridMapper.php
Normal file
23
lib/Mailer/Methods/ErrorMappers/SendGridMapper.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
|
||||||
|
class SendGridMapper {
|
||||||
|
use ConnectionErrorMapperTrait;
|
||||||
|
|
||||||
|
function getErrorFromResponse($response, $subscriber) {
|
||||||
|
$response = (!empty($response['errors'][0])) ?
|
||||||
|
$response['errors'][0] :
|
||||||
|
sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_SENDGRID);
|
||||||
|
|
||||||
|
$level = MailerError::LEVEL_HARD;
|
||||||
|
if(strpos($response, 'Invalid email address') === 0) {
|
||||||
|
$level = MailerError::LEVEL_SOFT;
|
||||||
|
}
|
||||||
|
$subscriber_errors = [new SubscriberError($subscriber, null)];
|
||||||
|
return new MailerError(MailerError::OPERATION_SEND, $level, $response, null, $subscriber_errors);
|
||||||
|
}
|
||||||
|
}
|
@ -3,31 +3,32 @@ namespace MailPoet\Mailer\Methods;
|
|||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
use MailPoet\Config\ServicesChecker;
|
use MailPoet\Config\ServicesChecker;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Services\Bridge\API;
|
use MailPoet\Services\Bridge\API;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class MailPoet {
|
class MailPoet {
|
||||||
|
|
||||||
const TEMPORARY_UNAVAILABLE_RETRY_INTERVAL = 300; // seconds
|
|
||||||
|
|
||||||
public $api;
|
public $api;
|
||||||
public $sender;
|
public $sender;
|
||||||
public $reply_to;
|
public $reply_to;
|
||||||
public $services_checker;
|
public $services_checker;
|
||||||
|
|
||||||
function __construct($api_key, $sender, $reply_to) {
|
/** @var MailPoetMapper */
|
||||||
|
private $error_mapper;
|
||||||
|
|
||||||
|
function __construct($api_key, $sender, $reply_to, MailPoetMapper $error_mapper) {
|
||||||
$this->api = new API($api_key);
|
$this->api = new API($api_key);
|
||||||
$this->sender = $sender;
|
$this->sender = $sender;
|
||||||
$this->reply_to = $reply_to;
|
$this->reply_to = $reply_to;
|
||||||
$this->services_checker = new ServicesChecker(false);
|
$this->services_checker = new ServicesChecker();
|
||||||
|
$this->error_mapper = $error_mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($newsletter, $subscriber, $extra_params = array()) {
|
function send($newsletter, $subscriber, $extra_params = array()) {
|
||||||
if($this->services_checker->isMailPoetAPIKeyValid() === false) {
|
if($this->services_checker->isMailPoetAPIKeyValid() === false) {
|
||||||
$response = __('MailPoet API key is invalid!', 'mailpoet');
|
return Mailer::formatMailerErrorResult($this->error_mapper->getInvalidApiKeyError());
|
||||||
return Mailer::formatMailerSendErrorResult($response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$message_body = $this->getBody($newsletter, $subscriber, $extra_params);
|
$message_body = $this->getBody($newsletter, $subscriber, $extra_params);
|
||||||
@ -35,9 +36,11 @@ class MailPoet {
|
|||||||
|
|
||||||
switch($result['status']) {
|
switch($result['status']) {
|
||||||
case API::SENDING_STATUS_CONNECTION_ERROR:
|
case API::SENDING_STATUS_CONNECTION_ERROR:
|
||||||
return Mailer::formatMailerConnectionErrorResult($result['message']);
|
$error = $this->error_mapper->getConnectionError($result['message']);
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
case API::SENDING_STATUS_SEND_ERROR:
|
case API::SENDING_STATUS_SEND_ERROR:
|
||||||
return $this->processSendError($result, $subscriber);
|
$error = $this->processSendError($result, $subscriber);
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
case API::SENDING_STATUS_OK:
|
case API::SENDING_STATUS_OK:
|
||||||
default:
|
default:
|
||||||
return Mailer::formatMailerSendSuccessResult();
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
@ -45,27 +48,10 @@ class MailPoet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processSendError($result, $subscriber) {
|
function processSendError($result, $subscriber) {
|
||||||
if(!empty($result['code'])) {
|
if(!empty($result['code']) && $result['code'] === API::RESPONSE_CODE_KEY_INVALID) {
|
||||||
switch($result['code']) {
|
Bridge::invalidateKey();
|
||||||
case API::RESPONSE_CODE_NOT_ARRAY:
|
|
||||||
return Mailer::formatMailerSendErrorResult(__('JSON input is not an array', 'mailpoet'));
|
|
||||||
case API::RESPONSE_CODE_PAYLOAD_TOO_BIG:
|
|
||||||
return Mailer::formatMailerSendErrorResult($result['message']);
|
|
||||||
case API::RESPONSE_CODE_PAYLOAD_ERROR:
|
|
||||||
$error = $this->parseErrorResponse($result['message'], $subscriber);
|
|
||||||
return Mailer::formatMailerSendErrorResult($error);
|
|
||||||
case API::RESPONSE_CODE_TEMPORARY_UNAVAILABLE:
|
|
||||||
$error = Mailer::formatMailerSendErrorResult(__('Email service is temporarily not available, please try again in a few minutes.', 'mailpoet'));
|
|
||||||
$error['retry_interval'] = self::TEMPORARY_UNAVAILABLE_RETRY_INTERVAL;
|
|
||||||
return $error;
|
|
||||||
case API::RESPONSE_CODE_KEY_INVALID:
|
|
||||||
Bridge::invalidateKey();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return Mailer::formatMailerSendErrorResult($result['message']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Mailer::formatMailerSendErrorResult($result['message']);
|
return $this->error_mapper->getErrorForResult($result, $subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
function processSubscriber($subscriber) {
|
function processSubscriber($subscriber) {
|
||||||
@ -128,37 +114,4 @@ class MailPoet {
|
|||||||
}
|
}
|
||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseErrorResponse($result, $subscriber) {
|
|
||||||
$result_parsed = json_decode($result, true);
|
|
||||||
$errors = [];
|
|
||||||
if(is_array($result_parsed)) {
|
|
||||||
foreach($result_parsed as $result_error) {
|
|
||||||
$errors[] = $this->processSingleSubscriberError($result_error, $subscriber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!empty($errors)) {
|
|
||||||
return __('Error while sending: ', 'mailpoet') . join(', ', $errors);
|
|
||||||
} else {
|
|
||||||
return __('Error while sending newsletters. ', 'mailpoet') . $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function processSingleSubscriberError($result_error, $subscriber) {
|
|
||||||
$error = '';
|
|
||||||
if(is_array($result_error)) {
|
|
||||||
$subscriber_errors = [];
|
|
||||||
if(isset($result_error['errors']) && is_array($result_error['errors'])) {
|
|
||||||
array_walk_recursive($result_error['errors'], function($item) use (&$subscriber_errors) {
|
|
||||||
$subscriber_errors[] = $item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$error .= join(', ', $subscriber_errors);
|
|
||||||
|
|
||||||
if(isset($result_error['index']) && isset($subscriber[$result_error['index']])) {
|
|
||||||
$error = '(' . $subscriber[$result_error['index']] . ': ' . $error . ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Mailer\Methods;
|
namespace MailPoet\Mailer\Methods;
|
||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\PHPMailMapper;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
@ -14,13 +15,17 @@ class PHPMail {
|
|||||||
public $return_path;
|
public $return_path;
|
||||||
public $mailer;
|
public $mailer;
|
||||||
|
|
||||||
function __construct($sender, $reply_to, $return_path) {
|
/** @var PHPMailMapper */
|
||||||
|
private $error_mapper;
|
||||||
|
|
||||||
|
function __construct($sender, $reply_to, $return_path, PHPMailMapper $error_mapper) {
|
||||||
$this->sender = $sender;
|
$this->sender = $sender;
|
||||||
$this->reply_to = $reply_to;
|
$this->reply_to = $reply_to;
|
||||||
$this->return_path = ($return_path) ?
|
$this->return_path = ($return_path) ?
|
||||||
$return_path :
|
$return_path :
|
||||||
$this->sender['from_email'];
|
$this->sender['from_email'];
|
||||||
$this->mailer = $this->buildMailer();
|
$this->mailer = $this->buildMailer();
|
||||||
|
$this->error_mapper = $error_mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($newsletter, $subscriber, $extra_params = array()) {
|
function send($newsletter, $subscriber, $extra_params = array()) {
|
||||||
@ -28,16 +33,13 @@ class PHPMail {
|
|||||||
$mailer = $this->configureMailerWithMessage($newsletter, $subscriber, $extra_params);
|
$mailer = $this->configureMailerWithMessage($newsletter, $subscriber, $extra_params);
|
||||||
$result = $mailer->send();
|
$result = $mailer->send();
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return Mailer::formatMailerSendErrorResult($e->getMessage());
|
return Mailer::formatMailerErrorResult($this->error_mapper->getErrorFromException($e, $subscriber));
|
||||||
}
|
}
|
||||||
if($result === true) {
|
if($result === true) {
|
||||||
return Mailer::formatMailerSendSuccessResult();
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
} else {
|
} else {
|
||||||
$result = sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_PHPMAIL);
|
$error = $this->error_mapper->getErrorForSubscriber($subscriber);
|
||||||
if(empty($extra_params['test_email'])) {
|
return Mailer::formatMailerErrorResult($error);
|
||||||
$result .= sprintf(' %s: %s', __('Unprocessed subscriber', 'mailpoet'), $subscriber);
|
|
||||||
}
|
|
||||||
return Mailer::formatMailerSendErrorResult($result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace MailPoet\Mailer\Methods;
|
namespace MailPoet\Mailer\Methods;
|
||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SMTPMapper;
|
||||||
use MailPoet\WP\Hooks;
|
use MailPoet\WP\Hooks;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
@ -19,9 +20,12 @@ class SMTP {
|
|||||||
public $mailer;
|
public $mailer;
|
||||||
const SMTP_CONNECTION_TIMEOUT = 15; // seconds
|
const SMTP_CONNECTION_TIMEOUT = 15; // seconds
|
||||||
|
|
||||||
|
/** @var SMTPMapper */
|
||||||
|
private $error_mapper;
|
||||||
|
|
||||||
function __construct(
|
function __construct(
|
||||||
$host, $port, $authentication, $login = null, $password = null, $encryption,
|
$host, $port, $authentication, $login = null, $password = null, $encryption,
|
||||||
$sender, $reply_to, $return_path) {
|
$sender, $reply_to, $return_path, SMTPMapper $error_mapper) {
|
||||||
$this->host = $host;
|
$this->host = $host;
|
||||||
$this->port = $port;
|
$this->port = $port;
|
||||||
$this->authentication = $authentication;
|
$this->authentication = $authentication;
|
||||||
@ -36,6 +40,7 @@ class SMTP {
|
|||||||
$this->mailer = $this->buildMailer();
|
$this->mailer = $this->buildMailer();
|
||||||
$this->mailer_logger = new \Swift_Plugins_Loggers_ArrayLogger();
|
$this->mailer_logger = new \Swift_Plugins_Loggers_ArrayLogger();
|
||||||
$this->mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($this->mailer_logger));
|
$this->mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($this->mailer_logger));
|
||||||
|
$this->error_mapper = $error_mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($newsletter, $subscriber, $extra_params = array()) {
|
function send($newsletter, $subscriber, $extra_params = array()) {
|
||||||
@ -43,13 +48,16 @@ class SMTP {
|
|||||||
$message = $this->createMessage($newsletter, $subscriber, $extra_params);
|
$message = $this->createMessage($newsletter, $subscriber, $extra_params);
|
||||||
$result = $this->mailer->send($message);
|
$result = $this->mailer->send($message);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
return Mailer::formatMailerSendErrorResult(
|
return Mailer::formatMailerErrorResult(
|
||||||
$this->processExceptionMessage($e->getMessage())
|
$this->error_mapper->getErrorFromException($e, $subscriber)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ($result === 1) ?
|
if($result === 1) {
|
||||||
Mailer::formatMailerSendSuccessResult() :
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
Mailer::formatMailerSendErrorResult($this->processLogMessage($subscriber, $extra_params));
|
} else {
|
||||||
|
$error = $this->error_mapper->getErrorFromLog($this->mailer_logger->dump(), $subscriber);
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildMailer() {
|
function buildMailer() {
|
||||||
@ -107,27 +115,4 @@ class SMTP {
|
|||||||
(isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
|
(isset($subscriber_data['name'])) ? $subscriber_data['name'] : ''
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function processLogMessage($subscriber, $extra_params = array(), $log = false) {
|
|
||||||
$log = ($log) ? $log : $this->mailer_logger->dump();
|
|
||||||
// extract error message from log
|
|
||||||
preg_match('/!! (.*?)>>/ism', $log, $message);
|
|
||||||
if(!empty($message[1])) {
|
|
||||||
$message = $message[1];
|
|
||||||
// remove line breaks from the message due to how logger's dump() method works
|
|
||||||
$message = preg_replace('/\r|\n/', '', $message);
|
|
||||||
} else {
|
|
||||||
$message = sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_SMTP);
|
|
||||||
}
|
|
||||||
if(empty($extra_params['test_email'])) {
|
|
||||||
$message .= sprintf(' %s: %s', __('Unprocessed subscriber', 'mailpoet'), $subscriber);
|
|
||||||
}
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processExceptionMessage($message) {
|
|
||||||
// remove redundant information appended by Swift logger to exception messages
|
|
||||||
$message = explode(PHP_EOL, $message);
|
|
||||||
return $message[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Mailer\Methods;
|
namespace MailPoet\Mailer\Methods;
|
||||||
|
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SendGridMapper;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
@ -13,10 +14,14 @@ class SendGrid {
|
|||||||
public $sender;
|
public $sender;
|
||||||
public $reply_to;
|
public $reply_to;
|
||||||
|
|
||||||
function __construct($api_key, $sender, $reply_to) {
|
/** @var SendGridMapper */
|
||||||
|
private $error_mapper;
|
||||||
|
|
||||||
|
function __construct($api_key, $sender, $reply_to, SendGridMapper $error_mapper) {
|
||||||
$this->api_key = $api_key;
|
$this->api_key = $api_key;
|
||||||
$this->sender = $sender;
|
$this->sender = $sender;
|
||||||
$this->reply_to = $reply_to;
|
$this->reply_to = $reply_to;
|
||||||
|
$this->error_mapper = $error_mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send($newsletter, $subscriber, $extra_params = array()) {
|
function send($newsletter, $subscriber, $extra_params = array()) {
|
||||||
@ -25,17 +30,13 @@ class SendGrid {
|
|||||||
$this->request($newsletter, $subscriber, $extra_params)
|
$this->request($newsletter, $subscriber, $extra_params)
|
||||||
);
|
);
|
||||||
if(is_wp_error($result)) {
|
if(is_wp_error($result)) {
|
||||||
return Mailer::formatMailerConnectionErrorResult($result->get_error_message());
|
$error = $this->error_mapper->getConnectionError($result->get_error_message());
|
||||||
|
return Mailer::formatMailerErrorResult($error);
|
||||||
}
|
}
|
||||||
if(WPFunctions::wpRemoteRetrieveResponseCode($result) !== 200) {
|
if(WPFunctions::wpRemoteRetrieveResponseCode($result) !== 200) {
|
||||||
$response = json_decode($result['body'], true);
|
$response = json_decode($result['body'], true);
|
||||||
$response = (!empty($response['errors'][0])) ?
|
$error = $this->error_mapper->getErrorFromResponse($response, $subscriber);
|
||||||
$response['errors'][0] :
|
return Mailer::formatMailerErrorResult($error);
|
||||||
sprintf(__('%s has returned an unknown error.', 'mailpoet'), Mailer::METHOD_SENDGRID);
|
|
||||||
if(empty($extra_params['test_email'])) {
|
|
||||||
$response .= sprintf(' %s: %s', __('Unprocessed subscriber', 'mailpoet'), $subscriber);
|
|
||||||
}
|
|
||||||
return Mailer::formatMailerSendErrorResult($response);
|
|
||||||
}
|
}
|
||||||
return Mailer::formatMailerSendSuccessResult();
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
}
|
}
|
||||||
|
38
lib/Mailer/SubscriberError.php
Normal file
38
lib/Mailer/SubscriberError.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Mailer;
|
||||||
|
|
||||||
|
class SubscriberError {
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $email;
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param string $message|null
|
||||||
|
*/
|
||||||
|
function __construct($email, $message = null) {
|
||||||
|
$this->email = $email;
|
||||||
|
$this->message = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getEmail() {
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
function getMessage() {
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __toString() {
|
||||||
|
return $this->message ? $this->email . ': ' . $this->message : $this->email;
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,9 @@ class ScheduledTaskSubscriber extends Model {
|
|||||||
const STATUS_UNPROCESSED = 0;
|
const STATUS_UNPROCESSED = 0;
|
||||||
const STATUS_PROCESSED = 1;
|
const STATUS_PROCESSED = 1;
|
||||||
|
|
||||||
|
const FAIL_STATUS_OK = 0;
|
||||||
|
const FAIL_STATUS_FAILED = 1;
|
||||||
|
|
||||||
public static $_table = MP_SCHEDULED_TASK_SUBSCRIBERS_TABLE;
|
public static $_table = MP_SCHEDULED_TASK_SUBSCRIBERS_TABLE;
|
||||||
public static $_id_column = array('task_id', 'subscriber_id');
|
public static $_id_column = array('task_id', 'subscriber_id');
|
||||||
|
|
||||||
@ -19,6 +22,7 @@ class ScheduledTaskSubscriber extends Model {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$data['processed'] = !empty($data['processed']) ? self::STATUS_PROCESSED : self::STATUS_UNPROCESSED;
|
$data['processed'] = !empty($data['processed']) ? self::STATUS_PROCESSED : self::STATUS_UNPROCESSED;
|
||||||
|
$data['failed'] = !empty($data['failed']) ? self::FAIL_STATUS_FAILED : self::FAIL_STATUS_OK;
|
||||||
return parent::_createOrUpdate($data, array(
|
return parent::_createOrUpdate($data, array(
|
||||||
'subscriber_id' => $data['subscriber_id'],
|
'subscriber_id' => $data['subscriber_id'],
|
||||||
'task_id' => $data['task_id']
|
'task_id' => $data['task_id']
|
||||||
|
@ -166,6 +166,11 @@ class Sending {
|
|||||||
return $this->updateCount()->getErrors() === false;
|
return $this->updateCount()->getErrors() === false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveSubscriberError($subcriber_id, $error_message) {
|
||||||
|
$this->task_subscribers->saveSubscriberError($subcriber_id, $error_message);
|
||||||
|
return $this->updateCount()->getErrors() === false;
|
||||||
|
}
|
||||||
|
|
||||||
function updateCount() {
|
function updateCount() {
|
||||||
$this->queue->count_processed = ScheduledTaskSubscriber::getProcessedCount($this->task->id);
|
$this->queue->count_processed = ScheduledTaskSubscriber::getProcessedCount($this->task->id);
|
||||||
$this->queue->count_to_process = ScheduledTaskSubscriber::getUnprocessedCount($this->task->id);
|
$this->queue->count_to_process = ScheduledTaskSubscriber::getUnprocessedCount($this->task->id);
|
||||||
|
@ -53,6 +53,15 @@ class Subscribers {
|
|||||||
$this->checkCompleted();
|
$this->checkCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveSubscriberError($subcriber_id, $error_message) {
|
||||||
|
$this->getSubscribers()
|
||||||
|
->where('subscriber_id', $subcriber_id)
|
||||||
|
->findResultSet()
|
||||||
|
->set('failed', ScheduledTaskSubscriber::FAIL_STATUS_FAILED)
|
||||||
|
->set('error', $error_message)
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
|
||||||
private function checkCompleted($count = null) {
|
private function checkCompleted($count = null) {
|
||||||
if(!$count && !ScheduledTaskSubscriber::getUnprocessedCount($this->task->id)) {
|
if(!$count && !ScheduledTaskSubscriber::getUnprocessedCount($this->task->id)) {
|
||||||
$this->task->complete();
|
$this->task->complete();
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Cron\Workers;
|
||||||
|
|
||||||
|
use Codeception\Stub;
|
||||||
|
use Codeception\Stub\Expected;
|
||||||
|
use MailPoet\Cron\Workers\SendingQueue\SendingErrorHandler;
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
use MailPoet\Tasks\Sending as SendingTask;
|
||||||
|
|
||||||
|
class SendingErrorHandlerTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/** @var SendingErrorHandler */
|
||||||
|
private $error_handler;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->error_handler = new SendingErrorHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItShouldProcessSoftErrorCorrectly() {
|
||||||
|
$subscribers = [
|
||||||
|
'john@doe.com',
|
||||||
|
'john@rambo.com',
|
||||||
|
];
|
||||||
|
$subscriber_ids = [1, 2];
|
||||||
|
$subscriber_errors = [
|
||||||
|
new SubscriberError('john@doe.com', 'Subscriber Message'),
|
||||||
|
new SubscriberError('john@rambo.com', null),
|
||||||
|
];
|
||||||
|
$error = new MailerError(
|
||||||
|
MailerError::OPERATION_SEND,
|
||||||
|
MailerError::LEVEL_SOFT,
|
||||||
|
'Error Message',
|
||||||
|
null, $subscriber_errors
|
||||||
|
);
|
||||||
|
|
||||||
|
$sending_task = Stub::make(
|
||||||
|
SendingTask::class,
|
||||||
|
[
|
||||||
|
'saveSubscriberError' => Expected::exactly(
|
||||||
|
2,
|
||||||
|
function($id, $message) {
|
||||||
|
if($id === 2) {
|
||||||
|
expect($message)->equals('Error Message');
|
||||||
|
} else {
|
||||||
|
expect($message)->equals('Subscriber Message');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
$this
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->error_handler->processError($error, $sending_task, $subscriber_ids, $subscribers);
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ use Codeception\Util\Fixtures;
|
|||||||
use Codeception\Stub;
|
use Codeception\Stub;
|
||||||
use Codeception\Stub\Expected;
|
use Codeception\Stub\Expected;
|
||||||
use MailPoet\Config\Populator;
|
use MailPoet\Config\Populator;
|
||||||
|
use MailPoet\Cron\Workers\SendingQueue\SendingErrorHandler;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
|
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
|
||||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
||||||
@ -32,6 +33,9 @@ use MailPoet\Tasks\Sending as SendingTask;
|
|||||||
use MailPoet\WP\Hooks;
|
use MailPoet\WP\Hooks;
|
||||||
|
|
||||||
class SendingQueueTest extends \MailPoetTest {
|
class SendingQueueTest extends \MailPoetTest {
|
||||||
|
/** @var SendingErrorHandler */
|
||||||
|
private $sending_error_handler;
|
||||||
|
|
||||||
function _before() {
|
function _before() {
|
||||||
$wp_users = get_users();
|
$wp_users = get_users();
|
||||||
wp_set_current_user($wp_users[0]->ID);
|
wp_set_current_user($wp_users[0]->ID);
|
||||||
@ -71,7 +75,8 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
$this->newsletter_link->url = '[link:subscription_unsubscribe_url]';
|
$this->newsletter_link->url = '[link:subscription_unsubscribe_url]';
|
||||||
$this->newsletter_link->hash = 'abcde';
|
$this->newsletter_link->hash = 'abcde';
|
||||||
$this->newsletter_link->save();
|
$this->newsletter_link->save();
|
||||||
$this->sending_queue_worker = new SendingQueueWorker();
|
$this->sending_error_handler = new SendingErrorHandler();
|
||||||
|
$this->sending_queue_worker = new SendingQueueWorker($this->sending_error_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDirectUnsubscribeURL() {
|
private function getDirectUnsubscribeURL() {
|
||||||
@ -101,20 +106,20 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
// constructor accepts timer argument
|
// constructor accepts timer argument
|
||||||
$timer = microtime(true) - 5;
|
$timer = microtime(true) - 5;
|
||||||
$sending_queue_worker = new SendingQueueWorker($timer);
|
$sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $timer);
|
||||||
expect($sending_queue_worker->timer)->equals($timer);
|
expect($sending_queue_worker->timer)->equals($timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItEnforcesExecutionLimitsBeforeQueueProcessing() {
|
function testItEnforcesExecutionLimitsBeforeQueueProcessing() {
|
||||||
$sending_queue_worker = Stub::make(
|
$sending_queue_worker = Stub::make(
|
||||||
new SendingQueueWorker(),
|
new SendingQueueWorker($this->sending_error_handler),
|
||||||
array(
|
array(
|
||||||
'processQueue' => Expected::never(),
|
'processQueue' => Expected::never(),
|
||||||
'enforceSendingAndExecutionLimits' => Expected::exactly(1, function() {
|
'enforceSendingAndExecutionLimits' => Expected::exactly(1, function() {
|
||||||
throw new \Exception();
|
throw new \Exception();
|
||||||
})
|
})
|
||||||
), $this);
|
), $this);
|
||||||
$sending_queue_worker->__construct();
|
$sending_queue_worker->__construct($this->sending_error_handler);
|
||||||
try {
|
try {
|
||||||
$sending_queue_worker->process();
|
$sending_queue_worker->process();
|
||||||
self::fail('Execution limits function was not called.');
|
self::fail('Execution limits function was not called.');
|
||||||
@ -125,24 +130,25 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItEnforcesExecutionLimitsAfterSendingWhenQueueStatusIsNotSetToComplete() {
|
function testItEnforcesExecutionLimitsAfterSendingWhenQueueStatusIsNotSetToComplete() {
|
||||||
$sending_queue_worker = Stub::make(
|
$sending_queue_worker = Stub::make(
|
||||||
new SendingQueueWorker(),
|
new SendingQueueWorker($this->sending_error_handler),
|
||||||
array(
|
array(
|
||||||
'enforceSendingAndExecutionLimits' => Expected::exactly(1)
|
'enforceSendingAndExecutionLimits' => Expected::exactly(1)
|
||||||
), $this);
|
), $this);
|
||||||
$sending_queue_worker->__construct(
|
$sending_queue_worker->__construct(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
array(
|
array(
|
||||||
'send' => null
|
'sendBulk' => null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$sending_queue_worker->sendNewsletters(
|
$sending_queue_worker->sendNewsletters(
|
||||||
$this->queue,
|
$this->queue,
|
||||||
$prepared_subscribers = array(),
|
$prepared_subscribers = array(),
|
||||||
$prepared_newsletters = false,
|
$prepared_newsletters = [],
|
||||||
$prepared_subscribers = false,
|
$prepared_subscribers = [],
|
||||||
$statistics[] = array(
|
$statistics[] = array(
|
||||||
'newsletter_id' => 1,
|
'newsletter_id' => 1,
|
||||||
'subscriber_id' => 1,
|
'subscriber_id' => 1,
|
||||||
@ -158,16 +164,17 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
$queue = $this->queue;
|
$queue = $this->queue;
|
||||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||||
$sending_queue_worker = Stub::make(
|
$sending_queue_worker = Stub::make(
|
||||||
new SendingQueueWorker(),
|
new SendingQueueWorker($this->sending_error_handler),
|
||||||
array(
|
array(
|
||||||
'enforceSendingAndExecutionLimits' => Expected::never()
|
'enforceSendingAndExecutionLimits' => Expected::never()
|
||||||
), $this);
|
), $this);
|
||||||
$sending_queue_worker->__construct(
|
$sending_queue_worker->__construct(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
array(
|
array(
|
||||||
'send' => null
|
'sendBulk' => null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -186,7 +193,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItEnforcesExecutionLimitsAfterQueueProcessing() {
|
function testItEnforcesExecutionLimitsAfterQueueProcessing() {
|
||||||
$sending_queue_worker = Stub::make(
|
$sending_queue_worker = Stub::make(
|
||||||
new SendingQueueWorker(),
|
new SendingQueueWorker($this->sending_error_handler),
|
||||||
array(
|
array(
|
||||||
'processQueue' => function() {
|
'processQueue' => function() {
|
||||||
// this function returns a queue object
|
// this function returns a queue object
|
||||||
@ -194,7 +201,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
},
|
},
|
||||||
'enforceSendingAndExecutionLimits' => Expected::exactly(2)
|
'enforceSendingAndExecutionLimits' => Expected::exactly(2)
|
||||||
), $this);
|
), $this);
|
||||||
$sending_queue_worker->__construct();
|
$sending_queue_worker->__construct($this->sending_error_handler);
|
||||||
$sending_queue_worker->process();
|
$sending_queue_worker->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +224,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
Setting::setValue('tracking.enabled', false);
|
Setting::setValue('tracking.enabled', false);
|
||||||
$directUnsubscribeURL = $this->getDirectUnsubscribeURL();
|
$directUnsubscribeURL = $this->getDirectUnsubscribeURL();
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -237,6 +245,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
Setting::setValue('tracking.enabled', true);
|
Setting::setValue('tracking.enabled', true);
|
||||||
$trackedUnsubscribeURL = $this->getTrackedUnsubscribeURL();
|
$trackedUnsubscribeURL = $this->getTrackedUnsubscribeURL();
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -255,6 +264,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItCanProcessSubscribersOneByOne() {
|
function testItCanProcessSubscribersOneByOne() {
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -298,11 +308,12 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItCanProcessSubscribersInBulk() {
|
function testItCanProcessSubscribersInBulk() {
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
array(
|
array(
|
||||||
'send' => Expected::exactly(1, function($newsletter, $subscriber) {
|
'sendBulk' => Expected::exactly(1, function($newsletter, $subscriber) {
|
||||||
// newsletter body should not be empty
|
// newsletter body should not be empty
|
||||||
expect(!empty($newsletter[0]['body']['html']))->true();
|
expect(!empty($newsletter[0]['body']['html']))->true();
|
||||||
expect(!empty($newsletter[0]['body']['text']))->true();
|
expect(!empty($newsletter[0]['body']['text']))->true();
|
||||||
@ -344,6 +355,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItProcessesStandardNewsletters() {
|
function testItProcessesStandardNewsletters() {
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -397,6 +409,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
$this->newsletter_segment->delete();
|
$this->newsletter_segment->delete();
|
||||||
|
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::makeEmpty(new MailerTask(), array(), $this)
|
Stub::makeEmpty(new MailerTask(), array(), $this)
|
||||||
);
|
);
|
||||||
@ -411,6 +424,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
$this->newsletter_segment->delete();
|
$this->newsletter_segment->delete();
|
||||||
|
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -573,27 +587,28 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testItPausesSendingWhenProcessedSubscriberListCannotBeUpdated() {
|
function testItPausesSendingWhenProcessedSubscriberListCannotBeUpdated() {
|
||||||
$queue = Mock::double(new \stdClass(), array(
|
$sending_task = Mock::double(SendingTask::create(), array(
|
||||||
'updateProcessedSubscribers' => false
|
'updateProcessedSubscribers' => false
|
||||||
));
|
));
|
||||||
$queue->id = 100;
|
$sending_task->id = 100;
|
||||||
$sending_queue_worker = Stub::make(new SendingQueueWorker());
|
$sending_queue_worker = Stub::make(new SendingQueueWorker($this->sending_error_handler));
|
||||||
$sending_queue_worker->__construct(
|
$sending_queue_worker->__construct(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
array(
|
array(
|
||||||
'send' => true
|
'sendBulk' => true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
$sending_queue_worker->sendNewsletters(
|
$sending_queue_worker->sendNewsletters(
|
||||||
$queue,
|
$sending_task->getObject(),
|
||||||
$prepared_subscribers = array(),
|
$prepared_subscribers = [],
|
||||||
$prepared_newsletters = false,
|
$prepared_newsletters = [],
|
||||||
$prepared_subscribers = false,
|
$prepared_subscribers = [],
|
||||||
$statistics = false
|
$statistics = []
|
||||||
);
|
);
|
||||||
$this->fail('Paused sending exception was not thrown.');
|
$this->fail('Paused sending exception was not thrown.');
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
@ -611,6 +626,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
|
|
||||||
function testItDoesNotUpdateNewsletterHashDuringSending() {
|
function testItDoesNotUpdateNewsletterHashDuringSending() {
|
||||||
$sending_queue_worker = new SendingQueueWorker(
|
$sending_queue_worker = new SendingQueueWorker(
|
||||||
|
$this->sending_error_handler,
|
||||||
$timer = false,
|
$timer = false,
|
||||||
Stub::make(
|
Stub::make(
|
||||||
new MailerTask(),
|
new MailerTask(),
|
||||||
@ -634,7 +650,7 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
return $custom_batch_size_value;
|
return $custom_batch_size_value;
|
||||||
};
|
};
|
||||||
Hooks::addFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
|
Hooks::addFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
|
||||||
$sending_queue_worker = new SendingQueueWorker();
|
$sending_queue_worker = new SendingQueueWorker($this->sending_error_handler);
|
||||||
expect($sending_queue_worker->batch_size)->equals($custom_batch_size_value);
|
expect($sending_queue_worker->batch_size)->equals($custom_batch_size_value);
|
||||||
Hooks::removeFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
|
Hooks::removeFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,10 @@ class MailerTest extends \MailPoetTest {
|
|||||||
return true;
|
return true;
|
||||||
})),
|
})),
|
||||||
$this
|
$this
|
||||||
)
|
),
|
||||||
|
'mailer_config' => [
|
||||||
|
'method' => null,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
// mailer instance should be properly configured
|
// mailer instance should be properly configured
|
||||||
|
40
tests/unit/Mailer/MailerErrorTest.php
Normal file
40
tests/unit/Mailer/MailerErrorTest.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\SubscriberError;
|
||||||
|
|
||||||
|
class MailerErrorTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
function testItCanComposeErrorMessageWithoutSubscribers() {
|
||||||
|
$error = new MailerError(MailerError::OPERATION_SEND, MailerError::LEVEL_HARD, 'Some Message');
|
||||||
|
expect($error->getMessageWithFailedSubscribers())->equals('Some Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanComposeErrorMessageWithOneSubscriber() {
|
||||||
|
$subscriber_error = new SubscriberError('email@example.com', 'Subscriber message');
|
||||||
|
$error = new MailerError(
|
||||||
|
MailerError::OPERATION_SEND,
|
||||||
|
MailerError::LEVEL_HARD,
|
||||||
|
'Some Message',
|
||||||
|
null,
|
||||||
|
[$subscriber_error]
|
||||||
|
);
|
||||||
|
expect($error->getMessageWithFailedSubscribers())->equals('Some Message Unprocessed subscriber: (email@example.com: Subscriber message)');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanComposeErrorMessageWithMultipleSubscriberErrors() {
|
||||||
|
$subscriber_error_1 = new SubscriberError('email1@example.com', 'Subscriber 1 message');
|
||||||
|
$subscriber_error_2 = new SubscriberError('email2@example.com', null);
|
||||||
|
$error = new MailerError(
|
||||||
|
MailerError::OPERATION_SEND,
|
||||||
|
MailerError::LEVEL_HARD,
|
||||||
|
'Some Message',
|
||||||
|
null,
|
||||||
|
[$subscriber_error_1, $subscriber_error_2]
|
||||||
|
);
|
||||||
|
expect($error->getMessageWithFailedSubscribers())->equals(
|
||||||
|
'Some Message Unprocessed subscribers: (email1@example.com: Subscriber 1 message), (email2@example.com)'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Test\Mailer\Methods;
|
namespace MailPoet\Test\Mailer\Methods;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
use MailPoet\Mailer\Methods\AmazonSES;
|
use MailPoet\Mailer\Methods\AmazonSES;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||||
|
|
||||||
class AmazonSESTest extends \MailPoetTest {
|
class AmazonSESTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
@ -34,7 +36,8 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
$this->settings['secret_key'],
|
$this->settings['secret_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new AmazonSESMapper()
|
||||||
);
|
);
|
||||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||||
$this->newsletter = array(
|
$this->newsletter = array(
|
||||||
@ -69,7 +72,8 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
$this->settings['secret_key'],
|
$this->settings['secret_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$return_path = false
|
$return_path = false,
|
||||||
|
new AmazonSESMapper()
|
||||||
);
|
);
|
||||||
expect($mailer->return_path)->equals($this->sender['from_email']);
|
expect($mailer->return_path)->equals($this->sender['from_email']);
|
||||||
}
|
}
|
||||||
@ -82,7 +86,8 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
$this->settings['secret_key'],
|
$this->settings['secret_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new AmazonSESMapper()
|
||||||
);
|
);
|
||||||
$this->fail('Unsupported region exception was not thrown');
|
$this->fail('Unsupported region exception was not thrown');
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
@ -223,7 +228,8 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
$invalid_subscriber
|
$invalid_subscriber
|
||||||
);
|
);
|
||||||
expect($result['response'])->false();
|
expect($result['response'])->false();
|
||||||
expect($result['error_message'])->contains('does not comply with RFC 2822');
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
|
expect($result['error']->getMessage())->contains('does not comply with RFC 2822');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItCanSend() {
|
function testItCanSend() {
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||||
|
use SimpleXMLElement;
|
||||||
|
|
||||||
|
class AmazonSESMapperTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/** @var AmazonSESMapper*/
|
||||||
|
private $mapper;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $response_data = [];
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->mapper = new AmazonSESMapper();
|
||||||
|
$this->response_data = [
|
||||||
|
'Error' => [
|
||||||
|
'Type' => 'Sender',
|
||||||
|
'Code' => 'ConfigurationSetDoesNotExist',
|
||||||
|
'Message' => 'Some message',
|
||||||
|
],
|
||||||
|
'RequestId' => '01ca93ec-b5a3-11e8-bff8-49dd5ddf8019',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetProperError() {
|
||||||
|
$response = $this->buildXmlResponseFromArray($this->response_data, new SimpleXMLElement('<response/>'));
|
||||||
|
$error = $this->mapper->getErrorFromResponse($response, 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('Some message');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail())->equals('john@rambo.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetSoftErrorForRejectedMessage() {
|
||||||
|
$this->response_data['Error']['Code'] = 'MessageRejected';
|
||||||
|
$response = $this->buildXmlResponseFromArray($this->response_data, new SimpleXMLElement('<response/>'));
|
||||||
|
$error = $this->mapper->getErrorFromResponse($response, 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_SOFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SimpleXMLElement
|
||||||
|
*/
|
||||||
|
private function buildXmlResponseFromArray($response_data, SimpleXMLElement $xml) {
|
||||||
|
foreach($response_data as $tag => $value) {
|
||||||
|
if(is_array($value)) {
|
||||||
|
$this->buildXmlResponseFromArray($value, $xml->addChild($tag));
|
||||||
|
} else {
|
||||||
|
$xml->addChild($tag, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper;
|
||||||
|
use MailPoet\Services\Bridge\API;
|
||||||
|
|
||||||
|
class MailPoetMapperTest extends \MailPoetTest {
|
||||||
|
/** @var MailPoetMapper */
|
||||||
|
private $mapper;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $subscribers;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->mapper = new MailPoetMapper();
|
||||||
|
$this->subscribers = ['a@example.com', 'c d <b@example.com>'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateConnectionError() {
|
||||||
|
$error = $this->mapper->getConnectionError('connection error');
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_CONNECT);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('connection error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetErrorNotArray() {
|
||||||
|
$api_result = [
|
||||||
|
'code' => API::RESPONSE_CODE_NOT_ARRAY,
|
||||||
|
'status' => API::SENDING_STATUS_SEND_ERROR,
|
||||||
|
'message' => 'error not array',
|
||||||
|
];
|
||||||
|
$error = $this->mapper->getErrorForResult($api_result, $this->subscribers);
|
||||||
|
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('JSON input is not an array');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetErrorPayloadTooBig() {
|
||||||
|
$api_result = [
|
||||||
|
'code' => API::RESPONSE_CODE_PAYLOAD_TOO_BIG,
|
||||||
|
'status' => API::SENDING_STATUS_SEND_ERROR,
|
||||||
|
'message' => 'error too big',
|
||||||
|
];
|
||||||
|
$error = $this->mapper->getErrorForResult($api_result, $this->subscribers);
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('error too big');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetPayloadError() {
|
||||||
|
$api_result = [
|
||||||
|
'code' => API::RESPONSE_CODE_PAYLOAD_ERROR,
|
||||||
|
'status' => API::SENDING_STATUS_SEND_ERROR,
|
||||||
|
'message' => 'Api Error',
|
||||||
|
];
|
||||||
|
$error = $this->mapper->getErrorForResult($api_result, $this->subscribers);
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('Error while sending. Api Error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetPayloadErrorWithErrorMessage() {
|
||||||
|
$api_result = [
|
||||||
|
'code' => API::RESPONSE_CODE_PAYLOAD_ERROR,
|
||||||
|
'status' => API::SENDING_STATUS_SEND_ERROR,
|
||||||
|
'message' => '[{"index":0,"errors":{"subject":"subject is missing"}},{"index":1,"errors":{"subject":"subject is missing"}}]'
|
||||||
|
];
|
||||||
|
$error = $this->mapper->getErrorForResult($api_result, $this->subscribers);
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_SOFT);
|
||||||
|
$subscriber_errors = $error->getSubscriberErrors();
|
||||||
|
expect(count($subscriber_errors))->equals(2);
|
||||||
|
expect($subscriber_errors[0]->getEmail())->equals('a@example.com');
|
||||||
|
expect($subscriber_errors[0]->getMessage())->equals('subject is missing');
|
||||||
|
expect($subscriber_errors[1]->getEmail())->equals('c d <b@example.com>');
|
||||||
|
expect($subscriber_errors[1]->getMessage())->equals('subject is missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetPayloadErrorForMalformedMSSResponse() {
|
||||||
|
$api_result = [
|
||||||
|
'code' => API::RESPONSE_CODE_PAYLOAD_ERROR,
|
||||||
|
'status' => API::SENDING_STATUS_SEND_ERROR,
|
||||||
|
'message' => '[{"errors":{"subject":"subject is missing"}},{"errors":{"subject":"subject is missing"}}]'
|
||||||
|
];
|
||||||
|
$error = $this->mapper->getErrorForResult($api_result, $this->subscribers);
|
||||||
|
expect($error)->isInstanceOf(MailerError::class);
|
||||||
|
expect($error->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('Error while sending. Invalid MSS response format.');
|
||||||
|
}
|
||||||
|
}
|
34
tests/unit/Mailer/Methods/ErrorMappers/PHPMailMapperTest.php
Normal file
34
tests/unit/Mailer/Methods/ErrorMappers/PHPMailMapperTest.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\PHPMailMapper;
|
||||||
|
|
||||||
|
class PHPMailMapperTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/** @var PHPMailMapper*/
|
||||||
|
private $mapper;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->mapper = new PHPMailMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetProperErrorForSubscriber() {
|
||||||
|
$error = $this->mapper->getErrorForSubscriber('john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('PHPMail has returned an unknown error.');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail())->equals('john@rambo.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetProperErrorFromException() {
|
||||||
|
$error = $this->mapper->getErrorFromException(new \Exception('Some message'), 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('Some message');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail())->equals('john@rambo.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetSoftErrorFromExceptionForInvalidEmail() {
|
||||||
|
$error = $this->mapper->getErrorFromException(new \Exception('Invalid address. (Add ...'), 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_SOFT);
|
||||||
|
}
|
||||||
|
}
|
57
tests/unit/Mailer/Methods/ErrorMappers/SMTPMapperTest.php
Normal file
57
tests/unit/Mailer/Methods/ErrorMappers/SMTPMapperTest.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SMTPMapper;
|
||||||
|
|
||||||
|
class SMTPMapperTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/** @var SMTPMapper */
|
||||||
|
private $mapper;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->mapper = new SMTPMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanProcessExceptionMessage() {
|
||||||
|
$message = 'Connection could not be established with host localhost [Connection refused #111]' . PHP_EOL
|
||||||
|
. 'Log data:' . PHP_EOL
|
||||||
|
. '++ Starting Swift_SmtpTransport' . PHP_EOL
|
||||||
|
. '!! Connection could not be established with host localhost [Connection refused #111] (code: 0)';
|
||||||
|
$error = $this->mapper->getErrorFromException(new \Exception($message), 'john@rambo.com');
|
||||||
|
expect($error->getMessage())
|
||||||
|
->equals('Connection could not be established with host localhost [Connection refused #111]');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail())->equals('john@rambo.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCreatesSoftErrorForInvalidEmail() {
|
||||||
|
$message = 'Invalid email';
|
||||||
|
$error = $this->mapper->getErrorFromException(new \Swift_RfcComplianceException($message), 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_SOFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanProcessLogMessageWhenOneExists() {
|
||||||
|
$log = '++ Swift_SmtpTransport started' . PHP_EOL
|
||||||
|
. '>> MAIL FROM:<moi@mrcasual.com>' . PHP_EOL
|
||||||
|
. '<< 250 OK' . PHP_EOL
|
||||||
|
. '>> RCPT TO:<test2@ietsdoenofferte.nl>' . PHP_EOL
|
||||||
|
. '<< 550 No such recipient here' . PHP_EOL
|
||||||
|
. '!! Expected response code 250/251/252 but got code "550", with message "550 No such recipient here' . PHP_EOL
|
||||||
|
. '" (code: 550)' . PHP_EOL
|
||||||
|
. '>> RSET' . PHP_EOL
|
||||||
|
. '<< 250 Reset OK' . PHP_EOL;
|
||||||
|
$error = $this->mapper->getErrorFromLog($log, 'test@example.com');
|
||||||
|
expect($error->getMessage())
|
||||||
|
->equals('Expected response code 250/251/252 but got code "550", with message "550 No such recipient here" (code: 550)');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail('moi@mrcasual.com'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItReturnsGenericMessageWhenLogMessageDoesNotExist() {
|
||||||
|
$error = $this->mapper->getErrorFromLog(null, 'test@example.com');
|
||||||
|
expect($error->getMessage())
|
||||||
|
->equals(Mailer::METHOD_SMTP . ' has returned an unknown error.');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail('moi@mrcasual.com'));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Test\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SendGridMapper;
|
||||||
|
|
||||||
|
class SendGridMapperTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
/** @var SendGridMapper*/
|
||||||
|
private $mapper;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $response = [];
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->mapper = new SendGridMapper();
|
||||||
|
$this->response = [
|
||||||
|
'errors' => [
|
||||||
|
'Some message',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetProperError() {
|
||||||
|
$error = $this->mapper->getErrorFromResponse($this->response, 'john@rambo.com');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_HARD);
|
||||||
|
expect($error->getMessage())->equals('Some message');
|
||||||
|
expect($error->getSubscriberErrors()[0]->getEmail())->equals('john@rambo.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetSoftErrorForInvalidEmail() {
|
||||||
|
$this->response['errors'][0] = 'Invalid email address ,,@';
|
||||||
|
$error = $this->mapper->getErrorFromResponse($this->response, ',,@');
|
||||||
|
expect($error->getLevel())->equals(MailerError::LEVEL_SOFT);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,8 @@ namespace MailPoet\Test\Mailer\Methods;
|
|||||||
|
|
||||||
use Codeception\Util\Stub;
|
use Codeception\Util\Stub;
|
||||||
use MailPoet\Config\ServicesChecker;
|
use MailPoet\Config\ServicesChecker;
|
||||||
|
use MailPoet\Mailer\MailerError;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper;
|
||||||
use MailPoet\Mailer\Methods\MailPoet;
|
use MailPoet\Mailer\Methods\MailPoet;
|
||||||
use MailPoet\Services\Bridge\API;
|
use MailPoet\Services\Bridge\API;
|
||||||
|
|
||||||
@ -27,7 +29,8 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this->mailer = new MailPoet(
|
$this->mailer = new MailPoet(
|
||||||
$this->settings['api_key'],
|
$this->settings['api_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to
|
$this->reply_to,
|
||||||
|
new MailPoetMapper()
|
||||||
);
|
);
|
||||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||||
$this->newsletter = array(
|
$this->newsletter = array(
|
||||||
@ -161,11 +164,9 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
||||||
expect($result)->equals([
|
expect($result['response'])->false();
|
||||||
'response' => false,
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
'operation' => 'connect',
|
expect($result['error']->getOperation())->equals(MailerError::OPERATION_CONNECT);
|
||||||
'error_message' => 'connection error',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFormatErrorNotArray() {
|
function testFormatErrorNotArray() {
|
||||||
@ -179,11 +180,9 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
||||||
expect($result)->equals([
|
expect($result['response'])->false();
|
||||||
'response' => false,
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
'operation' => 'send',
|
expect($result['error']->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
'error_message' => 'JSON input is not an array',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFormatErrorTooBig() {
|
function testFormatErrorTooBig() {
|
||||||
@ -197,11 +196,8 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
$result = $this->mailer->send($this->newsletter, $this->subscriber);
|
||||||
expect($result)->equals([
|
expect($result['response'])->false();
|
||||||
'response' => false,
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
'operation' => 'send',
|
|
||||||
'error_message' => 'error too big',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFormatPayloadError() {
|
function testFormatPayloadError() {
|
||||||
@ -215,11 +211,9 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$result = $this->mailer->send([$this->newsletter, $this->newsletter], ['a@example.com', 'c d <b@example.com>']);
|
$result = $this->mailer->send([$this->newsletter, $this->newsletter], ['a@example.com', 'c d <b@example.com>']);
|
||||||
expect($result)->equals([
|
expect($result['response'])->false();
|
||||||
'response' => false,
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
'operation' => 'send',
|
expect($result['error']->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
'error_message' => 'Error while sending newsletters. Api Error',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFormatPayloadErrorWithErrorMessage() {
|
function testFormatPayloadErrorWithErrorMessage() {
|
||||||
@ -233,12 +227,8 @@ class MailPoetAPITest extends \MailPoetTest {
|
|||||||
$this
|
$this
|
||||||
);
|
);
|
||||||
$result = $this->mailer->send([$this->newsletter, $this->newsletter], ['a@example.com', 'c d <b@example.com>']);
|
$result = $this->mailer->send([$this->newsletter, $this->newsletter], ['a@example.com', 'c d <b@example.com>']);
|
||||||
expect($result)->equals([
|
expect($result['response'])->false();
|
||||||
'response' => false,
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
'operation' => 'send',
|
expect($result['error']->getOperation())->equals(MailerError::OPERATION_SEND);
|
||||||
'error_message' => 'Error while sending: (a@example.com: subject is missing), (c d <b@example.com>: subject is missing)',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Test\Mailer\Methods;
|
namespace MailPoet\Test\Mailer\Methods;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\PHPMailMapper;
|
||||||
use MailPoet\Mailer\Methods\PHPMail;
|
use MailPoet\Mailer\Methods\PHPMail;
|
||||||
|
|
||||||
class PHPMailTest extends \MailPoetTest {
|
class PHPMailTest extends \MailPoetTest {
|
||||||
@ -19,7 +20,8 @@ class PHPMailTest extends \MailPoetTest {
|
|||||||
$this->mailer = new PHPMail(
|
$this->mailer = new PHPMail(
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new PHPMailMapper()
|
||||||
);
|
);
|
||||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||||
$this->newsletter = array(
|
$this->newsletter = array(
|
||||||
@ -44,7 +46,8 @@ class PHPMailTest extends \MailPoetTest {
|
|||||||
$mailer = new PHPMail(
|
$mailer = new PHPMail(
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$return_path = false
|
$return_path = false,
|
||||||
|
new PHPMailMapper()
|
||||||
);
|
);
|
||||||
expect($mailer->return_path)->equals($this->sender['from_email']);
|
expect($mailer->return_path)->equals($this->sender['from_email']);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ namespace MailPoet\Test\Mailer\Methods;
|
|||||||
|
|
||||||
use Helper\WordPressHooks as WPHooksHelper;
|
use Helper\WordPressHooks as WPHooksHelper;
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SMTPMapper;
|
||||||
use MailPoet\Mailer\Methods\SMTP;
|
use MailPoet\Mailer\Methods\SMTP;
|
||||||
use MailPoet\WP\Hooks;
|
use MailPoet\WP\Hooks;
|
||||||
|
|
||||||
@ -43,7 +44,8 @@ class SMTPTest extends \MailPoetTest {
|
|||||||
$this->settings['encryption'],
|
$this->settings['encryption'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$this->return_path
|
$this->return_path,
|
||||||
|
new SMTPMapper()
|
||||||
);
|
);
|
||||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||||
$this->newsletter = array(
|
$this->newsletter = array(
|
||||||
@ -82,7 +84,8 @@ class SMTPTest extends \MailPoetTest {
|
|||||||
$this->settings['encryption'],
|
$this->settings['encryption'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to,
|
$this->reply_to,
|
||||||
$return_path = false
|
$return_path = false,
|
||||||
|
new SMTPMapper()
|
||||||
);
|
);
|
||||||
expect($mailer->return_path)->equals($this->sender['from_email']);
|
expect($mailer->return_path)->equals($this->sender['from_email']);
|
||||||
}
|
}
|
||||||
@ -128,36 +131,6 @@ class SMTPTest extends \MailPoetTest {
|
|||||||
expect($result['response'])->false();
|
expect($result['response'])->false();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItCanProcessExceptionMessage() {
|
|
||||||
$message = 'Connection could not be established with host localhost [Connection refused #111]' . PHP_EOL
|
|
||||||
. 'Log data:' . PHP_EOL
|
|
||||||
. '++ Starting Swift_SmtpTransport' . PHP_EOL
|
|
||||||
. '!! Connection could not be established with host localhost [Connection refused #111] (code: 0)';
|
|
||||||
expect($this->mailer->processExceptionMessage($message))
|
|
||||||
->equals('Connection could not be established with host localhost [Connection refused #111]');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanProcessLogMessageWhenOneExists() {
|
|
||||||
$message = '++ Swift_SmtpTransport started' . PHP_EOL
|
|
||||||
. '>> MAIL FROM:<moi@mrcasual.com>' . PHP_EOL
|
|
||||||
. '<< 250 OK' . PHP_EOL
|
|
||||||
. '>> RCPT TO:<test2@ietsdoenofferte.nl>' . PHP_EOL
|
|
||||||
. '<< 550 No such recipient here' . PHP_EOL
|
|
||||||
. '!! Expected response code 250/251/252 but got code "550", with message "550 No such recipient here' . PHP_EOL
|
|
||||||
. '" (code: 550)' . PHP_EOL
|
|
||||||
. '>> RSET' . PHP_EOL
|
|
||||||
. '<< 250 Reset OK' . PHP_EOL;
|
|
||||||
expect($this->mailer->processLogMessage('test@example.com', $extra_params = array(), $message))
|
|
||||||
->equals('Expected response code 250/251/252 but got code "550", with message "550 No such recipient here" (code: 550) Unprocessed subscriber: test@example.com');
|
|
||||||
expect($this->mailer->processLogMessage('test@example.com', $extra_params = array(), $message))
|
|
||||||
->equals('Expected response code 250/251/252 but got code "550", with message "550 No such recipient here" (code: 550) Unprocessed subscriber: test@example.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItReturnsGenericMessageWhenLogMessageDoesNotExist() {
|
|
||||||
expect($this->mailer->processLogMessage('test@example.com'))
|
|
||||||
->equals(Mailer::METHOD_SMTP . ' has returned an unknown error. Unprocessed subscriber: test@example.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItAppliesTransportFilter() {
|
function testItAppliesTransportFilter() {
|
||||||
$mailer = $this->mailer->buildMailer();
|
$mailer = $this->mailer->buildMailer();
|
||||||
expect($mailer->getTransport()->getStreamOptions())->isEmpty();
|
expect($mailer->getTransport()->getStreamOptions())->isEmpty();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Test\Mailer\Methods;
|
namespace MailPoet\Test\Mailer\Methods;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\Methods\ErrorMappers\SendGridMapper;
|
||||||
use MailPoet\Mailer\Methods\SendGrid;
|
use MailPoet\Mailer\Methods\SendGrid;
|
||||||
|
|
||||||
class SendGridTest extends \MailPoetTest {
|
class SendGridTest extends \MailPoetTest {
|
||||||
@ -24,7 +25,8 @@ class SendGridTest extends \MailPoetTest {
|
|||||||
$this->mailer = new SendGrid(
|
$this->mailer = new SendGrid(
|
||||||
$this->settings['api_key'],
|
$this->settings['api_key'],
|
||||||
$this->sender,
|
$this->sender,
|
||||||
$this->reply_to
|
$this->reply_to,
|
||||||
|
new SendGridMapper()
|
||||||
);
|
);
|
||||||
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
|
||||||
$this->newsletter = array(
|
$this->newsletter = array(
|
||||||
|
Reference in New Issue
Block a user