Refactor BlocksRegistry to pass dependencies as an argument

For better extensibility of 3rd party developers, I refactored to pass Settings Controller as an argument.
[MAILPOET-5591]
This commit is contained in:
Jan Lysý
2023-11-06 17:24:17 +01:00
committed by Jan Lysý
parent 6e1a08d60b
commit 5644cab9e3
13 changed files with 83 additions and 37 deletions

View File

@@ -2,6 +2,8 @@
namespace MailPoet\EmailEditor\Engine\Renderer; namespace MailPoet\EmailEditor\Engine\Renderer;
use MailPoet\EmailEditor\Engine\SettingsController;
interface BlockRenderer { interface BlockRenderer {
public function render(string $blockContent, array $parsedBlock): string; public function render(string $blockContent, array $parsedBlock, SettingsController $settingsController): string;
} }

View File

@@ -2,22 +2,41 @@
namespace MailPoet\EmailEditor\Engine\Renderer; namespace MailPoet\EmailEditor\Engine\Renderer;
use MailPoet\EmailEditor\Engine\SettingsController;
class BlocksRegistry { class BlocksRegistry {
/** @var BlockRenderer[] */ /** @var BlockRenderer[] */
private $blockRenderersMap = []; private $blockRenderersMap = [];
public function addBlockRenderer(string $blockName, BlockRenderer $renderer): void { /** @var SettingsController */
$this->blockRenderersMap[$blockName] = $renderer; private $settingsController;
add_filter('render_block_' . $blockName, [$renderer, 'render'], 10, 2);
public function __construct(
SettingsController $settingsController
) {
$this->settingsController = $settingsController;
} }
public function removeBlockRenderer(string $blockName, BlockRenderer $renderer): void { public function addBlockRenderer(string $blockName, BlockRenderer $renderer): void {
$this->blockRenderersMap[$blockName] = $renderer;
add_filter('render_block_' . $blockName, [$this, 'renderBlock'], 10, 2);
}
public function removeBlockRenderer(string $blockName): void {
unset($this->blockRenderersMap[$blockName]); unset($this->blockRenderersMap[$blockName]);
remove_filter('render_block_' . $blockName, [$renderer, 'render']); remove_filter('render_block_' . $blockName, [$this, 'renderBlock']);
} }
public function getBlockRenderer(string $blockName): ?BlockRenderer { public function getBlockRenderer(string $blockName): ?BlockRenderer {
return apply_filters('mailpoet_block_renderer_' . $blockName, $this->blockRenderersMap[$blockName] ?? null); return apply_filters('mailpoet_block_renderer_' . $blockName, $this->blockRenderersMap[$blockName] ?? null);
} }
public function renderBlock($blockContent, $parsedBlock): string {
// Here we could add a default renderer for blocks that don't have a renderer registered
if (!isset($this->blockRenderersMap[$parsedBlock['blockName']])) {
throw new \InvalidArgumentException('Block renderer not found for block ' . $parsedBlock['name']);
}
return $this->blockRenderersMap[$parsedBlock['blockName']]->render($blockContent, $parsedBlock, $this->settingsController);
}
} }

View File

@@ -125,4 +125,16 @@ class SettingsController {
], ],
]; ];
} }
public function getLayoutWidthWithoutPadding(): string {
$layoutStyles = $this->getEmailLayoutStyles();
$width = $this->parseNumberFromStringWithPixels($layoutStyles['width']);
$width -= $this->parseNumberFromStringWithPixels($layoutStyles['padding']['left']);
$width -= $this->parseNumberFromStringWithPixels($layoutStyles['padding']['right']);
return "{$width}px";
}
private function parseNumberFromStringWithPixels(string $string): float {
return (float)str_replace('px', '', $string);
}
} }

View File

@@ -21,9 +21,9 @@ class Initializer {
} }
public function unregisterCoreBlocksRenderers(BlocksRegistry $blocksRegistry): void { public function unregisterCoreBlocksRenderers(BlocksRegistry $blocksRegistry): void {
$blocksRegistry->removeBlockRenderer('core/paragraph', new Renderer\Blocks\Paragraph()); $blocksRegistry->removeBlockRenderer('core/paragraph');
$blocksRegistry->removeBlockRenderer('core/heading', new Renderer\Blocks\Heading()); $blocksRegistry->removeBlockRenderer('core/heading');
$blocksRegistry->removeBlockRenderer('core/column', new Renderer\Blocks\Column()); $blocksRegistry->removeBlockRenderer('core/column');
$blocksRegistry->removeBlockRenderer('core/columns', new Renderer\Blocks\Columns()); $blocksRegistry->removeBlockRenderer('core/columns');
} }
} }

