diff --git a/lib/Newsletter/Editor/PostTransformer.php b/lib/Newsletter/Editor/PostTransformer.php
index cd8ee7075b..971730d62a 100644
--- a/lib/Newsletter/Editor/PostTransformer.php
+++ b/lib/Newsletter/Editor/PostTransformer.php
@@ -2,26 +2,22 @@
namespace MailPoet\Newsletter\Editor;
-use MailPoet\Config\Env;
-use MailPoet\WooCommerce\Helper as WooCommerceHelper;
-use MailPoet\WP\Functions as WPFunctions;
-
class PostTransformer {
+ /** @var PostTransformerContentsExtractor */
+ private $extractor;
private $args;
private $with_layout;
private $image_position;
- private $wp;
- /** @var WooCommerceHelper */
- private $woocommerce_helper;
-
- function __construct($args) {
+ function __construct($args, PostTransformerContentsExtractor $extractor = null) {
$this->args = $args;
$this->with_layout = isset($args['withLayout']) ? (bool)filter_var($args['withLayout'], FILTER_VALIDATE_BOOLEAN) : false;
$this->image_position = 'left';
- $this->wp = new WPFunctions();
- $this->woocommerce_helper = new WooCommerceHelper();
+ if ($extractor === null) {
+ $extractor = new PostTransformerContentsExtractor($args);
+ }
+ $this->extractor = $extractor;
}
function getDivider() {
@@ -41,9 +37,9 @@ class PostTransformer {
}
private function getStructure($post) {
- $content = $this->getContent($post, true, $this->args['displayType']);
- $title = $this->getTitle($post);
- $featured_image = $this->getFeaturedImage($post);
+ $content = $this->extractor->getContent($post, true, $this->args['displayType']);
+ $title = $this->extractor->getTitle($post);
+ $featured_image = $this->extractor->getFeaturedImage($post);
$featured_image_position = $this->args['featuredImagePosition'];
if (
@@ -51,7 +47,7 @@ class PostTransformer {
&& $featured_image_position === 'belowTitle'
&& (
$this->args['displayType'] === 'excerpt'
- || $this->isProduct($post)
+ || $this->extractor->isProduct($post)
)
) {
array_unshift($content, $title, $featured_image);
@@ -73,9 +69,9 @@ class PostTransformer {
private function getStructureWithLayout($post) {
$with_post_class = $this->args['displayType'] === 'full';
- $content = $this->getContent($post, $with_post_class, $this->args['displayType']);
- $title = $this->getTitle($post);
- $featured_image = $this->getFeaturedImage($post);
+ $content = $this->extractor->getContent($post, $with_post_class, $this->args['displayType']);
+ $title = $this->extractor->getTitle($post);
+ $featured_image = $this->extractor->getFeaturedImage($post);
$featured_image_position = $this->args['featuredImagePosition'];
@@ -84,7 +80,7 @@ class PostTransformer {
|| $featured_image_position === 'none'
|| (
$this->args['displayType'] !== 'excerpt'
- && !$this->isProduct($post)
+ && !$this->extractor->isProduct($post)
)
) {
array_unshift($content, $title);
@@ -154,180 +150,4 @@ class PostTransformer {
$this->image_position = ($this->image_position === 'left') ? 'right' : 'left';
return $this->image_position;
}
-
- private function getContent($post, $with_post_class, $display_type) {
- $content_manager = new PostContentManager();
- $meta_manager = new MetaInformationManager();
-
- $content = $content_manager->getContent($post, $this->args['displayType']);
- $content = $meta_manager->appendMetaInformation($content, $post, $this->args);
- $content = $content_manager->filterContent($content, $display_type, $with_post_class);
-
- $structure_transformer = new StructureTransformer();
- $content = $structure_transformer->transform($content, $this->args['imageFullWidth'] === true);
-
- if ($this->isProduct($post)) {
- $content = $this->addProductDataToContent($content, $post);
- }
-
- $read_more_btn = $this->getReadMoreButton($post);
- $blocks_count = count($content);
- if ($read_more_btn['type'] === 'text' && $blocks_count > 0 && $content[$blocks_count - 1]['type'] === 'text') {
- $content[$blocks_count - 1]['text'] .= $read_more_btn['text'];
- } else {
- $content[] = $read_more_btn;
- }
- return $content;
- }
-
- private function getImageInfo($id) {
- /*
- * In some cases wp_get_attachment_image_src ignore the second parameter
- * and use global variable $content_width value instead.
- * By overriding it ourselves when ensure a constant behaviour regardless
- * of the user setup.
- *
- * https://mailpoet.atlassian.net/browse/MAILPOET-1365
- */
- global $content_width; // default is NULL
-
- $content_width_copy = $content_width;
- $content_width = Env::NEWSLETTER_CONTENT_WIDTH;
- $image_info = $this->wp->wpGetAttachmentImageSrc($id, 'mailpoet_newsletter_max');
- $content_width = $content_width_copy;
-
- return $image_info;
- }
-
- private function getFeaturedImage($post) {
- $post_id = $post->ID;
- $post_title = $this->sanitizeTitle($post->post_title);
- $image_full_width = (bool)filter_var($this->args['imageFullWidth'], FILTER_VALIDATE_BOOLEAN);
-
- if (!has_post_thumbnail($post_id)) {
- return false;
- }
-
- $thumbnail_id = $this->wp->getPostThumbnailId($post_id);
- $image_info = $this->getImageInfo($thumbnail_id);
-
- // get alt text
- $alt_text = trim(strip_tags(get_post_meta(
- $thumbnail_id,
- '_wp_attachment_image_alt',
- true
- )));
- if (strlen($alt_text) === 0) {
- // if the alt text is empty then use the post title
- $alt_text = trim(strip_tags($post_title));
- }
-
- return [
- 'type' => 'image',
- 'link' => $this->wp->getPermalink($post_id),
- 'src' => $image_info[0],
- 'alt' => $alt_text,
- 'fullWidth' => $image_full_width,
- 'width' => $image_info[1],
- 'height' => $image_info[2],
- 'styles' => [
- 'block' => [
- 'textAlign' => 'center',
- ],
- ],
- ];
- }
-
- private function getReadMoreButton($post) {
- if ($this->args['readMoreType'] === 'button') {
- $button = $this->args['readMoreButton'];
- $button['url'] = $this->wp->getPermalink($post->ID);
- return $button;
- }
-
- $read_more_text = sprintf(
- '
%s
',
- $this->wp->getPermalink($post->ID),
- $this->args['readMoreText']
- );
-
- return [
- 'type' => 'text',
- 'text' => $read_more_text,
- ];
- }
-
- private function getTitle($post) {
- $title = $this->sanitizeTitle($post->post_title);
-
- if (filter_var($this->args['titleIsLink'], FILTER_VALIDATE_BOOLEAN)) {
- $title = '' . $title . '';
- }
-
- if (in_array($this->args['titleFormat'], ['h1', 'h2', 'h3'])) {
- $tag = $this->args['titleFormat'];
- } elseif ($this->args['titleFormat'] === 'ul') {
- $tag = 'li';
- } else {
- $tag = 'h1';
- }
-
- $alignment = (in_array($this->args['titleAlignment'], ['left', 'right', 'center'])) ? $this->args['titleAlignment'] : 'left';
-
- $title = '<' . $tag . ' data-post-id="' . $post->ID . '" style="text-align: ' . $alignment . ';">' . $title . '' . $tag . '>';
- return [
- 'type' => 'text',
- 'text' => $title,
- ];
- }
-
- private function getPrice($post) {
- $price = null;
- $product = null;
- if ($this->woocommerce_helper->isWooCommerceActive()) {
- $product = $this->woocommerce_helper->wcGetProduct($post->ID);
- }
- if ($product) {
- $price = '' . strip_tags($product->get_price_html(), '') . '
';
- }
- return $price;
- }
-
- private function addProductDataToContent($content, $post) {
- if (!isset($this->args['pricePosition']) || $this->args['pricePosition'] === 'hidden') {
- return $content;
- }
- $price = $this->getPrice($post);
- $blocks_count = count($content);
- if ($blocks_count > 0 && $content[$blocks_count - 1]['type'] === 'text') {
- if ($this->args['pricePosition'] === 'below') {
- $content[$blocks_count - 1]['text'] = $content[$blocks_count - 1]['text'] . $price;
- } else {
- $content[$blocks_count - 1]['text'] = $price . $content[$blocks_count - 1]['text'];
- }
- } else {
- $content[] = [
- 'type' => 'text',
- 'text' => $price,
- ];
- }
- return $content;
- }
-
- private function isProduct($post) {
- return $post->post_type === 'product';
- }
-
- /**
- * Replaces double quote character with a unicode
- * alternative to avoid problems when inlining CSS.
- * [MAILPOET-1937]
- *
- * @param string $title
- * @return string
- */
- private function sanitizeTitle($title) {
- return str_replace('"', '"', $title);
- }
-
}
diff --git a/lib/Newsletter/Editor/PostTransformerContentsExtractor.php b/lib/Newsletter/Editor/PostTransformerContentsExtractor.php
new file mode 100644
index 0000000000..f50f558bc1
--- /dev/null
+++ b/lib/Newsletter/Editor/PostTransformerContentsExtractor.php
@@ -0,0 +1,199 @@
+args = $args;
+ $this->wp = new WPFunctions();
+ $this->woocommerce_helper = new WooCommerceHelper();
+ }
+
+ function getContent($post, $with_post_class, $display_type) {
+ $content_manager = new PostContentManager();
+ $meta_manager = new MetaInformationManager();
+
+ $content = $content_manager->getContent($post, $this->args['displayType']);
+ $content = $meta_manager->appendMetaInformation($content, $post, $this->args);
+ $content = $content_manager->filterContent($content, $display_type, $with_post_class);
+
+ $structure_transformer = new StructureTransformer();
+ $content = $structure_transformer->transform($content, $this->args['imageFullWidth'] === true);
+
+ if ($this->isProduct($post)) {
+ $content = $this->addProductDataToContent($content, $post);
+ }
+
+ $read_more_btn = $this->getReadMoreButton($post);
+ $blocks_count = count($content);
+ if ($read_more_btn['type'] === 'text' && $blocks_count > 0 && $content[$blocks_count - 1]['type'] === 'text') {
+ $content[$blocks_count - 1]['text'] .= $read_more_btn['text'];
+ } else {
+ $content[] = $read_more_btn;
+ }
+ return $content;
+ }
+
+ private function getImageInfo($id) {
+ /*
+ * In some cases wp_get_attachment_image_src ignore the second parameter
+ * and use global variable $content_width value instead.
+ * By overriding it ourselves when ensure a constant behaviour regardless
+ * of the user setup.
+ *
+ * https://mailpoet.atlassian.net/browse/MAILPOET-1365
+ */
+ global $content_width; // default is NULL
+
+ $content_width_copy = $content_width;
+ $content_width = Env::NEWSLETTER_CONTENT_WIDTH;
+ $image_info = $this->wp->wpGetAttachmentImageSrc($id, 'mailpoet_newsletter_max');
+ $content_width = $content_width_copy;
+
+ return $image_info;
+ }
+
+ function getFeaturedImage($post) {
+ $post_id = $post->ID;
+ $post_title = $this->sanitizeTitle($post->post_title);
+ $image_full_width = (bool)filter_var($this->args['imageFullWidth'], FILTER_VALIDATE_BOOLEAN);
+
+ if (!has_post_thumbnail($post_id)) {
+ return false;
+ }
+
+ $thumbnail_id = $this->wp->getPostThumbnailId($post_id);
+ $image_info = $this->getImageInfo($thumbnail_id);
+
+ // get alt text
+ $alt_text = trim(strip_tags(get_post_meta(
+ $thumbnail_id,
+ '_wp_attachment_image_alt',
+ true
+ )));
+ if (strlen($alt_text) === 0) {
+ // if the alt text is empty then use the post title
+ $alt_text = trim(strip_tags($post_title));
+ }
+
+ return [
+ 'type' => 'image',
+ 'link' => $this->wp->getPermalink($post_id),
+ 'src' => $image_info[0],
+ 'alt' => $alt_text,
+ 'fullWidth' => $image_full_width,
+ 'width' => $image_info[1],
+ 'height' => $image_info[2],
+ 'styles' => [
+ 'block' => [
+ 'textAlign' => 'center',
+ ],
+ ],
+ ];
+ }
+
+ private function getReadMoreButton($post) {
+ if ($this->args['readMoreType'] === 'button') {
+ $button = $this->args['readMoreButton'];
+ $button['url'] = $this->wp->getPermalink($post->ID);
+ return $button;
+ }
+
+ $read_more_text = sprintf(
+ '%s
',
+ $this->wp->getPermalink($post->ID),
+ $this->args['readMoreText']
+ );
+
+ return [
+ 'type' => 'text',
+ 'text' => $read_more_text,
+ ];
+ }
+
+ function getTitle($post) {
+ $title = $this->sanitizeTitle($post->post_title);
+
+ if (filter_var($this->args['titleIsLink'], FILTER_VALIDATE_BOOLEAN)) {
+ $title = '' . $title . '';
+ }
+
+ if (in_array($this->args['titleFormat'], ['h1', 'h2', 'h3'])) {
+ $tag = $this->args['titleFormat'];
+ } elseif ($this->args['titleFormat'] === 'ul') {
+ $tag = 'li';
+ } else {
+ $tag = 'h1';
+ }
+
+ $alignment = (in_array($this->args['titleAlignment'], ['left', 'right', 'center'])) ? $this->args['titleAlignment'] : 'left';
+
+ $title = '<' . $tag . ' data-post-id="' . $post->ID . '" style="text-align: ' . $alignment . ';">' . $title . '' . $tag . '>';
+ return [
+ 'type' => 'text',
+ 'text' => $title,
+ ];
+ }
+
+ private function getPrice($post) {
+ $price = null;
+ $product = null;
+ if ($this->woocommerce_helper->isWooCommerceActive()) {
+ $product = $this->woocommerce_helper->wcGetProduct($post->ID);
+ }
+ if ($product) {
+ $price = '' . strip_tags($product->get_price_html(), '') . '
';
+ }
+ return $price;
+ }
+
+ private function addProductDataToContent($content, $post) {
+ if (!isset($this->args['pricePosition']) || $this->args['pricePosition'] === 'hidden') {
+ return $content;
+ }
+ $price = $this->getPrice($post);
+ $blocks_count = count($content);
+ if ($blocks_count > 0 && $content[$blocks_count - 1]['type'] === 'text') {
+ if ($this->args['pricePosition'] === 'below') {
+ $content[$blocks_count - 1]['text'] = $content[$blocks_count - 1]['text'] . $price;
+ } else {
+ $content[$blocks_count - 1]['text'] = $price . $content[$blocks_count - 1]['text'];
+ }
+ } else {
+ $content[] = [
+ 'type' => 'text',
+ 'text' => $price,
+ ];
+ }
+ return $content;
+ }
+
+ function isProduct($post) {
+ return $post->post_type === 'product';
+ }
+
+ /**
+ * Replaces double quote character with a unicode
+ * alternative to avoid problems when inlining CSS.
+ * [MAILPOET-1937]
+ *
+ * @param string $title
+ * @return string
+ */
+ private function sanitizeTitle($title) {
+ return str_replace('"', '"', $title);
+ }
+}
diff --git a/tests/integration/Newsletter/Editor/PostContentTransformerTest.php b/tests/integration/Newsletter/Editor/PostContentTransformerTest.php
index 1febda5ba4..25e862afbd 100644
--- a/tests/integration/Newsletter/Editor/PostContentTransformerTest.php
+++ b/tests/integration/Newsletter/Editor/PostContentTransformerTest.php
@@ -2,8 +2,9 @@
namespace MailPoet\Test\Newsletter\Editor;
-use AspectMock\Test as Mock;
+use Codeception\Stub\Expected;
use MailPoet\Newsletter\Editor\PostTransformer;
+use MailPoet\Newsletter\Editor\PostTransformerContentsExtractor;
class PostContentTransformerTest extends \MailPoetTest {
/** @var array */
@@ -241,12 +242,25 @@ class PostContentTransformerTest extends \MailPoetTest {
$post = [];
$expected_with_post_class = true;
- $transformer = new PostTransformer($args);
- $mock_get_content = Mock::double($transformer, ['getContent' => $this->content_mock]);
- Mock::double($transformer, ['getFeaturedImage' => null]);
- Mock::double($transformer, ['getTitle' => 'Title']);
+ $extractor = $this->make(
+ PostTransformerContentsExtractor::class,
+ [
+ 'getContent' => Expected::once($this->content_mock),
+ 'getFeaturedImage' => null,
+ 'getTitle' => 'Title',
+ ],
+ $this
+ );
+ $extractor->expects($this->once())
+ ->method('getContent')
+ ->with(
+ $this->equalTo($post),
+ $this->equalTo($expected_with_post_class),
+ $this->equalTo('full')
+ );
+
+ $transformer = new PostTransformer($args, $extractor);
$transformer->transform($post);
- $mock_get_content->verifyInvokedOnce('getContent', [$post, $expected_with_post_class, 'full']);
}
function testShouldNotAddClassToParagraphsInExcerptWithLayout() {
@@ -259,27 +273,42 @@ class PostContentTransformerTest extends \MailPoetTest {
$post = [];
$expected_with_post_class = false;
- $transformer = new PostTransformer($args);
- $mock_get_content = Mock::double($transformer, ['getContent' => $this->content_mock]);
- Mock::double($transformer, ['getFeaturedImage' => null]);
- Mock::double($transformer, ['getTitle' => 'Title']);
+ $extractor = $this->make(
+ PostTransformerContentsExtractor::class,
+ [
+ 'getContent' => Expected::once($this->content_mock),
+ 'getFeaturedImage' => null,
+ 'getTitle' => 'Title',
+ ],
+ $this
+ );
+ $extractor->expects($this->once())
+ ->method('getContent')
+ ->with(
+ $this->equalTo($post),
+ $this->equalTo($expected_with_post_class),
+ $this->equalTo('excerpt')
+ );
+
+ $transformer = new PostTransformer($args, $extractor);
$transformer->transform($post);
- $mock_get_content->verifyInvokedOnce('getContent', [$post, $expected_with_post_class, 'excerpt']);
}
/**
* @return PostTransformer
*/
private function getTransformer(array $args, array $content, array $title, array $image = null) {
- $transformer = new PostTransformer($args);
- Mock::double($transformer, ['getContent' => $content]);
- Mock::double($transformer, ['getFeaturedImage' => $image]);
- Mock::double($transformer, ['getTitle' => $title]);
- Mock::double($transformer, ['isProduct' => false]);
+ $extractor = $this->make(
+ PostTransformerContentsExtractor::class,
+ [
+ 'getContent' => $content,
+ 'getFeaturedImage' => $image,
+ 'getTitle' => $title,
+ 'isProduct' => false,
+ ],
+ $this
+ );
+ $transformer = new PostTransformer($args, $extractor);
return $transformer;
}
-
- function _after() {
- Mock::clean();
- }
}