Migrate email editor templates class to WP Coding Standard

[MAILPOET-6240]
This commit is contained in:
Jan Lysý
2024-10-23 15:46:37 +02:00
committed by Jan Lysý
parent a31857ffee
commit f5e54abecf
3 changed files with 180 additions and 82 deletions

View File

@@ -39,8 +39,8 @@ class Renderer {
public function render( \WP_Post $post, string $subject, string $preHeader, string $language, $metaRobots = '' ): array { public function render( \WP_Post $post, string $subject, string $preHeader, string $language, $metaRobots = '' ): array {
$templateId = 'mailpoet/mailpoet//' . ( get_page_template_slug( $post ) ?: 'email-general' ); $templateId = 'mailpoet/mailpoet//' . ( get_page_template_slug( $post ) ?: 'email-general' );
$template = $this->templates->getBlockTemplate( $templateId ); $template = $this->templates->get_block_template( $templateId );
$theme = $this->templates->getBlockTemplateTheme( $templateId, $template->wp_id ); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps $theme = $this->templates->get_block_template_theme( $templateId, $template->wp_id ); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
// Set the theme for the template. This is merged with base theme.json and core json before rendering. // Set the theme for the template. This is merged with base theme.json and core json before rendering.
self::$theme = new WP_Theme_JSON( $theme, 'default' ); self::$theme = new WP_Theme_JSON( $theme, 'default' );

View File

@@ -76,7 +76,7 @@ class Template_Preview {
*/ */
public function get_email_theme_preview_css( $template ): string { public function get_email_theme_preview_css( $template ): string {
$editor_theme = clone $this->theme_controller->get_theme(); $editor_theme = clone $this->theme_controller->get_theme();
$template_theme = $this->templates->getBlockTemplateTheme( $template['id'], $template['wp_id'] ); $template_theme = $this->templates->get_block_template_theme( $template['id'], $template['wp_id'] );
if ( is_array( $template_theme ) ) { if ( is_array( $template_theme ) ) {
$editor_theme->merge( new WP_Theme_JSON( $template_theme, 'custom' ) ); $editor_theme->merge( new WP_Theme_JSON( $template_theme, 'custom' ) );
} }

View File

@@ -1,126 +1,200 @@
<?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\Templates; namespace MailPoet\EmailEditor\Engine\Templates;
use MailPoet\EmailEditor\Engine\Email_Styles_Schema; use MailPoet\EmailEditor\Engine\Email_Styles_Schema;
use WP_Block_Template; use WP_Block_Template;
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps /**
* Templates class.
*/
class Templates { class Templates {
const MAILPOET_EMAIL_META_THEME_TYPE = 'mailpoet_email_theme'; const MAILPOET_EMAIL_META_THEME_TYPE = 'mailpoet_email_theme';
const MAILPOET_TEMPLATE_EMPTY_THEME = array( 'version' => 2 ); // The version 2 is important to merge themes correctly const MAILPOET_TEMPLATE_EMPTY_THEME = array( 'version' => 2 ); // The version 2 is important to merge themes correctly.
/**
* Provides the utils.
*
* @var Utils $utils
*/
private Utils $utils; private Utils $utils;
private string $pluginSlug = 'mailpoet/mailpoet'; /**
private string $postType = 'mailpoet_email'; * The plugin slug.
private string $templateDirectory; *
* @var string $plugin_slug
*/
private string $plugin_slug = 'mailpoet/mailpoet';
/**
* The post type.
*
* @var string $post_type
*/
private string $post_type = 'mailpoet_email';
/**
* The template directory.
*
* @var string $template_directory
*/
private string $template_directory;
/**
* The templates.
*
* @var array $templates
*/
private array $templates = array(); private array $templates = array();
private array $themeJson = array(); /**
* The theme JSON.
*
* @var array $theme_json
*/
private array $theme_json = array();
/**
* Templates constructor.
*
* @param Utils $utils The utils.
*/
public function __construct( public function __construct(
Utils $utils Utils $utils
) { ) {
$this->utils = $utils; $this->utils = $utils;
$this->templateDirectory = __DIR__ . DIRECTORY_SEPARATOR; $this->template_directory = __DIR__ . DIRECTORY_SEPARATOR;
} }
/**
* Initializes the class.
*/
public function initialize(): void { public function initialize(): void {
add_filter( 'pre_get_block_file_template', array( $this, 'getBlockFileTemplate' ), 10, 3 ); add_filter( 'pre_get_block_file_template', array( $this, 'get_block_file_template' ), 10, 3 );
add_filter( 'get_block_templates', array( $this, 'addBlockTemplates' ), 10, 3 ); add_filter( 'get_block_templates', array( $this, 'add_block_templates' ), 10, 3 );
add_filter( 'theme_templates', array( $this, 'addThemeTemplates' ), 10, 4 ); // Needed when saving post template association add_filter( 'theme_templates', array( $this, 'add_theme_templates' ), 10, 4 ); // Needed when saving post template association.
add_filter( 'get_block_template', array( $this, 'addBlockTemplateDetails' ), 10, 1 ); add_filter( 'get_block_template', array( $this, 'add_block_template_details' ), 10, 1 );
add_filter( 'rest_pre_insert_wp_template', array( $this, 'forcePostContent' ), 9, 1 ); add_filter( 'rest_pre_insert_wp_template', array( $this, 'force_post_content' ), 9, 1 );
$this->initializeTemplates(); $this->initialize_templates();
$this->initializeApi(); $this->initialize_api();
} }
/** /**
* Get a block template by ID. * Get a block template by ID.
*
* @param string $template_id The template ID.
* @return WP_Block_Template|null
*/ */
public function getBlockTemplate( $templateId ) { public function get_block_template( $template_id ) {
$templates = $this->getBlockTemplates(); $templates = $this->get_block_templates();
return $templates[ $templateId ] ?? null; return $templates[ $template_id ] ?? null;
} }
/** /**
* Get a predefined or user defined theme for a block template. * Get a predefined or user defined theme for a block template.
* *
* @param string $templateId * @param string $template_id The template ID.
* @param int|null $templateWpId * @param int|null $template_wp_id The template WP ID.
* @return array * @return array
*/ */
public function getBlockTemplateTheme( $templateId, $templateWpId = null ) { public function get_block_template_theme( $template_id, $template_wp_id = null ) {
// First check if there is a user updated theme saved // First check if there is a user updated theme saved.
$theme = $this->getCustomTemplateTheme( $templateWpId ); $theme = $this->get_custom_template_theme( $template_wp_id );
if ( $theme ) { if ( $theme ) {
return $theme; return $theme;
} }
// If there is no user edited theme, look for default template themes in files. // If there is no user edited theme, look for default template themes in files.
['prefix' => $templatePrefix, 'slug' => $templateSlug] = $this->utils->get_template_id_parts( $templateId ); ['prefix' => $template_prefix, 'slug' => $template_slug] = $this->utils->get_template_id_parts( $template_id );
if ( $this->pluginSlug !== $templatePrefix ) { if ( $this->plugin_slug !== $template_prefix ) {
return self::MAILPOET_TEMPLATE_EMPTY_THEME; return self::MAILPOET_TEMPLATE_EMPTY_THEME;
} }
if ( ! isset( $this->themeJson[ $templateSlug ] ) ) { if ( ! isset( $this->theme_json[ $template_slug ] ) ) {
$jsonFile = $this->templateDirectory . $templateSlug . '.json'; $json_file = $this->template_directory . $template_slug . '.json';
if ( file_exists( $jsonFile ) ) { if ( file_exists( $json_file ) ) {
$this->themeJson[ $templateSlug ] = json_decode( (string) file_get_contents( $jsonFile ), true ); $this->theme_json[ $template_slug ] = json_decode( (string) file_get_contents( $json_file ), true );
} }
} }
return $this->themeJson[ $templateSlug ] ?? self::MAILPOET_TEMPLATE_EMPTY_THEME; return $this->theme_json[ $template_slug ] ?? self::MAILPOET_TEMPLATE_EMPTY_THEME;
} }
public function getBlockFileTemplate( $return, $templateId, $template_type ) { /**
['prefix' => $templatePrefix, 'slug' => $templateSlug] = $this->utils->get_template_id_parts( $templateId ); * Get block template from file.
*
* @param WP_Block_Template $result The result.
* @param string $template_id The template ID.
* @param string $template_type The template type.
* @return WP_Block_Template
*/
public function get_block_file_template( $result, $template_id, $template_type ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
['prefix' => $template_prefix, 'slug' => $template_slug] = $this->utils->get_template_id_parts( $template_id );
if ( $this->pluginSlug !== $templatePrefix ) { if ( $this->plugin_slug !== $template_prefix ) {
return $return; return $result;
} }
$templatePath = $templateSlug . '.html'; $template_path = $template_slug . '.html';
if ( ! is_readable( $this->templateDirectory . $templatePath ) ) { if ( ! is_readable( $this->template_directory . $template_path ) ) {
return $return; return $result;
} }
return $this->getBlockTemplateFromFile( $templatePath ); return $this->get_block_template_from_file( $template_path );
} }
public function addBlockTemplates( $query_result, $query, $template_type ) { /**
* Add block templates to the block templates list.
*
* @param array $query_result The query result.
* @param array $query The query.
* @param string $template_type The template type.
* @return array
*/
public function add_block_templates( $query_result, $query, $template_type ) {
if ( 'wp_template' !== $template_type ) { if ( 'wp_template' !== $template_type ) {
return $query_result; return $query_result;
} }
$post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; $post_type = isset( $query['post_type'] ) ? $query['post_type'] : '';
if ( $post_type && $post_type !== $this->postType ) { if ( $post_type && $post_type !== $this->post_type ) {
return $query_result; return $query_result;
} }
foreach ( $this->getBlockTemplates() as $blockTemplate ) { foreach ( $this->get_block_templates() as $block_template ) {
$fits_slug_query = ! isset( $query['slug__in'] ) || in_array( $blockTemplate->slug, $query['slug__in'], true ); $fits_slug_query = ! isset( $query['slug__in'] ) || in_array( $block_template->slug, $query['slug__in'], true );
$fits_area_query = ! isset( $query['area'] ) || ( property_exists( $blockTemplate, 'area' ) && $blockTemplate->area === $query['area'] ); $fits_area_query = ! isset( $query['area'] ) || ( property_exists( $block_template, 'area' ) && $block_template->area === $query['area'] );
$should_include = $fits_slug_query && $fits_area_query; $should_include = $fits_slug_query && $fits_area_query;
if ( $should_include ) { if ( $should_include ) {
$query_result[] = $blockTemplate; $query_result[] = $block_template;
} }
} }
return $query_result; return $query_result;
} }
public function addThemeTemplates( $templates, $theme, $post, $post_type ) { /**
if ( $post_type && $post_type !== $this->postType ) { * Add theme templates to the theme templates list.
*
* @param array $templates The templates.
* @param string $theme The theme.
* @param \WP_Post $post The post.
* @param string $post_type The post type.
* @return array
*/
public function add_theme_templates( $templates, $theme, $post, $post_type ) {
if ( $post_type && $post_type !== $this->post_type ) {
return $templates; return $templates;
} }
foreach ( $this->getBlockTemplates() as $blockTemplate ) { foreach ( $this->get_block_templates() as $block_template ) {
$templates[ $blockTemplate->slug ] = $blockTemplate; $templates[ $block_template->slug ] = $block_template;
} }
return $templates; return $templates;
} }
@@ -135,9 +209,9 @@ class Templates {
* To test the issue create a new email, revert template changes, save a color change, then save a color change again. * To test the issue create a new email, revert template changes, save a color change, then save a color change again.
* When you refresh if the post is blank, the issue is present. * When you refresh if the post is blank, the issue is present.
* *
* @param \stdClass $changes * @param \stdClass $changes The changes to the post object.
*/ */
public function forcePostContent( $changes ) { public function force_post_content( $changes ) {
if ( empty( $changes->post_content ) && ! empty( $changes->ID ) ) { if ( empty( $changes->post_content ) && ! empty( $changes->ID ) ) {
// Find the existing post object. // Find the existing post object.
$post = get_post( $changes->ID ); $post = get_post( $changes->ID );
@@ -154,7 +228,7 @@ class Templates {
* @param WP_Block_Template $block_template Block template object. * @param WP_Block_Template $block_template Block template object.
* @return WP_Block_Template * @return WP_Block_Template
*/ */
public function addBlockTemplateDetails( $block_template ) { public function add_block_template_details( $block_template ) {
if ( ! $block_template || ! isset( $this->templates[ $block_template->slug ] ) ) { if ( ! $block_template || ! isset( $this->templates[ $block_template->slug ] ) ) {
return $block_template; return $block_template;
} }
@@ -170,7 +244,7 @@ class Templates {
/** /**
* Initialize template details. This is done at runtime because of localisation. * Initialize template details. This is done at runtime because of localisation.
*/ */
private function initializeTemplates(): void { private function initialize_templates(): void {
$this->templates['email-general'] = array( $this->templates['email-general'] = array(
'title' => __( 'General Email', 'mailpoet' ), 'title' => __( 'General Email', 'mailpoet' ),
'description' => __( 'A general template for emails.', 'mailpoet' ), 'description' => __( 'A general template for emails.', 'mailpoet' ),
@@ -181,7 +255,10 @@ class Templates {
); );
} }
private function initializeApi(): void { /**
* Initialize the API.
*/
private function initialize_api(): void {
register_post_meta( register_post_meta(
'wp_template', 'wp_template',
self::MAILPOET_EMAIL_META_THEME_TYPE, self::MAILPOET_EMAIL_META_THEME_TYPE,
@@ -198,8 +275,8 @@ class Templates {
'wp_template', 'wp_template',
self::MAILPOET_EMAIL_META_THEME_TYPE, self::MAILPOET_EMAIL_META_THEME_TYPE,
array( array(
'get_callback' => function ( $object ) { 'get_callback' => function ( $item ) {
return $this->getBlockTemplateTheme( $object['id'], $object['wp_id'] ); return $this->get_block_template_theme( $item['id'], $item['wp_id'] );
}, },
'update_callback' => function ( $value, $template ) { 'update_callback' => function ( $value, $template ) {
return update_post_meta( $template->wp_id, self::MAILPOET_EMAIL_META_THEME_TYPE, $value ); return update_post_meta( $template->wp_id, self::MAILPOET_EMAIL_META_THEME_TYPE, $value );
@@ -211,25 +288,27 @@ class Templates {
/** /**
* Gets block templates indexed by ID. * Gets block templates indexed by ID.
*
* @return WP_Block_Template[]
*/ */
private function getBlockTemplates() { private function get_block_templates() {
$blockTemplates = array_map( $block_templates = array_map(
function ( $templateSlug ) { function ( $template_slug ) {
return $this->getBlockTemplateFromFile( $templateSlug . '.html' ); return $this->get_block_template_from_file( $template_slug . '.html' );
}, },
array_keys( $this->templates ) array_keys( $this->templates )
); );
$customTemplates = $this->getCustomTemplates(); // From the DB. $custom_templates = $this->get_custom_templates(); // From the DB.
$customTemplateIds = wp_list_pluck( $customTemplates, 'id' ); $custom_template_ids = wp_list_pluck( $custom_templates, 'id' );
// Combine to remove duplicates if a custom template has the same ID as a file template. // Combine to remove duplicates if a custom template has the same ID as a file template.
return array_column( return array_column(
array_merge( array_merge(
$customTemplates, $custom_templates,
array_filter( array_filter(
$blockTemplates, $block_templates,
function ( $blockTemplate ) use ( $customTemplateIds ) { function ( $block_template ) use ( $custom_template_ids ) {
return ! in_array( $blockTemplate->id, $customTemplateIds, true ); return ! in_array( $block_template->id, $custom_template_ids, true );
} }
), ),
), ),
@@ -238,25 +317,38 @@ class Templates {
); );
} }
private function getBlockTemplateFromFile( string $template ) { /**
$template_slug = $this->utils->get_block_template_slug_from_path( $template ); * Get a block template from a file.
$templateObject = (object) array( *
* @param string $template The template file.
* @return WP_Block_Template
*/
private function get_block_template_from_file( string $template ) {
$template_slug = $this->utils->get_block_template_slug_from_path( $template );
$template_object = (object) array(
'slug' => $template_slug, 'slug' => $template_slug,
'id' => $this->pluginSlug . '//' . $template_slug, 'id' => $this->plugin_slug . '//' . $template_slug,
'title' => $this->templates[ $template_slug ]['title'] ?? '', 'title' => $this->templates[ $template_slug ]['title'] ?? '',
'description' => $this->templates[ $template_slug ]['description'] ?? '', 'description' => $this->templates[ $template_slug ]['description'] ?? '',
'path' => $this->templateDirectory . $template, 'path' => $this->template_directory . $template,
'type' => 'wp_template', 'type' => 'wp_template',
'theme' => $this->pluginSlug, 'theme' => $this->plugin_slug,
'source' => 'plugin', 'source' => 'plugin',
'post_types' => array( 'post_types' => array(
$this->postType, $this->post_type,
), ),
); );
return $this->utils->build_block_template_from_file( $templateObject ); return $this->utils->build_block_template_from_file( $template_object );
} }
private function getCustomTemplates( $slugs = array(), $template_type = 'wp_template' ) { /**
* Get custom templates from the database.
*
* @param array $slugs Array of template slugs to get.
* @param string $template_type The template type to get.
* @return array
*/
private function get_custom_templates( $slugs = array(), $template_type = 'wp_template' ): array {
$check_query_args = array( $check_query_args = array(
'post_type' => $template_type, 'post_type' => $template_type,
'posts_per_page' => -1, 'posts_per_page' => -1,
@@ -265,7 +357,7 @@ class Templates {
array( array(
'taxonomy' => 'wp_theme', 'taxonomy' => 'wp_theme',
'field' => 'name', 'field' => 'name',
'terms' => array( $this->pluginSlug, get_stylesheet() ), 'terms' => array( $this->plugin_slug, get_stylesheet() ),
), ),
), ),
); );
@@ -285,11 +377,17 @@ class Templates {
); );
} }
private function getCustomTemplateTheme( $templateWpId ) { /**
if ( ! $templateWpId ) { * Get the custom theme for a template.
*
* @param int|null $template_wp_id The template ID.
* @return array|null
*/
private function get_custom_template_theme( ?int $template_wp_id ): ?array {
if ( ! $template_wp_id ) {
return null; return null;
} }
$theme = get_post_meta( $templateWpId, self::MAILPOET_EMAIL_META_THEME_TYPE, true ); $theme = get_post_meta( $template_wp_id, self::MAILPOET_EMAIL_META_THEME_TYPE, true );
if ( is_array( $theme ) && isset( $theme['styles'] ) ) { if ( is_array( $theme ) && isset( $theme['styles'] ) ) {
return $theme; return $theme;
} }