Add Preprocessor for removing unwanted blocks
[MAILPOET-5591]
This commit is contained in:
@ -336,6 +336,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\EmailEditor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\EmailApiController::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\SettingsController::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Preprocessors\CleanupPreprocessor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TopLevelPreprocessor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Renderer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\BlocksRenderer::class)->setPublic(true);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\CleanupPreprocessor;
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\Preprocessor;
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TopLevelPreprocessor;
|
||||
|
||||
@ -10,18 +11,21 @@ class PreprocessManager {
|
||||
private $preprocessors = [];
|
||||
|
||||
public function __construct(
|
||||
CleanupPreprocessor $cleanupPreprocessor,
|
||||
TopLevelPreprocessor $topLevelPreprocessor
|
||||
) {
|
||||
$this->registerPreprocessor($cleanupPreprocessor);
|
||||
$this->registerPreprocessor($topLevelPreprocessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parsedBlocks
|
||||
* @param array{width: int, background: string, padding: array{bottom: int, left: int, right: int, top: int}} $layoutStyles
|
||||
* @return array
|
||||
*/
|
||||
public function preprocess(array $parsedBlocks): array {
|
||||
public function preprocess(array $parsedBlocks, array $layoutStyles): array {
|
||||
foreach ($this->preprocessors as $preprocessor) {
|
||||
$parsedBlocks = $preprocessor->preprocess($parsedBlocks);
|
||||
$parsedBlocks = $preprocessor->preprocess($parsedBlocks, $layoutStyles);
|
||||
}
|
||||
return $parsedBlocks;
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer\Preprocessors;
|
||||
|
||||
class CleanupPreprocessor implements Preprocessor {
|
||||
public function preprocess(array $parsedBlocks, array $layoutStyles): array {
|
||||
foreach ($parsedBlocks as $key => $block) {
|
||||
// https://core.trac.wordpress.org/ticket/45312
|
||||
// \WP_Block_Parser::parse_blocks() sometimes add a block with name null that can cause unexpected spaces in rendered content
|
||||
// This behavior was reported as an issue, but it was closed as won't fix
|
||||
if ($block['blockName'] === null) {
|
||||
unset($parsedBlocks[$key]);
|
||||
}
|
||||
}
|
||||
return array_values($parsedBlocks);
|
||||
}
|
||||
}
|
@ -3,5 +3,5 @@
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer\Preprocessors;
|
||||
|
||||
interface Preprocessor {
|
||||
public function preprocess(array $parsedBlocks): array;
|
||||
public function preprocess(array $parsedBlocks, array $layoutStyles): array;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class TopLevelPreprocessor implements Preprocessor {
|
||||
* But for rendering purposes it is more convenient to have them wrapped in a single column.
|
||||
* This method walks through the first level of blocks and wraps non column blocks into a single column.
|
||||
*/
|
||||
public function preprocess(array $parsedBlocks): array {
|
||||
public function preprocess(array $parsedBlocks, array $layoutStyles): array {
|
||||
$wrappedParsedBlocks = [];
|
||||
$nonColumnsBlocksBuffer = [];
|
||||
foreach ($parsedBlocks as $block) {
|
||||
|
@ -42,7 +42,7 @@ class Renderer {
|
||||
$parser = new \WP_Block_Parser();
|
||||
$parsedBlocks = $parser->parse($post->post_content); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
|
||||
$parsedBlocks = $this->preprocessManager->preprocess($parsedBlocks);
|
||||
$parsedBlocks = $this->preprocessManager->preprocess($parsedBlocks, $this->stylesController->getEmailLayoutStyles());
|
||||
$renderedBody = $this->blocksRenderer->render($parsedBlocks);
|
||||
|
||||
$styles = (string)file_get_contents(dirname(__FILE__) . '/' . self::TEMPLATE_STYLES_FILE);
|
||||
|
@ -3,18 +3,32 @@
|
||||
namespace unit\EmailEditor\Engine\Renderer;
|
||||
|
||||
use MailPoet\EmailEditor\Engine\Renderer\PreprocessManager;
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\CleanupPreprocessor;
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TopLevelPreprocessor;
|
||||
|
||||
class PreprocessManagerTest extends \MailPoetUnitTest {
|
||||
public function testItCallsPreprocessorsProperly(): void {
|
||||
$layoutStyles = [
|
||||
'width' => 600,
|
||||
'background' => '#ffffff',
|
||||
'padding' => [
|
||||
'bottom' => 0,
|
||||
'left' => 0,
|
||||
'right' => 0,
|
||||
'top' => 0,
|
||||
],
|
||||
];
|
||||
$topLevel = $this->createMock(TopLevelPreprocessor::class);
|
||||
$topLevel->expects($this->once())->method('preprocess')->willReturn([]);
|
||||
|
||||
$cleanup = $this->createMock(CleanupPreprocessor::class);
|
||||
$cleanup->expects($this->once())->method('preprocess')->willReturn([]);
|
||||
|
||||
$secondPreprocessor = $this->createMock(TopLevelPreprocessor::class);
|
||||
$secondPreprocessor->expects($this->once())->method('preprocess')->willReturn([]);
|
||||
|
||||
$preprocessManager = new PreprocessManager($topLevel);
|
||||
$preprocessManager = new PreprocessManager($cleanup, $topLevel);
|
||||
$preprocessManager->registerPreprocessor($secondPreprocessor);
|
||||
expect($preprocessManager->preprocess([]))->equals([]);
|
||||
expect($preprocessManager->preprocess([], $layoutStyles))->equals([]);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace unit\EmailEditor\Engine\Renderer\Preprocessors;
|
||||
|
||||
use MailPoet\EmailEditor\Engine\Renderer\Preprocessors\CleanupPreprocessor;
|
||||
|
||||
class CleanupPreprocessorTest extends \MailPoetUnitTest {
|
||||
|
||||
private const PARAGRAPH_BLOCK = [
|
||||
'blockName' => 'core/paragraph',
|
||||
'attrs' => [],
|
||||
'innerHTML' => 'Paragraph content',
|
||||
];
|
||||
|
||||
private const COLUMNS_BLOCK = [
|
||||
'blockName' => 'core/columns',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [[
|
||||
'blockName' => 'core/column',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [],
|
||||
]],
|
||||
];
|
||||
|
||||
/** @var CleanupPreprocessor */
|
||||
private $preprocessor;
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->preprocessor = new CleanupPreprocessor();
|
||||
}
|
||||
|
||||
public function testItRemovesUnwantedBlocks(): void {
|
||||
$blocks = [
|
||||
self::COLUMNS_BLOCK,
|
||||
['blockName' => null, 'attrs' => [], 'innerHTML' => "\r\n"],
|
||||
self::PARAGRAPH_BLOCK,
|
||||
];
|
||||
$result = $this->preprocessor->preprocess($blocks, []);
|
||||
expect($result)->count(2);
|
||||
expect($result[0])->equals(self::COLUMNS_BLOCK);
|
||||
expect($result[1])->equals(self::PARAGRAPH_BLOCK);
|
||||
}
|
||||
|
||||
public function testItPreservesAllRelevantBlocks(): void {
|
||||
$blocks = [
|
||||
self::COLUMNS_BLOCK,
|
||||
self::PARAGRAPH_BLOCK,
|
||||
self::COLUMNS_BLOCK,
|
||||
];
|
||||
$result = $this->preprocessor->preprocess($blocks, []);
|
||||
expect($result)->count(3);
|
||||
expect($result[0])->equals(self::COLUMNS_BLOCK);
|
||||
expect($result[1])->equals(self::PARAGRAPH_BLOCK);
|
||||
expect($result[2])->equals(self::COLUMNS_BLOCK);
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ class TopLevelPreprocessorTest extends \MailPoetUnitTest {
|
||||
|
||||
public function testItWrapsSingleTopLevelBlockIntoColumns() {
|
||||
$parsedDocument = [$this->paragraphBlock];
|
||||
$result = $this->preprocessor->preprocess($parsedDocument);
|
||||
$result = $this->preprocessor->preprocess($parsedDocument, []);
|
||||
verify($result[0]['blockName'])->equals('core/columns');
|
||||
verify($result[0]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
verify($result[0]['innerBlocks'][0]['innerBlocks'][0]['blockName'])->equals('core/paragraph');
|
||||
@ -41,14 +41,14 @@ class TopLevelPreprocessorTest extends \MailPoetUnitTest {
|
||||
|
||||
public function testItDoesntWrapColumns() {
|
||||
$parsedDocumentWithMultipleColumns = [$this->columnsBlock, $this->columnsBlock];
|
||||
$result = $this->preprocessor->preprocess($parsedDocumentWithMultipleColumns);
|
||||
$result = $this->preprocessor->preprocess($parsedDocumentWithMultipleColumns, []);
|
||||
verify($result)->equals($parsedDocumentWithMultipleColumns);
|
||||
}
|
||||
|
||||
public function testItWrapsTopLevelBlocksSpreadBetweenColumns() {
|
||||
$parsedDocument = [$this->paragraphBlock, $this->columnsBlock, $this->paragraphBlock, $this->paragraphBlock];
|
||||
// We expect to wrap top level paragraph blocks into columns so the result should three columns blocks
|
||||
$result = $this->preprocessor->preprocess($parsedDocument);
|
||||
$result = $this->preprocessor->preprocess($parsedDocument, []);
|
||||
verify($result)->arrayCount(3);
|
||||
// First columns contain columns with one paragraph block
|
||||
verify($result[0]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
|
Reference in New Issue
Block a user