Use template for WooCommerce transactional emails
[MAILPOET-2286]
This commit is contained in:
committed by
Jack Kitterhing
parent
e1a8883935
commit
aa129f5987
@@ -5,11 +5,14 @@ namespace MailPoet\Config;
|
|||||||
use MailPoet\API\JSON\API;
|
use MailPoet\API\JSON\API;
|
||||||
use MailPoet\AutomaticEmails\AutomaticEmails;
|
use MailPoet\AutomaticEmails\AutomaticEmails;
|
||||||
use MailPoet\Cron\CronTrigger;
|
use MailPoet\Cron\CronTrigger;
|
||||||
|
use MailPoet\Features\FeaturesController;
|
||||||
use MailPoet\Router;
|
use MailPoet\Router;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Util\ConflictResolver;
|
use MailPoet\Util\ConflictResolver;
|
||||||
use MailPoet\Util\Helpers;
|
use MailPoet\Util\Helpers;
|
||||||
use MailPoet\Util\Notices\PermanentNotices;
|
use MailPoet\Util\Notices\PermanentNotices;
|
||||||
|
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails as WCTransactionalEmails;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoet\WP\Notice as WPNotice;
|
use MailPoet\WP\Notice as WPNotice;
|
||||||
|
|
||||||
@@ -36,6 +39,9 @@ class Initializer {
|
|||||||
/** @var SettingsController */
|
/** @var SettingsController */
|
||||||
private $settings;
|
private $settings;
|
||||||
|
|
||||||
|
/** @var FeaturesController */
|
||||||
|
private $flags_controller;
|
||||||
|
|
||||||
/** @var Router\Router */
|
/** @var Router\Router */
|
||||||
private $router;
|
private $router;
|
||||||
|
|
||||||
@@ -60,6 +66,12 @@ class Initializer {
|
|||||||
/** @var DatabaseInitializer */
|
/** @var DatabaseInitializer */
|
||||||
private $database_initializer;
|
private $database_initializer;
|
||||||
|
|
||||||
|
/** @var WCTransactionalEmails */
|
||||||
|
private $wc_transactional_emails;
|
||||||
|
|
||||||
|
/** @var WooCommerceHelper */
|
||||||
|
private $wc_helper;
|
||||||
|
|
||||||
const INITIALIZED = 'MAILPOET_INITIALIZED';
|
const INITIALIZED = 'MAILPOET_INITIALIZED';
|
||||||
|
|
||||||
function __construct(
|
function __construct(
|
||||||
@@ -75,7 +87,10 @@ class Initializer {
|
|||||||
CronTrigger $cron_trigger,
|
CronTrigger $cron_trigger,
|
||||||
PermanentNotices $permanent_notices,
|
PermanentNotices $permanent_notices,
|
||||||
Shortcodes $shortcodes,
|
Shortcodes $shortcodes,
|
||||||
DatabaseInitializer $database_initializer
|
DatabaseInitializer $database_initializer,
|
||||||
|
FeaturesController $flags_controller,
|
||||||
|
WCTransactionalEmails $wc_transactional_emails,
|
||||||
|
WooCommerceHelper $wc_helper
|
||||||
) {
|
) {
|
||||||
$this->renderer_factory = $renderer_factory;
|
$this->renderer_factory = $renderer_factory;
|
||||||
$this->access_control = $access_control;
|
$this->access_control = $access_control;
|
||||||
@@ -90,6 +105,9 @@ class Initializer {
|
|||||||
$this->permanent_notices = $permanent_notices;
|
$this->permanent_notices = $permanent_notices;
|
||||||
$this->shortcodes = $shortcodes;
|
$this->shortcodes = $shortcodes;
|
||||||
$this->database_initializer = $database_initializer;
|
$this->database_initializer = $database_initializer;
|
||||||
|
$this->flags_controller = $flags_controller;
|
||||||
|
$this->wc_transactional_emails = $wc_transactional_emails;
|
||||||
|
$this->wc_helper = $wc_helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@@ -172,6 +190,7 @@ class Initializer {
|
|||||||
$this->renderer = $this->renderer_factory->getRenderer();
|
$this->renderer = $this->renderer_factory->getRenderer();
|
||||||
$this->setupWidget();
|
$this->setupWidget();
|
||||||
$this->hooks->init();
|
$this->hooks->init();
|
||||||
|
$this->setupWoocommerceTransactionalEmails();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->handleFailedInitialization($e);
|
$this->handleFailedInitialization($e);
|
||||||
}
|
}
|
||||||
@@ -347,6 +366,15 @@ class Initializer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setupWoocommerceTransactionalEmails() {
|
||||||
|
$feature_enabled = $this->flags_controller->isSupported(FeaturesController::WC_TRANSACTIONAL_EMAILS_CUSTOMIZER);
|
||||||
|
$opt_in_enabled = $this->settings->get('woocommerce.use_mailpoet_editor', false);
|
||||||
|
$wc_enabled = $this->wc_helper->isWooCommerceActive();
|
||||||
|
if ($feature_enabled && $wc_enabled && $opt_in_enabled) {
|
||||||
|
$this->wc_transactional_emails->useTemplateForWoocommerceEmails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function includeAutomaticEmailsData() {
|
function includeAutomaticEmailsData() {
|
||||||
$data = [
|
$data = [
|
||||||
'automatic_emails' => $this->automatic_emails,
|
'automatic_emails' => $this->automatic_emails,
|
||||||
|
@@ -243,6 +243,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
|||||||
$container->autowire(\MailPoet\WooCommerce\Subscription::class)->setPublic(true);
|
$container->autowire(\MailPoet\WooCommerce\Subscription::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\WooCommerce\TransactionalEmails::class);
|
$container->autowire(\MailPoet\WooCommerce\TransactionalEmails::class);
|
||||||
$container->autowire(\MailPoet\WooCommerce\TransactionalEmails\Template::class);
|
$container->autowire(\MailPoet\WooCommerce\TransactionalEmails\Template::class);
|
||||||
|
$container->autowire(\MailPoet\WooCommerce\TransactionalEmails\Renderer::class);
|
||||||
// WordPress
|
// WordPress
|
||||||
$container->autowire(\MailPoet\WP\Emoji::class)->setPublic(true);
|
$container->autowire(\MailPoet\WP\Emoji::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\WP\Functions::class)->setPublic(true);
|
$container->autowire(\MailPoet\WP\Functions::class)->setPublic(true);
|
||||||
|
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace MailPoet\WooCommerce;
|
namespace MailPoet\WooCommerce;
|
||||||
|
|
||||||
use MailPoet\Config\Env;
|
|
||||||
use MailPoet\Models\Newsletter;
|
use MailPoet\Models\Newsletter;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails\Renderer;
|
||||||
use MailPoet\WooCommerce\TransactionalEmails\Template;
|
use MailPoet\WooCommerce\TransactionalEmails\Template;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
@@ -20,13 +20,17 @@ class TransactionalEmails {
|
|||||||
/** @var Template */
|
/** @var Template */
|
||||||
private $template;
|
private $template;
|
||||||
|
|
||||||
|
/** @var Renderer */
|
||||||
|
private $renderer;
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
private $email_headings;
|
private $email_headings;
|
||||||
|
|
||||||
function __construct(WPFunctions $wp, SettingsController $settings, Template $template) {
|
function __construct(WPFunctions $wp, SettingsController $settings, Template $template, Renderer $renderer) {
|
||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
|
$this->renderer = $renderer;
|
||||||
$this->email_headings = [
|
$this->email_headings = [
|
||||||
'new_account' => [
|
'new_account' => [
|
||||||
'option_name' => 'woocommerce_new_order_settings',
|
'option_name' => 'woocommerce_new_order_settings',
|
||||||
@@ -69,6 +73,21 @@ class TransactionalEmails {
|
|||||||
return $values;
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function useTemplateForWoocommerceEmails() {
|
||||||
|
$this->wp->addAction('woocommerce_init', function() {
|
||||||
|
$this->wp->removeAction('woocommerce_email_header', [\WC()->mailer(), 'email_header']);
|
||||||
|
$this->wp->removeAction('woocommerce_email_footer', [\WC()->mailer(), 'email_footer']);
|
||||||
|
$this->wp->addAction('woocommerce_email_header', function($email_heading) {
|
||||||
|
$this->renderer->render($this->getNewsletter());
|
||||||
|
echo $this->renderer->getHTMLBeforeContent($email_heading);
|
||||||
|
});
|
||||||
|
$this->wp->addAction('woocommerce_email_footer', function() {
|
||||||
|
echo $this->renderer->getHTMLAfterContent();
|
||||||
|
});
|
||||||
|
$this->wp->addAction('woocommerce_email_styles', [$this->renderer, 'prefixCss']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function createNewsletter() {
|
private function createNewsletter() {
|
||||||
$wc_email_settings = $this->getWCEmailSettings();
|
$wc_email_settings = $this->getWCEmailSettings();
|
||||||
return Newsletter::createOrUpdate([
|
return Newsletter::createOrUpdate([
|
||||||
@@ -79,6 +98,10 @@ class TransactionalEmails {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getNewsletter() {
|
||||||
|
return Newsletter::findOne($this->settings->get(self::SETTING_EMAIL_ID));
|
||||||
|
}
|
||||||
|
|
||||||
private function replacePlaceholders($text) {
|
private function replacePlaceholders($text) {
|
||||||
$title = $this->wp->wpSpecialcharsDecode($this->wp->getOption('blogname'), ENT_QUOTES);
|
$title = $this->wp->wpSpecialcharsDecode($this->wp->getOption('blogname'), ENT_QUOTES);
|
||||||
$address = $this->wp->wpParseUrl($this->wp->homeUrl(), PHP_URL_HOST);
|
$address = $this->wp->wpParseUrl($this->wp->homeUrl(), PHP_URL_HOST);
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace MailPoet\WooCommerce\TransactionalEmails;
|
namespace MailPoet\WooCommerce\TransactionalEmails;
|
||||||
|
|
||||||
|
use MailPoet\Config\Env;
|
||||||
|
|
||||||
class Template {
|
class Template {
|
||||||
public function create($wc_email_settings) {
|
public function create($wc_email_settings) {
|
||||||
$social_icon_url = Env::$assets_url . '/img/newsletter_editor/social-icons';
|
$social_icon_url = Env::$assets_url . '/img/newsletter_editor/social-icons';
|
||||||
|
@@ -4,7 +4,10 @@ namespace MailPoet\WooCommerce;
|
|||||||
|
|
||||||
use Codeception\Stub;
|
use Codeception\Stub;
|
||||||
use MailPoet\Models\Newsletter;
|
use MailPoet\Models\Newsletter;
|
||||||
|
use MailPoet\Newsletter\Editor\LayoutHelper as L;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails\Renderer;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails\Template;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Idiorm\ORM;
|
use MailPoetVendor\Idiorm\ORM;
|
||||||
|
|
||||||
@@ -25,7 +28,7 @@ class TransactionalEmailsTest extends \MailPoetTest {
|
|||||||
$this->wp = new WPFunctions();
|
$this->wp = new WPFunctions();
|
||||||
$this->settings = SettingsController::getInstance();
|
$this->settings = SettingsController::getInstance();
|
||||||
$this->original_wc_settings = $this->settings->get('woocommerce');
|
$this->original_wc_settings = $this->settings->get('woocommerce');
|
||||||
$this->transactional_emails = new TransactionalEmails($this->wp, $this->settings);
|
$this->transactional_emails = new TransactionalEmails($this->wp, $this->settings, new Template, new Renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testInitCreatesTransactionalEmailAndSavesItsId() {
|
function testInitCreatesTransactionalEmailAndSavesItsId() {
|
||||||
@@ -50,13 +53,76 @@ class TransactionalEmailsTest extends \MailPoetTest {
|
|||||||
return 'my-awesome-image-url';
|
return 'my-awesome-image-url';
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
$transactional_emails = new TransactionalEmails($wp, $this->settings);
|
$transactional_emails = new TransactionalEmails($wp, $this->settings, new Template, new Renderer);
|
||||||
$transactional_emails->init();
|
$transactional_emails->init();
|
||||||
$email = Newsletter::where('type', Newsletter::TYPE_WC_TRANSACTIONAL_EMAIL)->findOne();
|
$email = Newsletter::where('type', Newsletter::TYPE_WC_TRANSACTIONAL_EMAIL)->findOne();
|
||||||
expect($email)->notEmpty();
|
expect($email)->notEmpty();
|
||||||
expect($email->body)->contains('my-awesome-image-url');
|
expect($email->body)->contains('my-awesome-image-url');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testUseTemplateForWCEmails() {
|
||||||
|
$added_actions = [];
|
||||||
|
$removed_actions = [];
|
||||||
|
$newsletter = Newsletter::createOrUpdate([
|
||||||
|
'type' => Newsletter::TYPE_WC_TRANSACTIONAL_EMAIL,
|
||||||
|
'subject' => 'WooCommerce Transactional Email',
|
||||||
|
'preheader' => '',
|
||||||
|
'body' => json_encode([
|
||||||
|
'content' => L::col([
|
||||||
|
L::row([L::col([['type' => 'text', 'text' => 'Some text before heading']])]),
|
||||||
|
['type' => 'woocommerceHeading'],
|
||||||
|
L::row([L::col([['type' => 'text', 'text' => 'Some text between heading and content']])]),
|
||||||
|
['type' => 'woocommerceContent'],
|
||||||
|
L::row([L::col([['type' => 'text', 'text' => 'Some text after content']])]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
$this->settings->set(TransactionalEmails::SETTING_EMAIL_ID, $newsletter->id);
|
||||||
|
$wp = Stub::make(new WPFunctions, [
|
||||||
|
'getOption' => function($name) {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
'addAction' => function ($name, $action) use(&$added_actions) {
|
||||||
|
$added_actions[$name] = $action;
|
||||||
|
},
|
||||||
|
'removeAction' => function ($name, $action) use(&$removed_actions) {
|
||||||
|
$removed_actions[$name] = $action;
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
$renderer = Stub::make(Renderer::class, [
|
||||||
|
'render' => function($email) use(&$newsletter) {
|
||||||
|
expect($email->id)->equals($newsletter->id);
|
||||||
|
},
|
||||||
|
'getHTMLBeforeContent' => function($heading_text) {
|
||||||
|
return 'HTML before content with ' . $heading_text;
|
||||||
|
},
|
||||||
|
'getHTMLAfterContent' => function() {
|
||||||
|
return 'HTML after content';
|
||||||
|
},
|
||||||
|
'prefixCss' => function($css) {
|
||||||
|
return 'prefixed ' . $css;
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
$transactional_emails = new TransactionalEmails($wp, $this->settings, new Template, $renderer);
|
||||||
|
$transactional_emails->useTemplateForWoocommerceEmails();
|
||||||
|
expect($added_actions)->count(1);
|
||||||
|
expect($added_actions['woocommerce_init'])->isCallable();
|
||||||
|
$added_actions['woocommerce_init']();
|
||||||
|
expect($removed_actions)->count(2);
|
||||||
|
expect($added_actions)->count(4);
|
||||||
|
expect($added_actions['woocommerce_email_header'])->isCallable();
|
||||||
|
ob_start();
|
||||||
|
$added_actions['woocommerce_email_header']('heading text');
|
||||||
|
expect(ob_get_clean())->equals('HTML before content with heading text');
|
||||||
|
expect($added_actions['woocommerce_email_footer'])->isCallable();
|
||||||
|
ob_start();
|
||||||
|
$added_actions['woocommerce_email_footer']();
|
||||||
|
expect(ob_get_clean())->equals('HTML after content');
|
||||||
|
expect($added_actions['woocommerce_email_styles'])->isCallable();
|
||||||
|
expect($added_actions['woocommerce_email_styles']('some css'))->equals('prefixed some css');
|
||||||
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||||
$this->settings->set('woocommerce', $this->original_wc_settings);
|
$this->settings->set('woocommerce', $this->original_wc_settings);
|
||||||
|
@@ -216,4 +216,21 @@ if (!class_exists(WC_Session::class)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('WC')) {
|
||||||
|
class WC_Mailer {
|
||||||
|
function email_header() {
|
||||||
|
}
|
||||||
|
function email_footer() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class WooCommerce {
|
||||||
|
function mailer() {
|
||||||
|
return new WC_Mailer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function WC() {
|
||||||
|
return new WooCommerce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
include '_fixtures.php';
|
include '_fixtures.php';
|
||||||
|
@@ -4,6 +4,8 @@ namespace MailPoet\WooCommerce;
|
|||||||
|
|
||||||
use Codeception\Stub;
|
use Codeception\Stub;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails\Renderer;
|
||||||
|
use MailPoet\WooCommerce\TransactionalEmails\Template;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
class TransactionalEmailsTest extends \MailPoetUnitTest {
|
class TransactionalEmailsTest extends \MailPoetUnitTest {
|
||||||
@@ -32,7 +34,9 @@ class TransactionalEmailsTest extends \MailPoetUnitTest {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
$settings = Stub::make(SettingsController::class);
|
$settings = Stub::make(SettingsController::class);
|
||||||
$transactional_emails = new TransactionalEmails($wp, $settings);
|
$template = Stub::make(Template::class);
|
||||||
|
$renderer = Stub::make(Renderer::class);
|
||||||
|
$transactional_emails = new TransactionalEmails($wp, $settings, $template, $renderer);
|
||||||
expect($transactional_emails->getEmailHeadings())->equals([
|
expect($transactional_emails->getEmailHeadings())->equals([
|
||||||
'new_account' => 'Test: New Order: #0001',
|
'new_account' => 'Test: New Order: #0001',
|
||||||
'processing_order' => 'Thank you for your order',
|
'processing_order' => 'Thank you for your order',
|
||||||
@@ -40,5 +44,4 @@ class TransactionalEmailsTest extends \MailPoetUnitTest {
|
|||||||
'customer_note' => 'Note added to order #0001 - ' . date('Y-m-d'),
|
'customer_note' => 'Note added to order #0001 - ' . date('Y-m-d'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user