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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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';
|
||||||
|
@@ -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';
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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() {
|
||||||
|
@@ -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) . ']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;');
|
||||||
|
@@ -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;');
|
||||||
|
@@ -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;');
|
||||||
|
Reference in New Issue
Block a user