View File

@@ -3,9 +3,10 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer; use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer;
use MailPoet\EmailEditor\Engine\SettingsController;
class Column implements BlockRenderer { class Column implements BlockRenderer {
public function render($blockContent, array $parsedBlock): string { public function render($blockContent, array $parsedBlock, SettingsController $settingsController): string {
$content = ''; $content = '';
foreach ($parsedBlock['innerBlocks'] ?? [] as $block) { foreach ($parsedBlock['innerBlocks'] ?? [] as $block) {
$content .= render_block($block); $content .= render_block($block);
@@ -14,15 +15,15 @@ class Column implements BlockRenderer {
return str_replace( return str_replace(
'{column_content}', '{column_content}',
$content, $content,
$this->prepareColumnTemplate($parsedBlock) $this->prepareColumnTemplate($parsedBlock, $settingsController)
); );
} }
/** /**
* Based on MJML <mj-column> * Based on MJML <mj-column>
*/ */
private function prepareColumnTemplate(array $parsedBlock): string { private function prepareColumnTemplate(array $parsedBlock, SettingsController $settingsController): string {
$width = $parsedBlock['email_attrs']['width'] ?? '640px'; $width = $parsedBlock['email_attrs']['width'] ?? $settingsController->getLayoutWidthWithoutPadding();
$backgroundColor = $parsedBlock['attrs']['style']['color']['background'] ?? 'none'; $backgroundColor = $parsedBlock['attrs']['style']['color']['background'] ?? 'none';
$paddingBottom = $parsedBlock['attrs']['style']['spacing']['padding']['bottom'] ?? '0px'; $paddingBottom = $parsedBlock['attrs']['style']['spacing']['padding']['bottom'] ?? '0px';
$paddingLeft = $parsedBlock['attrs']['style']['spacing']['padding']['left'] ?? '0px'; $paddingLeft = $parsedBlock['attrs']['style']['spacing']['padding']['left'] ?? '0px';

View File

@@ -3,9 +3,10 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer; use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer;
use MailPoet\EmailEditor\Engine\SettingsController;
class Columns implements BlockRenderer { class Columns implements BlockRenderer {
public function render($blockContent, array $parsedBlock): string { public function render($blockContent, array $parsedBlock, SettingsController $settingsController): string {
$content = ''; $content = '';
foreach ($parsedBlock['innerBlocks'] ?? [] as $block) { foreach ($parsedBlock['innerBlocks'] ?? [] as $block) {
$content .= render_block($block); $content .= render_block($block);
@@ -14,15 +15,15 @@ class Columns implements BlockRenderer {
return str_replace( return str_replace(
'{columns_content}', '{columns_content}',
$content, $content,
$this->prepareColumnsTemplate($parsedBlock) $this->prepareColumnsTemplate($parsedBlock, $settingsController)
); );
} }
/** /**
* Based on MJML <mj-section> * Based on MJML <mj-section>
*/ */
private function prepareColumnsTemplate(array $parsedBlock): string { private function prepareColumnsTemplate(array $parsedBlock, SettingsController $settingsController): string {
$width = $parsedBlock['email_attrs']['width'] ?? '640px'; $width = $parsedBlock['email_attrs']['width'] ?? $settingsController->getLayoutWidthWithoutPadding();
$backgroundColor = $parsedBlock['attrs']['style']['color']['background'] ?? 'none'; $backgroundColor = $parsedBlock['attrs']['style']['color']['background'] ?? 'none';
$paddingBottom = $parsedBlock['attrs']['style']['spacing']['padding']['bottom'] ?? '0px'; $paddingBottom = $parsedBlock['attrs']['style']['spacing']['padding']['bottom'] ?? '0px';
$paddingLeft = $parsedBlock['attrs']['style']['spacing']['padding']['left'] ?? '0px'; $paddingLeft = $parsedBlock['attrs']['style']['spacing']['padding']['left'] ?? '0px';

View File

@@ -3,9 +3,10 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer; use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer;
use MailPoet\EmailEditor\Engine\SettingsController;
class Heading implements BlockRenderer { class Heading implements BlockRenderer {
public function render($blockContent, array $parsedBlock): string { public function render($blockContent, array $parsedBlock, SettingsController $settingsController): string {
return $blockContent; return $blockContent;
} }
} }

View File

@@ -2,20 +2,12 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\DI\ContainerWrapper;
use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer; use MailPoet\EmailEditor\Engine\Renderer\BlockRenderer;
use MailPoet\EmailEditor\Engine\SettingsController; use MailPoet\EmailEditor\Engine\SettingsController;
class Paragraph implements BlockRenderer { class Paragraph implements BlockRenderer {
public function render($blockContent, array $parsedBlock, SettingsController $settingsController): string {
private $settingsController; $contentStyles = $settingsController->getEmailContentStyles();
public function __construct() {
$this->settingsController = ContainerWrapper::getInstance()->get(SettingsController::class);
}
public function render($blockContent, array $parsedBlock): string {
$contentStyles = $this->settingsController->getEmailContentStyles();
return str_replace('{paragraph_content}', $blockContent, $this->prepareColumnTemplate($parsedBlock, $contentStyles)); return str_replace('{paragraph_content}', $blockContent, $this->prepareColumnTemplate($parsedBlock, $contentStyles));
} }

View File

@@ -2,6 +2,7 @@
namespace MailPoet\EmailEditor\Engine\Renderer; namespace MailPoet\EmailEditor\Engine\Renderer;
use MailPoet\EmailEditor\Engine\SettingsController;
use MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks\Paragraph; use MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks\Paragraph;
require_once __DIR__ . '/DummyBlockRenderer.php'; require_once __DIR__ . '/DummyBlockRenderer.php';
@@ -13,7 +14,7 @@ class BlocksRegistryTest extends \MailPoetTest {
public function _before() { public function _before() {
parent::_before(); parent::_before();
$this->registry = new BlocksRegistry(); $this->registry = new BlocksRegistry(new SettingsController());
} }
public function testItReturnsNullForUnknownRenderer() { public function testItReturnsNullForUnknownRenderer() {

View File

@@ -2,12 +2,14 @@
namespace MailPoet\EmailEditor\Engine\Renderer; namespace MailPoet\EmailEditor\Engine\Renderer;
use MailPoet\EmailEditor\Engine\SettingsController;
class DummyBlockRenderer implements BlockRenderer { class DummyBlockRenderer implements BlockRenderer {
public function render(string $blockContent, array $parsedBlock): string { public function render(string $blockContent, array $parsedBlock, SettingsController $settingsController): string {
if (!isset($parsedBlock['innerBlocks']) || empty($parsedBlock['innerBlocks'])) { if (!isset($parsedBlock['innerBlocks']) || empty($parsedBlock['innerBlocks'])) {
return $parsedBlock['innerHTML']; return $parsedBlock['innerHTML'];
} }
// Wrapper is rendered in parent Columns block because it needs to operate with columns count etc. // Wrapper is rendered in parent Columns block because it needs to operate with columns count etc.
return '[' . $this->render('', $parsedBlock['innerBlocks']) . ']'; return '[' . $this->render('', $parsedBlock['innerBlocks'], $settingsController) . ']';
} }
} }

View File

@@ -3,6 +3,7 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\EmailEditor; use MailPoet\EmailEditor\Engine\EmailEditor;
use MailPoet\EmailEditor\Engine\SettingsController;
class ColumnTest extends \MailPoetTest { class ColumnTest extends \MailPoetTest {
/** @var Column */ /** @var Column */
@@ -34,13 +35,17 @@ class ColumnTest extends \MailPoetTest {
], ],
]; ];
/** @var SettingsController */
private $settingsController;
public function _before() { public function _before() {
$this->diContainer->get(EmailEditor::class)->initialize(); $this->diContainer->get(EmailEditor::class)->initialize();
$this->columnRenderer = new Column(); $this->columnRenderer = new Column();
$this->settingsController = $this->diContainer->get(SettingsController::class);
} }
public function testItRendersColumnContent() { public function testItRendersColumnContent() {
$rendered = $this->columnRenderer->render('', $this->parsedColumn); $rendered = $this->columnRenderer->render('', $this->parsedColumn, $this->settingsController);
verify($rendered)->stringContainsString('Column content'); verify($rendered)->stringContainsString('Column content');
verify($rendered)->stringContainsString('width:300px;'); verify($rendered)->stringContainsString('width:300px;');
verify($rendered)->stringContainsString('max-width:300px;'); verify($rendered)->stringContainsString('max-width:300px;');
@@ -63,7 +68,7 @@ class ColumnTest extends \MailPoetTest {
], ],
], ],
]; ];
$rendered = $this->columnRenderer->render('', $parsedColumn); $rendered = $this->columnRenderer->render('', $parsedColumn, $this->settingsController);
verify($rendered)->stringContainsString('background:#abcdef;'); verify($rendered)->stringContainsString('background:#abcdef;');
verify($rendered)->stringContainsString('background-color:#abcdef;'); verify($rendered)->stringContainsString('background-color:#abcdef;');
verify($rendered)->stringContainsString('padding-bottom:5px;'); verify($rendered)->stringContainsString('padding-bottom:5px;');

View File

@@ -3,6 +3,7 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\EmailEditor; use MailPoet\EmailEditor\Engine\EmailEditor;
use MailPoet\EmailEditor\Engine\SettingsController;
class ColumnsTest extends \MailPoetTest { class ColumnsTest extends \MailPoetTest {
/** @var Columns */ /** @var Columns */
@@ -40,13 +41,17 @@ class ColumnsTest extends \MailPoetTest {
], ],
]; ];
/** @var SettingsController */
private $settingsController;
public function _before() { public function _before() {
$this->diContainer->get(EmailEditor::class)->initialize(); $this->diContainer->get(EmailEditor::class)->initialize();
$this->columnsRenderer = new Columns(); $this->columnsRenderer = new Columns();
$this->settingsController = $this->diContainer->get(SettingsController::class);
} }
public function testItRendersInnerColumn() { public function testItRendersInnerColumn() {
$rendered = $this->columnsRenderer->render('', $this->parsedColumns); $rendered = $this->columnsRenderer->render('', $this->parsedColumns, $this->settingsController);
verify($rendered)->stringContainsString('Column 1'); verify($rendered)->stringContainsString('Column 1');
verify($rendered)->stringContainsString('width:784px;'); verify($rendered)->stringContainsString('width:784px;');
verify($rendered)->stringContainsString('max-width:784px;'); verify($rendered)->stringContainsString('max-width:784px;');
@@ -69,7 +74,7 @@ class ColumnsTest extends \MailPoetTest {
], ],
], ],
]; ];
$rendered = $this->columnsRenderer->render('', $parsedColumns); $rendered = $this->columnsRenderer->render('', $parsedColumns, $this->settingsController);
verify($rendered)->stringContainsString('background:#abcdef;'); verify($rendered)->stringContainsString('background:#abcdef;');
verify($rendered)->stringContainsString('background-color:#abcdef;'); verify($rendered)->stringContainsString('background-color:#abcdef;');
verify($rendered)->stringContainsString('padding-bottom:5px;'); verify($rendered)->stringContainsString('padding-bottom:5px;');

View File

@@ -3,6 +3,7 @@
namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks; namespace MailPoet\EmailEditor\Integrations\Core\Renderer\Blocks;
use MailPoet\EmailEditor\Engine\EmailEditor; use MailPoet\EmailEditor\Engine\EmailEditor;
use MailPoet\EmailEditor\Engine\SettingsController;
class ParagraphTest extends \MailPoetTest { class ParagraphTest extends \MailPoetTest {
/** @var Paragraph */ /** @var Paragraph */
@@ -22,13 +23,17 @@ class ParagraphTest extends \MailPoetTest {
], ],
]; ];
/** @var SettingsController */
private $settingsController;
public function _before() { public function _before() {
$this->diContainer->get(EmailEditor::class)->initialize(); $this->diContainer->get(EmailEditor::class)->initialize();
$this->paragraphRenderer = new Paragraph(); $this->paragraphRenderer = new Paragraph();
$this->settingsController = $this->diContainer->get(SettingsController::class);
} }
public function testItRendersContent(): void { public function testItRendersContent(): void {
$rendered = $this->paragraphRenderer->render('<p>Lorem Ipsum</p>', $this->parsedParagraph); $rendered = $this->paragraphRenderer->render('<p>Lorem Ipsum</p>', $this->parsedParagraph, $this->settingsController);
verify($rendered)->stringNotContainsString('width:'); // Paragraph should not contain width verify($rendered)->stringNotContainsString('width:'); // Paragraph should not contain width
verify($rendered)->stringContainsString('Lorem Ipsum'); verify($rendered)->stringContainsString('Lorem Ipsum');
verify($rendered)->stringContainsString('font-size:16px;'); verify($rendered)->stringContainsString('font-size:16px;');