Refactor confirmation email sending
Aspect mock stopped working for me so I had to create a separate service for sending confirmation emails. [MAILPOET-1522]
This commit is contained in:
@ -7,6 +7,7 @@ use MailPoet\Models\Subscriber;
|
|||||||
use MailPoet\Models\SubscriberSegment;
|
use MailPoet\Models\SubscriberSegment;
|
||||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||||
use MailPoet\Subscribers\RequiredCustomFieldValidator;
|
use MailPoet\Subscribers\RequiredCustomFieldValidator;
|
||||||
|
use MailPoet\Subscribers\SendConfirmationEmail;
|
||||||
use MailPoet\Subscribers\SendNewSubscriberNotification;
|
use MailPoet\Subscribers\SendNewSubscriberNotification;
|
||||||
use MailPoet\Subscribers\Source;
|
use MailPoet\Subscribers\Source;
|
||||||
use MailPoet\Tasks\Sending;
|
use MailPoet\Tasks\Sending;
|
||||||
@ -254,7 +255,8 @@ class API {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function _sendConfirmationEmail(Subscriber $subscriber) {
|
protected function _sendConfirmationEmail(Subscriber $subscriber) {
|
||||||
return $subscriber->sendConfirmationEmail();
|
$sender = new SendConfirmationEmail();
|
||||||
|
return $sender->sendConfirmationEmail($subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _scheduleWelcomeNotification(Subscriber $subscriber, array $segments) {
|
protected function _scheduleWelcomeNotification(Subscriber $subscriber, array $segments) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace MailPoet\Models;
|
namespace MailPoet\Models;
|
||||||
use MailPoet\Mailer\Mailer;
|
use MailPoet\Mailer\Mailer;
|
||||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||||
|
use MailPoet\Subscribers\SendConfirmationEmail;
|
||||||
use MailPoet\Subscribers\SendNewSubscriberNotification;
|
use MailPoet\Subscribers\SendNewSubscriberNotification;
|
||||||
use MailPoet\Subscribers\Source;
|
use MailPoet\Subscribers\Source;
|
||||||
use MailPoet\Util\Helpers;
|
use MailPoet\Util\Helpers;
|
||||||
@ -83,71 +84,6 @@ class Subscriber extends Model {
|
|||||||
return self::where('wp_user_id', $wp_user->ID)->findOne();
|
return self::where('wp_user_id', $wp_user->ID)->findOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendConfirmationEmail() {
|
|
||||||
$signup_confirmation = Setting::getValue('signup_confirmation');
|
|
||||||
|
|
||||||
if((bool)$signup_confirmation['enabled'] === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$segments = $this->segments()->findMany();
|
|
||||||
$segment_names = array_map(function($segment) {
|
|
||||||
return $segment->name;
|
|
||||||
}, $segments);
|
|
||||||
|
|
||||||
$body = nl2br($signup_confirmation['body']);
|
|
||||||
|
|
||||||
// replace list of segments shortcode
|
|
||||||
$body = str_replace(
|
|
||||||
'[lists_to_confirm]',
|
|
||||||
'<strong>'.join(', ', $segment_names).'</strong>',
|
|
||||||
$body
|
|
||||||
);
|
|
||||||
|
|
||||||
// replace activation link
|
|
||||||
$body = Helpers::replaceLinkTags(
|
|
||||||
$body,
|
|
||||||
Subscription\Url::getConfirmationUrl($this),
|
|
||||||
array('target' => '_blank'),
|
|
||||||
'activation_link'
|
|
||||||
);
|
|
||||||
|
|
||||||
// build email data
|
|
||||||
$email = array(
|
|
||||||
'subject' => $signup_confirmation['subject'],
|
|
||||||
'body' => array(
|
|
||||||
'html' => $body,
|
|
||||||
'text' => $body
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// convert subscriber to array
|
|
||||||
$subscriber = $this->asArray();
|
|
||||||
|
|
||||||
// set from
|
|
||||||
$from = (
|
|
||||||
!empty($signup_confirmation['from'])
|
|
||||||
&& !empty($signup_confirmation['from']['address'])
|
|
||||||
) ? $signup_confirmation['from']
|
|
||||||
: false;
|
|
||||||
|
|
||||||
// set reply to
|
|
||||||
$reply_to = (
|
|
||||||
!empty($signup_confirmation['reply_to'])
|
|
||||||
&& !empty($signup_confirmation['reply_to']['address'])
|
|
||||||
) ? $signup_confirmation['reply_to']
|
|
||||||
: false;
|
|
||||||
|
|
||||||
// send email
|
|
||||||
try {
|
|
||||||
$mailer = new Mailer(false, $from, $reply_to);
|
|
||||||
return $mailer->send($email, $subscriber);
|
|
||||||
} catch(\Exception $e) {
|
|
||||||
$this->setError($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static function generateToken($email = null) {
|
static function generateToken($email = null) {
|
||||||
if($email !== null) {
|
if($email !== null) {
|
||||||
$auth_key = '';
|
$auth_key = '';
|
||||||
@ -216,8 +152,8 @@ class Subscriber extends Model {
|
|||||||
// link subscriber to segments
|
// link subscriber to segments
|
||||||
SubscriberSegment::subscribeToSegments($subscriber, $segment_ids);
|
SubscriberSegment::subscribeToSegments($subscriber, $segment_ids);
|
||||||
|
|
||||||
// signup confirmation
|
$sender = new SendConfirmationEmail();
|
||||||
$subscriber->sendConfirmationEmail();
|
$sender->sendConfirmationEmail($subscriber);
|
||||||
|
|
||||||
if($subscriber->status === self::STATUS_SUBSCRIBED) {
|
if($subscriber->status === self::STATUS_SUBSCRIBED) {
|
||||||
$sender = new SendNewSubscriberNotification();
|
$sender = new SendNewSubscriberNotification();
|
||||||
|
91
lib/Subscribers/SendConfirmationEmail.php
Normal file
91
lib/Subscribers/SendConfirmationEmail.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Subscribers;
|
||||||
|
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Models\Setting;
|
||||||
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Subscription\Url;
|
||||||
|
use MailPoet\Util\Helpers;
|
||||||
|
|
||||||
|
class SendConfirmationEmail {
|
||||||
|
|
||||||
|
/** @var Mailer */
|
||||||
|
private $mailer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Mailer|null $mailer
|
||||||
|
*/
|
||||||
|
function __construct($mailer = null) {
|
||||||
|
if($mailer) {
|
||||||
|
$this->mailer = $mailer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendConfirmationEmail(Subscriber $subscriber) {
|
||||||
|
$signup_confirmation = Setting::getValue('signup_confirmation');
|
||||||
|
|
||||||
|
if((bool)$signup_confirmation['enabled'] === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$segments = $subscriber->segments()->findMany();
|
||||||
|
$segment_names = array_map(function($segment) {
|
||||||
|
return $segment->name;
|
||||||
|
}, $segments);
|
||||||
|
|
||||||
|
$body = nl2br($signup_confirmation['body']);
|
||||||
|
|
||||||
|
// replace list of segments shortcode
|
||||||
|
$body = str_replace(
|
||||||
|
'[lists_to_confirm]',
|
||||||
|
'<strong>'.join(', ', $segment_names).'</strong>',
|
||||||
|
$body
|
||||||
|
);
|
||||||
|
|
||||||
|
// replace activation link
|
||||||
|
$body = Helpers::replaceLinkTags(
|
||||||
|
$body,
|
||||||
|
Url::getConfirmationUrl($subscriber),
|
||||||
|
array('target' => '_blank'),
|
||||||
|
'activation_link'
|
||||||
|
);
|
||||||
|
|
||||||
|
// build email data
|
||||||
|
$email = array(
|
||||||
|
'subject' => $signup_confirmation['subject'],
|
||||||
|
'body' => array(
|
||||||
|
'html' => $body,
|
||||||
|
'text' => $body
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// set from
|
||||||
|
$from = (
|
||||||
|
!empty($signup_confirmation['from'])
|
||||||
|
&& !empty($signup_confirmation['from']['address'])
|
||||||
|
) ? $signup_confirmation['from']
|
||||||
|
: false;
|
||||||
|
|
||||||
|
// set reply to
|
||||||
|
$reply_to = (
|
||||||
|
!empty($signup_confirmation['reply_to'])
|
||||||
|
&& !empty($signup_confirmation['reply_to']['address'])
|
||||||
|
) ? $signup_confirmation['reply_to']
|
||||||
|
: false;
|
||||||
|
|
||||||
|
// send email
|
||||||
|
try {
|
||||||
|
if(!$this->mailer) {
|
||||||
|
$this->mailer = new Mailer(false, $from, $reply_to);
|
||||||
|
}
|
||||||
|
$this->mailer->getSenderNameAndAddress($from);
|
||||||
|
$this->mailer->getReplyToNameAndAddress($reply_to);
|
||||||
|
return $this->mailer->send($email, $subscriber);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$subscriber->setError($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -33,7 +33,7 @@ class SendNewSubscriberNotification {
|
|||||||
if($mailer) {
|
if($mailer) {
|
||||||
$this->mailer = $mailer;
|
$this->mailer = $mailer;
|
||||||
} else {
|
} else {
|
||||||
$this->mailer = new \MailPoet\Mailer\Mailer();
|
$this->mailer = new \MailPoet\Mailer\Mailer(false, $this->constructSenderEmail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ $kernel->init(
|
|||||||
array(
|
array(
|
||||||
'debug' => true,
|
'debug' => true,
|
||||||
'cacheDir' => $cacheDir,
|
'cacheDir' => $cacheDir,
|
||||||
'includePaths' => [__DIR__ . '/../lib']
|
'includePaths' => [__DIR__ . '/../lib'],
|
||||||
|
'appDir' => __DIR__ . '/../'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Test\Models;
|
namespace MailPoet\Test\Models;
|
||||||
|
|
||||||
use AspectMock\Test as Mock;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Codeception\Util\Fixtures;
|
use Codeception\Util\Fixtures;
|
||||||
use MailPoet\Models\CustomField;
|
use MailPoet\Models\CustomField;
|
||||||
@ -1120,48 +1119,6 @@ class SubscriberTest extends \MailPoetTest {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItSendsConfirmationEmail() {
|
|
||||||
Mock::double('MailPoet\Mailer\Mailer', [
|
|
||||||
'__construct' => null,
|
|
||||||
'send' => function($email) {
|
|
||||||
return $email;
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
Mock::double('MailPoet\Subscription\Url', [
|
|
||||||
'getConfirmationUrl' => 'http://example.com'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$segment = Segment::createOrUpdate(
|
|
||||||
array(
|
|
||||||
'name' => 'Test segment'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
SubscriberSegment::subscribeToSegments(
|
|
||||||
$this->subscriber,
|
|
||||||
array($segment->id)
|
|
||||||
);
|
|
||||||
|
|
||||||
$result = $this->subscriber->sendConfirmationEmail();
|
|
||||||
|
|
||||||
// email contains subscriber's lists
|
|
||||||
expect($result['body']['html'])->contains('<strong>Test segment</strong>');
|
|
||||||
// email contains activation link
|
|
||||||
expect($result['body']['html'])->contains('<a target="_blank" href="http://example.com">Click here to confirm your subscription.</a>');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItSetsErrorsWhenConfirmationEmailCannotBeSent() {
|
|
||||||
Mock::double('MailPoet\Mailer\Mailer', [
|
|
||||||
'__construct' => null,
|
|
||||||
'send' => function() {
|
|
||||||
throw new \Exception('send error');
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->subscriber->sendConfirmationEmail();
|
|
||||||
// error is set on the subscriber model object
|
|
||||||
expect($this->subscriber->getErrors()[0])->equals('send error');
|
|
||||||
}
|
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
\ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
\ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||||
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
\ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||||
|
71
tests/unit/Subscribers/SendConfirmationEmailTest.php
Normal file
71
tests/unit/Subscribers/SendConfirmationEmailTest.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Subscribers;
|
||||||
|
|
||||||
|
use AspectMock\Test as Mock;
|
||||||
|
use Codeception\Stub;
|
||||||
|
use MailPoet\Mailer\Mailer;
|
||||||
|
use MailPoet\Models\Segment;
|
||||||
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
|
||||||
|
class SendConfirmationEmailTest extends \MailPoetTest {
|
||||||
|
|
||||||
|
function testItSendsConfirmationEmail() {
|
||||||
|
Mock::double('MailPoet\Subscription\Url', [
|
||||||
|
'getConfirmationUrl' => 'http://example.com'
|
||||||
|
]);
|
||||||
|
$subscriber = Subscriber::create();
|
||||||
|
$subscriber->hydrate([
|
||||||
|
'first_name' => 'John',
|
||||||
|
'last_name' => 'Mailer',
|
||||||
|
'email' => 'john@mailpoet.com'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$mailer = Stub::makeEmpty(Mailer::class, [
|
||||||
|
'send' =>
|
||||||
|
Stub\Expected::once(function($email) {
|
||||||
|
expect($email['body']['html'])->contains('<strong>Test segment</strong>');
|
||||||
|
expect($email['body']['html'])->contains('<a target="_blank" href="http://example.com">Click here to confirm your subscription.</a>');
|
||||||
|
}),
|
||||||
|
], $this);
|
||||||
|
|
||||||
|
$sender = new SendConfirmationEmail($mailer);
|
||||||
|
|
||||||
|
|
||||||
|
$segment = Segment::createOrUpdate(
|
||||||
|
array(
|
||||||
|
'name' => 'Test segment'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
SubscriberSegment::subscribeToSegments(
|
||||||
|
$subscriber,
|
||||||
|
array($segment->id)
|
||||||
|
);
|
||||||
|
|
||||||
|
$sender->sendConfirmationEmail($subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItSetsErrorsWhenConfirmationEmailCannotBeSent() {
|
||||||
|
$subscriber = Subscriber::create();
|
||||||
|
$subscriber->hydrate([
|
||||||
|
'first_name' => 'John',
|
||||||
|
'last_name' => 'Mailer',
|
||||||
|
'email' => 'john@mailpoet.com'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$mailer = Stub::makeEmpty(Mailer::class, [
|
||||||
|
'send' =>
|
||||||
|
Stub\Expected::once(function () {
|
||||||
|
throw new \Exception('send error');
|
||||||
|
}),
|
||||||
|
], $this);
|
||||||
|
|
||||||
|
$sender = new SendConfirmationEmail($mailer);
|
||||||
|
|
||||||
|
$sender->sendConfirmationEmail($subscriber);
|
||||||
|
// error is set on the subscriber model object
|
||||||
|
expect($subscriber->getErrors()[0])->equals('send error');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user