Extract ALC and ACC block classes out of block renderer [MAILPOET-2979]
This commit is contained in:
@@ -295,6 +295,8 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\Newsletter\Options\NewsletterOptionsRepository::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Newsletter\Preview\SendPreviewController::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Renderer\Blocks\AbandonedCartContent::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Renderer\Blocks\AutomatedLatestContentBlock::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Renderer\Blocks\Button::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Renderer\Blocks\Divider::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Renderer\Blocks\Footer::class);
|
||||
|
62
lib/Newsletter/Renderer/Blocks/AbandonedCartContent.php
Normal file
62
lib/Newsletter/Renderer/Blocks/AbandonedCartContent.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\AutomaticEmails\WooCommerce\Events\AbandonedCart;
|
||||
use MailPoet\AutomaticEmails\WooCommerce\WooCommerce as WooCommerceEmail;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\NewsletterOptionEntity;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
|
||||
class AbandonedCartContent {
|
||||
/** @var AutomatedLatestContentBlock */
|
||||
private $ALCBlock;
|
||||
|
||||
public function __construct(
|
||||
AutomatedLatestContentBlock $ALCBlock
|
||||
) {
|
||||
$this->ALCBlock = $ALCBlock;
|
||||
}
|
||||
|
||||
public function render(
|
||||
NewsletterEntity $newsletter,
|
||||
array $args,
|
||||
bool $preview = false,
|
||||
SendingTask $sendingTask = null
|
||||
): array {
|
||||
if ($newsletter->getType() !== NewsletterEntity::TYPE_AUTOMATIC) {
|
||||
// Do not display the block if not an automatic email
|
||||
return [];
|
||||
}
|
||||
$groupOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption) {
|
||||
$optionField = $newsletterOption->getOptionField();
|
||||
return $optionField && $optionField->getName() === 'group';
|
||||
})->first();
|
||||
$eventOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption) {
|
||||
$optionField = $newsletterOption->getOptionField();
|
||||
return $optionField && $optionField->getName() === 'event';
|
||||
})->first();
|
||||
if ($groupOption->getValue() !== WooCommerceEmail::SLUG
|
||||
|| $eventOption->getValue() !== AbandonedCart::SLUG
|
||||
) {
|
||||
// Do not display the block if not an AbandonedCart email
|
||||
return [];
|
||||
}
|
||||
if ($preview) {
|
||||
// Display latest products for preview (no 'posts' argument specified)
|
||||
return $this->ALCBlock->render($newsletter, $args);
|
||||
}
|
||||
if (!($sendingTask instanceof SendingTask)) {
|
||||
// Do not display the block if we're not sending an email
|
||||
return [];
|
||||
}
|
||||
$meta = $sendingTask->getMeta();
|
||||
if (empty($meta[AbandonedCart::TASK_META_NAME])) {
|
||||
// Do not display the block if a cart is empty
|
||||
return [];
|
||||
}
|
||||
$args['amount'] = 50;
|
||||
$args['posts'] = $meta[AbandonedCart::TASK_META_NAME];
|
||||
return $this->ALCBlock->render($newsletter, $args);
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\NewsletterPostEntity;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Newsletter\AutomatedLatestContent;
|
||||
use MailPoet\Newsletter\NewsletterPostsRepository;
|
||||
|
||||
class AutomatedLatestContentBlock {
|
||||
/**
|
||||
* Cache for rendered posts in newsletter.
|
||||
* Used to prevent duplicate post in case a newsletter contains 2 ALC blocks
|
||||
* @var array
|
||||
*/
|
||||
public $renderedPostsInNewsletter;
|
||||
|
||||
/** @var AutomatedLatestContent */
|
||||
private $ALC;
|
||||
|
||||
/** @var NewsletterPostsRepository */
|
||||
private $newsletterPostsRepository;
|
||||
|
||||
public function __construct(
|
||||
NewsletterPostsRepository $newsletterPostsRepository,
|
||||
AutomatedLatestContent $ALC
|
||||
) {
|
||||
$this->renderedPostsInNewsletter = [];
|
||||
$this->ALC = $ALC;
|
||||
$this->newsletterPostsRepository = $newsletterPostsRepository;
|
||||
}
|
||||
|
||||
public function render(NewsletterEntity $newsletter, $args) {
|
||||
$newerThanTimestamp = false;
|
||||
$newsletterId = false;
|
||||
if ($newsletter->getType() === Newsletter::TYPE_NOTIFICATION_HISTORY) {
|
||||
$parent = $newsletter->getParent();
|
||||
if ($parent instanceof NewsletterEntity) {
|
||||
$newsletterId = $parent->getId();
|
||||
|
||||
$lastPost = $this->newsletterPostsRepository->findOneBy(['newsletter' => $parent], ['createdAt' => 'desc']);
|
||||
if ($lastPost instanceof NewsletterPostEntity) {
|
||||
$newerThanTimestamp = $lastPost->getCreatedAt();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$postsToExclude = $this->getRenderedPosts((int)$newsletterId);
|
||||
$aLCPosts = $this->ALC->getPosts($args, $postsToExclude, $newsletterId, $newerThanTimestamp);
|
||||
foreach ($aLCPosts as $post) {
|
||||
$postsToExclude[] = $post->ID;
|
||||
}
|
||||
$this->setRenderedPosts((int)$newsletterId, $postsToExclude);
|
||||
return $this->ALC->transformPosts($args, $aLCPosts);
|
||||
}
|
||||
|
||||
private function getRenderedPosts(int $newsletterId) {
|
||||
return $this->renderedPostsInNewsletter[$newsletterId] ?? [];
|
||||
}
|
||||
|
||||
private function setRenderedPosts(int $newsletterId, array $posts) {
|
||||
return $this->renderedPostsInNewsletter[$newsletterId] = $posts;
|
||||
}
|
||||
}
|
@@ -2,27 +2,12 @@
|
||||
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\AutomaticEmails\WooCommerce\Events\AbandonedCart;
|
||||
use MailPoet\AutomaticEmails\WooCommerce\WooCommerce as WooCommerceEmail;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\NewsletterOptionEntity;
|
||||
use MailPoet\Entities\NewsletterPostEntity;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Newsletter\AutomatedLatestContent;
|
||||
use MailPoet\Newsletter\NewsletterPostsRepository;
|
||||
use MailPoet\Newsletter\Renderer\Columns\ColumnsHelper;
|
||||
use MailPoet\Newsletter\Renderer\StylesHelper;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
|
||||
class Renderer {
|
||||
/**
|
||||
* Cache for rendered posts in newsletter.
|
||||
* Used to prevent duplicate post in case a newsletter contains 2 ALC blocks
|
||||
* @var array
|
||||
*/
|
||||
public $renderedPostsInNewsletter;
|
||||
|
||||
/** @var AutomatedLatestContent */
|
||||
/** @var AutomatedLatestContentBlock */
|
||||
private $ALC;
|
||||
|
||||
/** @var Button */
|
||||
@@ -49,12 +34,8 @@ class Renderer {
|
||||
/** @var Text */
|
||||
private $text;
|
||||
|
||||
/** @var NewsletterPostsRepository */
|
||||
private $newsletterPostsRepository;
|
||||
|
||||
public function __construct(
|
||||
NewsletterPostsRepository $newsletterPostsRepository,
|
||||
AutomatedLatestContent $ALC,
|
||||
AutomatedLatestContentBlock $ALC,
|
||||
Button $button,
|
||||
Divider $divider,
|
||||
Footer $footer,
|
||||
@@ -64,7 +45,6 @@ class Renderer {
|
||||
Spacer $spacer,
|
||||
Text $text
|
||||
) {
|
||||
$this->renderedPostsInNewsletter = [];
|
||||
$this->ALC = $ALC;
|
||||
$this->button = $button;
|
||||
$this->divider = $divider;
|
||||
@@ -74,7 +54,6 @@ class Renderer {
|
||||
$this->social = $social;
|
||||
$this->spacer = $spacer;
|
||||
$this->text = $text;
|
||||
$this->newsletterPostsRepository = $newsletterPostsRepository;
|
||||
}
|
||||
|
||||
public function render(NewsletterEntity $newsletter, $data) {
|
||||
@@ -135,85 +114,11 @@ class Renderer {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function automatedLatestContentTransformedPosts(NewsletterEntity $newsletter, $args) {
|
||||
$newerThanTimestamp = false;
|
||||
$newsletterId = false;
|
||||
if ($newsletter->getType() === Newsletter::TYPE_NOTIFICATION_HISTORY) {
|
||||
$parent = $newsletter->getParent();
|
||||
if ($parent instanceof NewsletterEntity) {
|
||||
$newsletterId = $parent->getId();
|
||||
|
||||
$lastPost = $this->newsletterPostsRepository->findOneBy(['newsletter' => $parent], ['createdAt' => 'desc']);
|
||||
if ($lastPost instanceof NewsletterPostEntity) {
|
||||
$newerThanTimestamp = $lastPost->getCreatedAt();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$postsToExclude = $this->getRenderedPosts((int)$newsletterId);
|
||||
$aLCPosts = $this->ALC->getPosts($args, $postsToExclude, $newsletterId, $newerThanTimestamp);
|
||||
foreach ($aLCPosts as $post) {
|
||||
$postsToExclude[] = $post->ID;
|
||||
}
|
||||
$this->setRenderedPosts((int)$newsletterId, $postsToExclude);
|
||||
return $this->ALC->transformPosts($args, $aLCPosts);
|
||||
}
|
||||
|
||||
public function processAutomatedLatestContent(NewsletterEntity $newsletter, $args, $columnBaseWidth) {
|
||||
$transformedPosts = [
|
||||
'blocks' => $this->automatedLatestContentTransformedPosts($newsletter, $args),
|
||||
'blocks' => $this->ALC->render($newsletter, $args),
|
||||
];
|
||||
$transformedPosts = StylesHelper::applyTextAlignment($transformedPosts);
|
||||
return $this->renderBlocksInColumn($newsletter, $transformedPosts, $columnBaseWidth);
|
||||
}
|
||||
|
||||
public function abandonedCartContentTransformedProducts(
|
||||
NewsletterEntity $newsletter,
|
||||
array $args,
|
||||
bool $preview = false,
|
||||
SendingTask $sendingTask = null
|
||||
): array {
|
||||
if ($newsletter->getType() !== NewsletterEntity::TYPE_AUTOMATIC) {
|
||||
// Do not display the block if not an automatic email
|
||||
return [];
|
||||
}
|
||||
$groupOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption) {
|
||||
$optionField = $newsletterOption->getOptionField();
|
||||
return $optionField && $optionField->getName() === 'group';
|
||||
})->first();
|
||||
$eventOption = $newsletter->getOptions()->filter(function (NewsletterOptionEntity $newsletterOption) {
|
||||
$optionField = $newsletterOption->getOptionField();
|
||||
return $optionField && $optionField->getName() === 'event';
|
||||
})->first();
|
||||
if ($groupOption->getValue() !== WooCommerceEmail::SLUG
|
||||
|| $eventOption->getValue() !== AbandonedCart::SLUG
|
||||
) {
|
||||
// Do not display the block if not an AbandonedCart email
|
||||
return [];
|
||||
}
|
||||
if ($preview) {
|
||||
// Display latest products for preview (no 'posts' argument specified)
|
||||
return $this->automatedLatestContentTransformedPosts($newsletter, $args);
|
||||
}
|
||||
if (!($sendingTask instanceof SendingTask)) {
|
||||
// Do not display the block if we're not sending an email
|
||||
return [];
|
||||
}
|
||||
$meta = $sendingTask->getMeta();
|
||||
if (empty($meta[AbandonedCart::TASK_META_NAME])) {
|
||||
// Do not display the block if a cart is empty
|
||||
return [];
|
||||
}
|
||||
$args['amount'] = 50;
|
||||
$args['posts'] = $meta[AbandonedCart::TASK_META_NAME];
|
||||
return $this->automatedLatestContentTransformedPosts($newsletter, $args);
|
||||
}
|
||||
|
||||
private function getRenderedPosts(int $newsletterId) {
|
||||
return $this->renderedPostsInNewsletter[$newsletterId] ?? [];
|
||||
}
|
||||
|
||||
private function setRenderedPosts(int $newsletterId, array $posts) {
|
||||
return $this->renderedPostsInNewsletter[$newsletterId] = $posts;
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,8 @@ namespace MailPoet\Newsletter\Renderer;
|
||||
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Newsletter\Editor\LayoutHelper;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\Renderer as BlocksRenderer;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\AbandonedCartContent;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\AutomatedLatestContentBlock;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
use MailPoet\WooCommerce\TransactionalEmails;
|
||||
|
||||
@@ -21,14 +22,22 @@ class Preprocessor {
|
||||
</tr>
|
||||
</table>';
|
||||
|
||||
/** @var BlocksRenderer */
|
||||
private $blocksRenderer;
|
||||
/** @var AbandonedCartContent */
|
||||
private $abandonedCartContent;
|
||||
|
||||
/** @var AutomatedLatestContentBlock */
|
||||
private $automatedLatestContent;
|
||||
|
||||
/** @var TransactionalEmails */
|
||||
private $transactionalEmails;
|
||||
|
||||
public function __construct(BlocksRenderer $blocksRenderer, TransactionalEmails $transactionalEmails) {
|
||||
$this->blocksRenderer = $blocksRenderer;
|
||||
public function __construct(
|
||||
AbandonedCartContent $abandonedCartContent,
|
||||
AutomatedLatestContentBlock $automatedLatestContent,
|
||||
TransactionalEmails $transactionalEmails
|
||||
) {
|
||||
$this->abandonedCartContent = $abandonedCartContent;
|
||||
$this->automatedLatestContent = $automatedLatestContent;
|
||||
$this->transactionalEmails = $transactionalEmails;
|
||||
}
|
||||
|
||||
@@ -55,9 +64,9 @@ class Preprocessor {
|
||||
public function processBlock(NewsletterEntity $newsletter, array $block, bool $preview = false, SendingTask $sendingTask = null): array {
|
||||
switch ($block['type']) {
|
||||
case 'abandonedCartContent':
|
||||
return $this->blocksRenderer->abandonedCartContentTransformedProducts($newsletter, $block, $preview, $sendingTask);
|
||||
return $this->abandonedCartContent->render($newsletter, $block, $preview, $sendingTask);
|
||||
case 'automatedLatestContentLayout':
|
||||
return $this->blocksRenderer->automatedLatestContentTransformedPosts($newsletter, $block);
|
||||
return $this->automatedLatestContent->render($newsletter, $block);
|
||||
case 'woocommerceHeading':
|
||||
$wcEmailSettings = $this->transactionalEmails->getWCEmailSettings();
|
||||
$content = self::WC_HEADING_BEFORE . '<h1 style="color:' . $wcEmailSettings['base_text_color'] . ';">' . self::WC_HEADING_PLACEHOLDER . '</h1>' . self::WC_HEADING_AFTER;
|
||||
|
@@ -9,92 +9,23 @@ use MailPoet\Entities\NewsletterOptionEntity;
|
||||
use MailPoet\Entities\NewsletterOptionFieldEntity;
|
||||
use MailPoet\Entities\NewsletterPostEntity;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Newsletter\NewsletterPostsRepository;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Newsletter\Scheduler\AutomaticEmailScheduler;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class RendererTest extends \MailPoetTest {
|
||||
/** @var Renderer */
|
||||
private $renderer;
|
||||
class AbandonedCartContentTest extends \MailPoetTest {
|
||||
/** @var AbandonedCartContent */
|
||||
private $block;
|
||||
|
||||
/** @var NewslettersRepository */
|
||||
private $newslettersRepository;
|
||||
|
||||
/** @var NewsletterPostsRepository */
|
||||
private $newsletterPostRepository;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
/** @var AutomaticEmailScheduler */
|
||||
private $automaticEmailScheduler;
|
||||
|
||||
/** @var array */
|
||||
private $postIds = [];
|
||||
|
||||
private $alcBlock = [
|
||||
'type' => 'automatedLatestContentLayout',
|
||||
'withLayout' => true,
|
||||
'amount' => '2',
|
||||
'contentType' => 'post',
|
||||
'terms' => [],
|
||||
'inclusionType' => 'include',
|
||||
'displayType' => 'excerpt',
|
||||
'titleFormat' => 'h2',
|
||||
'titleAlignment' => 'left',
|
||||
'titleIsLink' => false,
|
||||
'imageFullWidth' => true,
|
||||
'titlePosition' => 'abovePost',
|
||||
'featuredImagePosition' => 'left',
|
||||
'fullPostFeaturedImagePosition' => 'none',
|
||||
'showAuthor' => 'no',
|
||||
'authorPrecededBy' => 'Author:',
|
||||
'showCategories' => 'no',
|
||||
'categoriesPrecededBy' => 'Categories:',
|
||||
'readMoreType' => 'button',
|
||||
'readMoreText' => 'Read more',
|
||||
'readMoreButton' => [
|
||||
'type' => 'button',
|
||||
'text' => 'Read more',
|
||||
'url' => '[postLink]',
|
||||
'styles' => [
|
||||
'block' => [
|
||||
'backgroundColor' => '#e2973f',
|
||||
'borderColor' => '#e2973f',
|
||||
'borderWidth' => '0px',
|
||||
'borderRadius' => '5px',
|
||||
'borderStyle' => 'solid',
|
||||
'width' => '110px',
|
||||
'lineHeight' => '40px',
|
||||
'fontColor' => '#ffffff',
|
||||
'fontFamily' => 'Arial',
|
||||
'fontSize' => '14px',
|
||||
'fontWeight' => 'bold',
|
||||
'textAlign' => 'left',
|
||||
],
|
||||
],
|
||||
'context' => 'automatedLatestContentLayout.readMoreButton',
|
||||
],
|
||||
'sortBy' => 'newest',
|
||||
'showDivider' => false,
|
||||
'divider' => [
|
||||
'type' => 'divider',
|
||||
'styles' => [
|
||||
'block' => [
|
||||
'backgroundColor' => 'transparent',
|
||||
'padding' => '13px',
|
||||
'borderStyle' => 'solid',
|
||||
'borderWidth' => '3px',
|
||||
'borderColor' => '#aaaaaa',
|
||||
],
|
||||
],
|
||||
'context' => 'automatedLatestContentLayout.divider',
|
||||
],
|
||||
'backgroundColor' => '#ffffff',
|
||||
'backgroundColorAlternate' => '#eeeeee',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
private $productIds = [];
|
||||
|
||||
@@ -136,30 +67,17 @@ class RendererTest extends \MailPoetTest {
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->renderer = $this->diContainer->get(Renderer::class);
|
||||
$this->block = $this->diContainer->get(AbandonedCartContent::class);
|
||||
$this->wp = $this->diContainer->get(WPFunctions::class);
|
||||
$this->newsletterPostRepository = $this->diContainer->get(NewsletterPostsRepository::class);
|
||||
$this->newslettersRepository = $this->diContainer->get(NewslettersRepository::class);
|
||||
$this->automaticEmailScheduler = new AutomaticEmailScheduler();
|
||||
|
||||
// Clear old posts
|
||||
$posts = $this->wp->getPosts(['post_type' => 'post']);
|
||||
foreach ($posts as $post) {
|
||||
$this->wp->wpDeletePost((int)$post->ID);
|
||||
}
|
||||
|
||||
// Clear old products
|
||||
$products = $this->wp->getPosts(['post_type' => 'product']);
|
||||
foreach ($products as $product) {
|
||||
$this->wp->wpDeletePost((int)$product->ID);
|
||||
}
|
||||
|
||||
$this->postIds = [];
|
||||
$this->postIds[] = $this->createPost('POST 1', '2020-01-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 2', '2020-02-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 3', '2020-03-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 4', '2020-04-01 01:01:01');
|
||||
|
||||
$this->productIds = [];
|
||||
$this->productIds[] = $this->createPost('Product 1', '2020-05-01 01:01:01', 'product');
|
||||
$this->productIds[] = $this->createPost('Product 2', '2020-06-01 01:01:01', 'product');
|
||||
@@ -167,73 +85,10 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->productIds[] = $this->createPost('Product 4', '2020-08-01 01:01:01', 'product');
|
||||
}
|
||||
|
||||
public function testItRendersLatestPostsInAlc() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
public function testItRendersPostOnlyOncePerEmail() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->notContains('POST 4');
|
||||
expect($encodedResult)->notContains('POST 3');
|
||||
expect($encodedResult)->contains('POST 2');
|
||||
expect($encodedResult)->contains('POST 1');
|
||||
}
|
||||
|
||||
public function testItCanRenderSamePostsForDifferentPostNotifications() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
$notification2 = $this->createNewsletter('Newsletter2', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory2 = $this->createNewsletter('Newsletter2', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification2);
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory2, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
public function testItRendersOnlyPostsNewerThanLastSent() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$newsletterPost = new NewsletterPostEntity($notification, $this->postIds[2]); // Id of POST3
|
||||
$this->newsletterPostRepository->persist($newsletterPost);
|
||||
$this->newsletterPostRepository->flush();
|
||||
$newsletterPost->setCreatedAt(new \DateTime('2020-03-30 01:01:01'));
|
||||
$this->newsletterPostRepository->flush();
|
||||
$result = $this->renderer->automatedLatestContentTransformedPosts($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->notContains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
public function testItDoesNotRenderIfNewsletterTypeIsNotAutomatic() {
|
||||
$newsletter = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_STANDARD);
|
||||
$sendingTask = $this->createSendingTask($newsletter);
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->equals('[]');
|
||||
}
|
||||
@@ -242,7 +97,7 @@ class RendererTest extends \MailPoetTest {
|
||||
$newsletter = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_AUTOMATIC);
|
||||
$this->setGroupAndEventOptions($newsletter, WooCommerceEmail::SLUG, 'some_event');
|
||||
$sendingTask = $this->createSendingTask($newsletter);
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->equals('[]');
|
||||
}
|
||||
@@ -252,7 +107,7 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->setGroupAndEventOptions($newsletter);
|
||||
$this->accBlock['displayType'] = 'titleOnly';
|
||||
$this->accBlock['pricePosition'] = 'hidden';
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, true);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, true);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('Product 4');
|
||||
expect($encodedResult)->contains('Product 3');
|
||||
@@ -265,7 +120,7 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->setGroupAndEventOptions($newsletter);
|
||||
$this->accBlock['displayType'] = 'titleOnly';
|
||||
$this->accBlock['pricePosition'] = 'hidden';
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, false);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, false);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->equals('[]');
|
||||
}
|
||||
@@ -276,7 +131,7 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->accBlock['displayType'] = 'titleOnly';
|
||||
$this->accBlock['pricePosition'] = 'hidden';
|
||||
$sendingTask = $this->createSendingTask($newsletter, 1, [AbandonedCart::TASK_META_NAME => []]);
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->equals('[]');
|
||||
}
|
||||
@@ -287,7 +142,7 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->accBlock['displayType'] = 'titleOnly';
|
||||
$this->accBlock['pricePosition'] = 'hidden';
|
||||
$sendingTask = $this->createSendingTask($newsletter);
|
||||
$result = $this->renderer->abandonedCartContentTransformedProducts($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$result = $this->block->render($newsletter, $this->accBlock, false, $sendingTask);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->notContains('Product 4');
|
||||
expect($encodedResult)->contains('Product 3');
|
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Newsletter\Renderer\Blocks;
|
||||
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\NewsletterPostEntity;
|
||||
use MailPoet\Newsletter\NewsletterPostsRepository;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class AutomatedLatestContentBlockTest extends \MailPoetTest {
|
||||
/** @var AutomatedLatestContentBlock */
|
||||
private $block;
|
||||
|
||||
/** @var NewslettersRepository */
|
||||
private $newslettersRepository;
|
||||
|
||||
/** @var NewsletterPostsRepository */
|
||||
private $newsletterPostRepository;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
/** @var array */
|
||||
private $postIds = [];
|
||||
|
||||
private $alcBlock = [
|
||||
'type' => 'automatedLatestContentLayout',
|
||||
'withLayout' => true,
|
||||
'amount' => '2',
|
||||
'contentType' => 'post',
|
||||
'terms' => [],
|
||||
'inclusionType' => 'include',
|
||||
'displayType' => 'excerpt',
|
||||
'titleFormat' => 'h2',
|
||||
'titleAlignment' => 'left',
|
||||
'titleIsLink' => false,
|
||||
'imageFullWidth' => true,
|
||||
'titlePosition' => 'abovePost',
|
||||
'featuredImagePosition' => 'left',
|
||||
'fullPostFeaturedImagePosition' => 'none',
|
||||
'showAuthor' => 'no',
|
||||
'authorPrecededBy' => 'Author:',
|
||||
'showCategories' => 'no',
|
||||
'categoriesPrecededBy' => 'Categories:',
|
||||
'readMoreType' => 'button',
|
||||
'readMoreText' => 'Read more',
|
||||
'readMoreButton' => [
|
||||
'type' => 'button',
|
||||
'text' => 'Read more',
|
||||
'url' => '[postLink]',
|
||||
'styles' => [
|
||||
'block' => [
|
||||
'backgroundColor' => '#e2973f',
|
||||
'borderColor' => '#e2973f',
|
||||
'borderWidth' => '0px',
|
||||
'borderRadius' => '5px',
|
||||
'borderStyle' => 'solid',
|
||||
'width' => '110px',
|
||||
'lineHeight' => '40px',
|
||||
'fontColor' => '#ffffff',
|
||||
'fontFamily' => 'Arial',
|
||||
'fontSize' => '14px',
|
||||
'fontWeight' => 'bold',
|
||||
'textAlign' => 'left',
|
||||
],
|
||||
],
|
||||
'context' => 'automatedLatestContentLayout.readMoreButton',
|
||||
],
|
||||
'sortBy' => 'newest',
|
||||
'showDivider' => false,
|
||||
'divider' => [
|
||||
'type' => 'divider',
|
||||
'styles' => [
|
||||
'block' => [
|
||||
'backgroundColor' => 'transparent',
|
||||
'padding' => '13px',
|
||||
'borderStyle' => 'solid',
|
||||
'borderWidth' => '3px',
|
||||
'borderColor' => '#aaaaaa',
|
||||
],
|
||||
],
|
||||
'context' => 'automatedLatestContentLayout.divider',
|
||||
],
|
||||
'backgroundColor' => '#ffffff',
|
||||
'backgroundColorAlternate' => '#eeeeee',
|
||||
];
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->block = $this->diContainer->get(AutomatedLatestContentBlock::class);
|
||||
$this->wp = $this->diContainer->get(WPFunctions::class);
|
||||
$this->newsletterPostRepository = $this->diContainer->get(NewsletterPostsRepository::class);
|
||||
$this->newslettersRepository = $this->diContainer->get(NewslettersRepository::class);
|
||||
|
||||
// Clear old posts
|
||||
$posts = $this->wp->getPosts(['post_type' => 'post']);
|
||||
foreach ($posts as $post) {
|
||||
$this->wp->wpDeletePost((int)$post->ID);
|
||||
}
|
||||
|
||||
$this->postIds = [];
|
||||
$this->postIds[] = $this->createPost('POST 1', '2020-01-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 2', '2020-02-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 3', '2020-03-01 01:01:01');
|
||||
$this->postIds[] = $this->createPost('POST 4', '2020-04-01 01:01:01');
|
||||
}
|
||||
|
||||
public function testItRendersLatestPostsInAlc() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->block->render($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
public function testItRendersPostOnlyOncePerEmail() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->block->render($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
$result = $this->block->render($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->notContains('POST 4');
|
||||
expect($encodedResult)->notContains('POST 3');
|
||||
expect($encodedResult)->contains('POST 2');
|
||||
expect($encodedResult)->contains('POST 1');
|
||||
}
|
||||
|
||||
public function testItCanRenderSamePostsForDifferentPostNotifications() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$result = $this->block->render($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
$notification2 = $this->createNewsletter('Newsletter2', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory2 = $this->createNewsletter('Newsletter2', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification2);
|
||||
$result = $this->block->render($notificationHistory2, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->contains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
public function testItRendersOnlyPostsNewerThanLastSent() {
|
||||
$notification = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION);
|
||||
$notificationHistory = $this->createNewsletter('Newsletter', NewsletterEntity::TYPE_NOTIFICATION_HISTORY, $notification);
|
||||
$newsletterPost = new NewsletterPostEntity($notification, $this->postIds[2]); // Id of POST3
|
||||
$this->newsletterPostRepository->persist($newsletterPost);
|
||||
$this->newsletterPostRepository->flush();
|
||||
$newsletterPost->setCreatedAt(new \DateTime('2020-03-30 01:01:01'));
|
||||
$this->newsletterPostRepository->flush();
|
||||
$result = $this->block->render($notificationHistory, $this->alcBlock);
|
||||
$encodedResult = json_encode($result);
|
||||
expect($encodedResult)->contains('POST 4');
|
||||
expect($encodedResult)->notContains('POST 3');
|
||||
expect($encodedResult)->notContains('POST 2');
|
||||
expect($encodedResult)->notContains('POST 1');
|
||||
}
|
||||
|
||||
private function createPost(string $title, string $publishDate, string $type = 'post') {
|
||||
return $this->wp->wpInsertPost([
|
||||
'post_title' => $title,
|
||||
'post_status' => 'publish',
|
||||
'post_date' => $publishDate,
|
||||
'post_date_gmt' => $this->wp->getGmtFromDate($publishDate),
|
||||
'post_type' => $type,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createNewsletter($subject, $type, $parent = null) {
|
||||
$newsletter = new NewsletterEntity();
|
||||
$newsletter->setSubject($subject);
|
||||
$newsletter->setType($type);
|
||||
$newsletter->setParent($parent);
|
||||
$this->newslettersRepository->persist($newsletter);
|
||||
$this->newslettersRepository->flush();
|
||||
return $newsletter;
|
||||
}
|
||||
|
||||
public function _after() {
|
||||
parent::_after();
|
||||
$this->truncateEntity(NewsletterPostEntity::class);
|
||||
$this->truncateEntity(NewsletterEntity::class);
|
||||
}
|
||||
}
|
@@ -39,7 +39,8 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\Renderer::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Columns\Renderer::class),
|
||||
new Preprocessor(
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\Renderer::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\AbandonedCartContent::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\AutomatedLatestContentBlock::class),
|
||||
Stub::make(
|
||||
\MailPoet\WooCommerce\TransactionalEmails::class,
|
||||
[
|
||||
@@ -70,7 +71,8 @@ class RendererTest extends \MailPoetTest {
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\Renderer::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Columns\Renderer::class),
|
||||
new Preprocessor(
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\Renderer::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\AbandonedCartContent::class),
|
||||
$this->diContainer->get(\MailPoet\Newsletter\Renderer\Blocks\AutomatedLatestContentBlock::class),
|
||||
Stub::make(
|
||||
\MailPoet\WooCommerce\TransactionalEmails::class,
|
||||
[
|
||||
|
@@ -4,20 +4,22 @@ namespace MailPoet\Test\Newsletter;
|
||||
|
||||
use Codeception\Stub;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\Renderer;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\AbandonedCartContent;
|
||||
use MailPoet\Newsletter\Renderer\Blocks\AutomatedLatestContentBlock;
|
||||
use MailPoet\Newsletter\Renderer\Preprocessor;
|
||||
use MailPoet\WooCommerce\TransactionalEmails;
|
||||
|
||||
class PreprocessorTest extends \MailPoetUnitTest {
|
||||
public function testProcessWooCommerceHeadingBlock() {
|
||||
$renderer = Stub::make(Renderer::class);
|
||||
$acc = Stub::make(AbandonedCartContent::class);
|
||||
$alc = Stub::make(AutomatedLatestContentBlock::class);
|
||||
$transactionalEmails = Stub::make(TransactionalEmails::class, [
|
||||
'getWCEmailSettings' => [
|
||||
'base_color' => '{base_color}',
|
||||
'base_text_color' => '{base_text_color}',
|
||||
],
|
||||
]);
|
||||
$preprocessor = new Preprocessor($renderer, $transactionalEmails);
|
||||
$preprocessor = new Preprocessor($acc, $alc, $transactionalEmails);
|
||||
expect($preprocessor->processBlock(new NewsletterEntity(), ['type' => 'woocommerceHeading']))->equals([[
|
||||
'type' => 'container',
|
||||
'orientation' => 'horizontal',
|
||||
@@ -41,8 +43,9 @@ class PreprocessorTest extends \MailPoetUnitTest {
|
||||
}
|
||||
|
||||
public function testProcessWooCommerceContentBlock() {
|
||||
$renderer = Stub::make(Renderer::class);
|
||||
$preprocessor = new Preprocessor($renderer, Stub::make(TransactionalEmails::class));
|
||||
$acc = Stub::make(AbandonedCartContent::class);
|
||||
$alc = Stub::make(AutomatedLatestContentBlock::class);
|
||||
$preprocessor = new Preprocessor($acc, $alc, Stub::make(TransactionalEmails::class));
|
||||
expect($preprocessor->processBlock(new NewsletterEntity(), ['type' => 'woocommerceContent']))->equals([[
|
||||
'type' => 'container',
|
||||
'orientation' => 'horizontal',
|
||||
|
Reference in New Issue
Block a user