Migrate email editor settings-controller to WP Coding Standard

[MAILPOET-6240]
This commit is contained in:
Jan Lysý
2024-10-16 18:16:33 +02:00
committed by Jan Lysý
parent fba5482cd2
commit c83ec3c8d7
13 changed files with 146 additions and 75 deletions

View File

@@ -9,9 +9,9 @@ use MailPoet\EmailEditor\Engine\Settings_Controller;
*/ */
class Flex_Layout_Renderer { class Flex_Layout_Renderer {
public function renderInnerBlocksInLayout( array $parsedBlock, Settings_Controller $settingsController ): string { public function renderInnerBlocksInLayout( array $parsedBlock, Settings_Controller $settingsController ): string {
$themeStyles = $settingsController->getEmailStyles(); $themeStyles = $settingsController->get_email_styles();
$flexGap = $themeStyles['spacing']['blockGap'] ?? '0px'; $flexGap = $themeStyles['spacing']['blockGap'] ?? '0px';
$flexGapNumber = $settingsController->parseNumberFromStringWithPixels( $flexGap ); $flexGapNumber = $settingsController->parse_number_from_string_with_pixels( $flexGap );
$marginTop = $parsedBlock['email_attrs']['margin-top'] ?? '0px'; $marginTop = $parsedBlock['email_attrs']['margin-top'] ?? '0px';
$justify = $parsedBlock['attrs']['layout']['justifyContent'] ?? 'left'; $justify = $parsedBlock['attrs']['layout']['justifyContent'] ?? 'left';
@@ -52,7 +52,7 @@ class Flex_Layout_Renderer {
} }
$blocksCount = count( $parsedBlock['innerBlocks'] ); $blocksCount = count( $parsedBlock['innerBlocks'] );
$totalUsedWidth = 0; // Total width assuming items without set width would consume proportional width $totalUsedWidth = 0; // Total width assuming items without set width would consume proportional width
$parentWidth = $settingsController->parseNumberFromStringWithPixels( $parsedBlock['email_attrs']['width'] ); $parentWidth = $settingsController->parse_number_from_string_with_pixels( $parsedBlock['email_attrs']['width'] );
$innerBlocks = $parsedBlock['innerBlocks'] ?? array(); $innerBlocks = $parsedBlock['innerBlocks'] ?? array();
foreach ( $innerBlocks as $key => $block ) { foreach ( $innerBlocks as $key => $block ) {
@@ -75,7 +75,7 @@ class Flex_Layout_Renderer {
foreach ( $innerBlocks as $key => $block ) { foreach ( $innerBlocks as $key => $block ) {
$proportionalSpaceOverflow = $parentWidth / $totalUsedWidth; $proportionalSpaceOverflow = $parentWidth / $totalUsedWidth;
$blockWidth = $block['email_attrs']['layout_width'] ? $settingsController->parseNumberFromStringWithPixels( $block['email_attrs']['layout_width'] ) : 0; $blockWidth = $block['email_attrs']['layout_width'] ? $settingsController->parse_number_from_string_with_pixels( $block['email_attrs']['layout_width'] ) : 0;
$blockProportionalWidth = $blockWidth * $proportionalSpaceOverflow; $blockProportionalWidth = $blockWidth * $proportionalSpaceOverflow;
$blockProportionalPercentage = ( $blockProportionalWidth / $parentWidth ) * 100; $blockProportionalPercentage = ( $blockProportionalWidth / $parentWidth ) * 100;
$innerBlocks[ $key ]['email_attrs']['layout_width'] = $blockWidth ? $this->getWidthWithoutGap( $blockProportionalWidth, $flexGap, $blockProportionalPercentage ) . 'px' : null; $innerBlocks[ $key ]['email_attrs']['layout_width'] = $blockWidth ? $this->getWidthWithoutGap( $blockProportionalWidth, $flexGap, $blockProportionalPercentage ) . 'px' : null;

View File

@@ -57,7 +57,7 @@ class Typography_Preprocessor implements Preprocessor {
// In case the fontSize is set via a slug (small, medium, large, etc.) we translate it to a number // In case the fontSize is set via a slug (small, medium, large, etc.) we translate it to a number
// The font size slug is set in $block['attrs']['fontSize'] and value in $block['attrs']['style']['typography']['fontSize'] // The font size slug is set in $block['attrs']['fontSize'] and value in $block['attrs']['style']['typography']['fontSize']
if ( isset( $block['attrs']['fontSize'] ) ) { if ( isset( $block['attrs']['fontSize'] ) ) {
$block['attrs']['style']['typography']['fontSize'] = $this->settingsController->translateSlugToFontSize( $block['attrs']['fontSize'] ); $block['attrs']['style']['typography']['fontSize'] = $this->settingsController->translate_slug_to_font_size( $block['attrs']['fontSize'] );
} }
// Pass font size to email_attrs // Pass font size to email_attrs
if ( isset( $block['attrs']['style']['typography']['fontSize'] ) ) { if ( isset( $block['attrs']['style']['typography']['fontSize'] ) ) {
@@ -75,7 +75,7 @@ class Typography_Preprocessor implements Preprocessor {
} }
private function setDefaultsFromTheme( array $block ): array { private function setDefaultsFromTheme( array $block ): array {
$themeData = $this->settingsController->getTheme()->get_data(); $themeData = $this->settingsController->get_theme()->get_data();
if ( ! ( $block['email_attrs']['color'] ?? '' ) ) { if ( ! ( $block['email_attrs']['color'] ?? '' ) ) {
$block['email_attrs']['color'] = $themeData['styles']['color']['text'] ?? null; $block['email_attrs']['color'] = $themeData['styles']['color']['text'] ?? null;
} }

View File

@@ -92,7 +92,7 @@ class Content_Renderer {
$styles .= (string) file_get_contents( __DIR__ . '/../../content-shared.css' ); $styles .= (string) file_get_contents( __DIR__ . '/../../content-shared.css' );
// Apply default contentWidth to constrained blocks. // Apply default contentWidth to constrained blocks.
$layout = $this->themeController->getLayoutSettings(); $layout = $this->themeController->get_layout_settings();
$styles .= sprintf( $styles .= sprintf(
' '
.is-layout-constrained > *:not(.alignleft):not(.alignright):not(.alignfull) { .is-layout-constrained > *:not(.alignleft):not(.alignright):not(.alignfull) {

View File

@@ -1,7 +1,16 @@
<?php declare(strict_types = 1); <?php
/**
* This file is part of the MailPoet plugin.
*
* @package MailPoet\EmailEditor
*/
declare(strict_types = 1);
namespace MailPoet\EmailEditor\Engine; namespace MailPoet\EmailEditor\Engine;
/**
* Class managing the settings for the email editor.
*/
class Settings_Controller { class Settings_Controller {
const ALLOWED_BLOCK_TYPES = array( const ALLOWED_BLOCK_TYPES = array(
@@ -22,60 +31,88 @@ class Settings_Controller {
'enableCustomUnits' => array( 'px', '%' ), 'enableCustomUnits' => array( 'px', '%' ),
); );
private Theme_Controller $themeController; /**
* Theme controller.
private array $iframeAssets = array(); *
* @var Theme_Controller
*/
private Theme_Controller $theme_controller;
/** /**
* @param Theme_Controller $themeController * Assets for iframe editor (component styles, scripts, etc.)
*
* @var array
*/
private array $iframe_assets = array();
/**
* Class constructor.
*
* @param Theme_Controller $theme_controller Theme controller.
*/ */
public function __construct( public function __construct(
Theme_Controller $themeController Theme_Controller $theme_controller
) { ) {
$this->themeController = $themeController; $this->theme_controller = $theme_controller;
} }
public function init() { /**
// We need to initialize these assets early because they are read from global variables $wp_styles and $wp_scripts * Method to initialize the settings controller.
// and in later WordPress page load pages they contain stuff we don't want (e.g. html for admin login popup) *
// in the post editor this is called directly in post.php * @return void
$this->iframeAssets = _wp_get_iframed_editor_assets(); */
public function init(): void {
/*
* We need to initialize these assets early because they are read from global variables $wp_styles and $wp_scripts
* and in later WordPress page load pages they contain stuff we don't want (e.g. html for admin login popup)
* in the post editor this is called directly in post.php.
*/
$this->iframe_assets = _wp_get_iframed_editor_assets();
} }
/**
* Get the settings for the email editor.
*
* @return array
*/
public function get_settings(): array { public function get_settings(): array {
$coreDefaultSettings = \get_default_block_editor_settings(); $core_default_settings = \get_default_block_editor_settings();
$themeSettings = $this->themeController->get_settings(); $theme_settings = $this->theme_controller->get_settings();
$settings = array_merge( $coreDefaultSettings, self::DEFAULT_SETTINGS ); $settings = array_merge( $core_default_settings, self::DEFAULT_SETTINGS );
$settings['allowedBlockTypes'] = self::ALLOWED_BLOCK_TYPES; $settings['allowedBlockTypes'] = self::ALLOWED_BLOCK_TYPES;
// Assets for iframe editor (component styles, scripts, etc.) // Assets for iframe editor (component styles, scripts, etc.).
$settings['__unstableResolvedAssets'] = $this->iframeAssets; $settings['__unstableResolvedAssets'] = $this->iframe_assets;
$editorContentStyles = file_get_contents( __DIR__ . '/content-editor.css' ); $editor_content_styles = file_get_contents( __DIR__ . '/content-editor.css' );
$sharesContentStyles = file_get_contents( __DIR__ . '/content-shared.css' ); $shares_content_styles = file_get_contents( __DIR__ . '/content-shared.css' );
$settings['styles'] = array( $settings['styles'] = array(
array( 'css' => $editorContentStyles ), array( 'css' => $editor_content_styles ),
array( 'css' => $sharesContentStyles ), array( 'css' => $shares_content_styles ),
); );
$settings['__experimentalFeatures'] = $themeSettings; $settings['__experimentalFeatures'] = $theme_settings;
// Controls which alignment options are available for blocks // Controls which alignment options are available for blocks.
$settings['supportsLayout'] = true; // Allow using default layouts $settings['supportsLayout'] = true; // Allow using default layouts.
$settings['__unstableIsBlockBasedTheme'] = true; // For default setting this to true disables wide and full alignments $settings['__unstableIsBlockBasedTheme'] = true; // For default setting this to true disables wide and full alignments.
return $settings; return $settings;
} }
/** /**
* Returns the layout settings for the email editor.
*
* @return array{contentSize: string, wideSize: string} * @return array{contentSize: string, wideSize: string}
*/ */
public function getLayout(): array { public function get_layout(): array {
$layoutSettings = $this->themeController->get_layout_settings(); $layout_settings = $this->theme_controller->get_layout_settings();
return array( return array(
'contentSize' => $layoutSettings['contentSize'], 'contentSize' => $layout_settings['contentSize'],
'wideSize' => $layoutSettings['wideSize'], 'wideSize' => $layout_settings['wideSize'],
); );
} }
/** /**
* Get the email styles.
*
* @return array{ * @return array{
* spacing: array{ * spacing: array{
* blockGap: string, * blockGap: string,
@@ -89,45 +126,79 @@ class Settings_Controller {
* } * }
* } * }
*/ */
public function getEmailStyles(): array { public function get_email_styles(): array {
$theme = $this->getTheme(); $theme = $this->get_theme();
return $theme->get_data()['styles']; return $theme->get_data()['styles'];
} }
public function getLayoutWidthWithoutPadding(): string { /**
$styles = $this->getEmailStyles(); * Returns the width of the layout without padding.
$layout = $this->getLayout(); *
$width = $this->parseNumberFromStringWithPixels( $layout['contentSize'] ); * @return string
$width -= $this->parseNumberFromStringWithPixels( $styles['spacing']['padding']['left'] ); */
$width -= $this->parseNumberFromStringWithPixels( $styles['spacing']['padding']['right'] ); public function get_layout_width_without_padding(): string {
$styles = $this->get_email_styles();
$layout = $this->get_layout();
$width = $this->parse_number_from_string_with_pixels( $layout['contentSize'] );
$width -= $this->parse_number_from_string_with_pixels( $styles['spacing']['padding']['left'] );
$width -= $this->parse_number_from_string_with_pixels( $styles['spacing']['padding']['right'] );
return "{$width}px"; return "{$width}px";
} }
public function parseStylesToArray( string $styles ): array { /**
$styles = explode( ';', $styles ); * Parse styles string to array.
$parsedStyles = array(); *
* @param string $styles Styles string.
* @return array
*/
public function parse_styles_to_array( string $styles ): array {
$styles = explode( ';', $styles );
$parsed_styles = array();
foreach ( $styles as $style ) { foreach ( $styles as $style ) {
$style = explode( ':', $style ); $style = explode( ':', $style );
if ( count( $style ) === 2 ) { if ( count( $style ) === 2 ) {
$parsedStyles[ trim( $style[0] ) ] = trim( $style[1] ); $parsed_styles[ trim( $style[0] ) ] = trim( $style[1] );
} }
} }
return $parsedStyles; return $parsed_styles;
} }
public function parseNumberFromStringWithPixels( string $string ): float { /**
return (float) str_replace( 'px', '', $string ); * Returns float number parsed from string with pixels.
*
* @param string $value Value with pixels.
* @return float
*/
public function parse_number_from_string_with_pixels( string $value ): float {
return (float) str_replace( 'px', '', $value );
} }
public function getTheme(): \WP_Theme_JSON { /**
return $this->themeController->get_theme(); * Returns the theme.
*
* @return \WP_Theme_JSON
*/
public function get_theme(): \WP_Theme_JSON {
return $this->theme_controller->get_theme();
} }
public function translateSlugToFontSize( string $fontSize ): string { /**
return $this->themeController->translate_slug_to_font_size( $fontSize ); * Translate slug to font size.
*
* @param string $font_size Font size slug.
* @return string
*/
public function translate_slug_to_font_size( string $font_size ): string {
return $this->theme_controller->translate_slug_to_font_size( $font_size );
} }
public function translateSlugToColor( string $colorSlug ): string { /**
return $this->themeController->translate_slug_to_color( $colorSlug ); * Translate slug to color.
*
* @param string $color_slug Color slug.
* @return string
*/
public function translate_slug_to_color( string $color_slug ): string {
return $this->theme_controller->translate_slug_to_color( $color_slug );
} }
} }

View File

@@ -77,8 +77,8 @@ class Button extends Abstract_Block_Renderer {
array( array(
'color' => array_filter( 'color' => array_filter(
array( array(
'background' => $blockAttributes['backgroundColor'] ? $settingsController->translateSlugToColor( $blockAttributes['backgroundColor'] ) : null, 'background' => $blockAttributes['backgroundColor'] ? $settingsController->translate_slug_to_color( $blockAttributes['backgroundColor'] ) : null,
'text' => $blockAttributes['textColor'] ? $settingsController->translateSlugToColor( $blockAttributes['textColor'] ) : null, 'text' => $blockAttributes['textColor'] ? $settingsController->translate_slug_to_color( $blockAttributes['textColor'] ) : null,
) )
), ),
), ),

View File

@@ -37,7 +37,7 @@ class Column extends Abstract_Block_Renderer {
$parsedBlock['attrs'] ?? array(), $parsedBlock['attrs'] ?? array(),
array( array(
'verticalAlignment' => 'stretch', 'verticalAlignment' => 'stretch',
'width' => $settingsController->getLayoutWidthWithoutPadding(), 'width' => $settingsController->get_layout_width_without_padding(),
'style' => array(), 'style' => array(),
) )
); );

View File

@@ -30,7 +30,7 @@ class Columns extends Abstract_Block_Renderer {
$parsedBlock['attrs'] ?? array(), $parsedBlock['attrs'] ?? array(),
array( array(
'align' => null, 'align' => null,
'width' => $settingsController->getLayoutWidthWithoutPadding(), 'width' => $settingsController->get_layout_width_without_padding(),
'style' => array(), 'style' => array(),
) )
); );

View File

@@ -41,9 +41,9 @@ class Group extends Abstract_Block_Renderer {
array( array(
'color' => array_filter( 'color' => array_filter(
array( array(
'background' => $blockAttributes['backgroundColor'] ? $settingsController->translateSlugToColor( $blockAttributes['backgroundColor'] ) : null, 'background' => $blockAttributes['backgroundColor'] ? $settingsController->translate_slug_to_color( $blockAttributes['backgroundColor'] ) : null,
'text' => $blockAttributes['textColor'] ? $settingsController->translateSlugToColor( $blockAttributes['textColor'] ) : null, 'text' => $blockAttributes['textColor'] ? $settingsController->translate_slug_to_color( $blockAttributes['textColor'] ) : null,
'border' => $blockAttributes['borderColor'] ? $settingsController->translateSlugToColor( $blockAttributes['borderColor'] ) : null, 'border' => $blockAttributes['borderColor'] ? $settingsController->translate_slug_to_color( $blockAttributes['borderColor'] ) : null,
) )
), ),
'background' => $blockAttributes['style']['background'] ?? array(), 'background' => $blockAttributes['style']['background'] ?? array(),

View File

@@ -114,15 +114,15 @@ class Image extends Abstract_Block_Renderer {
if ( $html->next_tag( array( 'tag_name' => 'img' ) ) ) { if ( $html->next_tag( array( 'tag_name' => 'img' ) ) ) {
// Getting height from styles and if it's set, we set the height attribute // Getting height from styles and if it's set, we set the height attribute
$styles = $html->get_attribute( 'style' ) ?? ''; $styles = $html->get_attribute( 'style' ) ?? '';
$styles = $settingsController->parseStylesToArray( $styles ); $styles = $settingsController->parse_styles_to_array( $styles );
$height = $styles['height'] ?? null; $height = $styles['height'] ?? null;
if ( $height && $height !== 'auto' && is_numeric( $settingsController->parseNumberFromStringWithPixels( $height ) ) ) { if ( $height && $height !== 'auto' && is_numeric( $settingsController->parse_number_from_string_with_pixels( $height ) ) ) {
$height = $settingsController->parseNumberFromStringWithPixels( $height ); $height = $settingsController->parse_number_from_string_with_pixels( $height );
$html->set_attribute( 'height', esc_attr( $height ) ); $html->set_attribute( 'height', esc_attr( $height ) );
} }
if ( isset( $parsedBlock['attrs']['width'] ) ) { if ( isset( $parsedBlock['attrs']['width'] ) ) {
$width = $settingsController->parseNumberFromStringWithPixels( $parsedBlock['attrs']['width'] ); $width = $settingsController->parse_number_from_string_with_pixels( $parsedBlock['attrs']['width'] );
$html->set_attribute( 'width', esc_attr( $width ) ); $html->set_attribute( 'width', esc_attr( $width ) );
} }
$blockContent = $html->get_updated_html(); $blockContent = $html->get_updated_html();
@@ -136,7 +136,7 @@ class Image extends Abstract_Block_Renderer {
* We try to use font-size passed down from the parent element $parsedBlock['email_attrs']['font-size'], but if it's not set, we use the default font-size from the email theme. * We try to use font-size passed down from the parent element $parsedBlock['email_attrs']['font-size'], but if it's not set, we use the default font-size from the email theme.
*/ */
private function getCaptionStyles( Settings_Controller $settingsController, array $parsedBlock ): string { private function getCaptionStyles( Settings_Controller $settingsController, array $parsedBlock ): string {
$themeData = $settingsController->getTheme()->get_data(); $themeData = $settingsController->get_theme()->get_data();
$styles = array( $styles = array(
'text-align' => isset( $parsedBlock['attrs']['align'] ) ? 'center' : 'left', 'text-align' => isset( $parsedBlock['attrs']['align'] ) ? 'center' : 'left',

View File

@@ -11,14 +11,14 @@ class List_Block extends Abstract_Block_Renderer {
$tagName = ( $parsedBlock['attrs']['ordered'] ?? false ) ? 'ol' : 'ul'; $tagName = ( $parsedBlock['attrs']['ordered'] ?? false ) ? 'ol' : 'ul';
if ( $html->next_tag( array( 'tag_name' => $tagName ) ) ) { if ( $html->next_tag( array( 'tag_name' => $tagName ) ) ) {
$styles = $html->get_attribute( 'style' ) ?? ''; $styles = $html->get_attribute( 'style' ) ?? '';
$styles = $settingsController->parseStylesToArray( $styles ); $styles = $settingsController->parse_styles_to_array( $styles );
// Font size // Font size
if ( isset( $parsedBlock['email_attrs']['font-size'] ) ) { if ( isset( $parsedBlock['email_attrs']['font-size'] ) ) {
$styles['font-size'] = $parsedBlock['email_attrs']['font-size']; $styles['font-size'] = $parsedBlock['email_attrs']['font-size'];
} else { } else {
// Use font-size from email theme when those properties are not set // Use font-size from email theme when those properties are not set
$themeData = $settingsController->getTheme()->get_data(); $themeData = $settingsController->get_theme()->get_data();
$styles['font-size'] = $themeData['styles']['typography']['fontSize']; $styles['font-size'] = $themeData['styles']['typography']['fontSize'];
} }

View File

@@ -36,7 +36,7 @@ class Renderer_Test extends \MailPoetTest {
'styles' => $styles, 'styles' => $styles,
]); ]);
$settingsControllerMock = $this->createMock(Settings_Controller::class); $settingsControllerMock = $this->createMock(Settings_Controller::class);
$settingsControllerMock->method('getEmailStyles')->willReturn($styles); $settingsControllerMock->method('get_email_styles')->willReturn($styles);
$themeControllerMock = $this->createMock(Theme_Controller::class); $themeControllerMock = $this->createMock(Theme_Controller::class);
$themeControllerMock->method('get_theme')->willReturn($themeJsonMock); $themeControllerMock->method('get_theme')->willReturn($themeJsonMock);
$themeControllerMock->method('get_styles')->willReturn($styles); $themeControllerMock->method('get_styles')->willReturn($styles);

View File

@@ -47,9 +47,9 @@ class Typography_Preprocessor_Test extends \MailPoetUnitTest {
], ],
], ],
]); ]);
$settingsMock->method('getTheme')->willReturn($themeMock); $settingsMock->method('get_theme')->willReturn($themeMock);
// This slug translate mock expect slugs in format slug-10px and will return 10px // This slug translate mock expect slugs in format slug-10px and will return 10px
$settingsMock->method('translateSlugToFontSize')->willReturnCallback(function($slug) { $settingsMock->method('translate_slug_to_font_size')->willReturnCallback(function($slug) {
return str_replace('slug-', '', $slug); return str_replace('slug-', '', $slug);
}); });
$this->preprocessor = new Typography_Preprocessor($settingsMock); $this->preprocessor = new Typography_Preprocessor($settingsMock);

View File

@@ -22,7 +22,7 @@ class Settings_Controller_Test extends \MailPoetUnitTest {
"wideSize" => null, "wideSize" => null,
]); ]);
$settingsController = new Settings_Controller($themeController); $settingsController = new Settings_Controller($themeController);
$layoutWidth = $settingsController->getLayoutWidthWithoutPadding(); $layoutWidth = $settingsController->get_layout_width_without_padding();
// default width is 660px and if we subtract padding from left and right we must get the correct value // default width is 660px and if we subtract padding from left and right we must get the correct value
$expectedWidth = 660 - 10 * 2; $expectedWidth = 660 - 10 * 2;
$this->assertEquals($expectedWidth . 'px', $layoutWidth); $this->assertEquals($expectedWidth . 'px', $layoutWidth);