OwlCyberSecurity - MANAGER
Edit File: class-email-editor.php
<?php /** * This file is part of the MailPoet Email Editor package. * * @package MailPoet\EmailEditor */ declare(strict_types = 1); namespace MailPoet\EmailEditor\Engine; use MailPoet\EmailEditor\Engine\Patterns\Patterns; use MailPoet\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry; use MailPoet\EmailEditor\Engine\Templates\Templates; use WP_Post; use WP_Theme_JSON; /** * Email editor class. * * @phpstan-type EmailPostType array{name: string, args: array, meta: array{key: string, args: array}[]} * See register_post_type for details about EmailPostType args. */ class Email_Editor { public const MAILPOET_EMAIL_META_THEME_TYPE = 'mailpoet_email_theme'; /** * Property for the email API controller. * * @var Email_Api_Controller Email API controller. */ private Email_Api_Controller $email_api_controller; /** * Property for the templates. * * @var Templates Templates. */ private Templates $templates; /** * Property for the patterns. * * @var Patterns Patterns. */ private Patterns $patterns; /** * Property for the send preview email controller. * * @var Send_Preview_Email Send Preview controller. */ private Send_Preview_Email $send_preview_email; /** * Property for Personalization_Tags_Controller that allows initializing personalization tags. * * @var Personalization_Tags_Registry Personalization tags registry. */ private Personalization_Tags_Registry $personalization_tags_registry; /** * Constructor. * * @param Email_Api_Controller $email_api_controller Email API controller. * @param Templates $templates Templates. * @param Patterns $patterns Patterns. * @param Send_Preview_Email $send_preview_email Preview email controller. * @param Personalization_Tags_Registry $personalization_tags_controller Personalization tags registry that allows initializing personalization tags. */ public function __construct( Email_Api_Controller $email_api_controller, Templates $templates, Patterns $patterns, Send_Preview_Email $send_preview_email, Personalization_Tags_Registry $personalization_tags_controller ) { $this->email_api_controller = $email_api_controller; $this->templates = $templates; $this->patterns = $patterns; $this->send_preview_email = $send_preview_email; $this->personalization_tags_registry = $personalization_tags_controller; } /** * Initialize the email editor. * * @return void */ public function initialize(): void { do_action( 'mailpoet_email_editor_initialized' ); add_filter( 'mailpoet_email_editor_rendering_theme_styles', array( $this, 'extend_email_theme_styles' ), 10, 2 ); $this->register_block_patterns(); $this->register_email_post_types(); $this->register_block_templates(); $this->register_email_post_sent_status(); $this->register_personalization_tags(); $is_editor_page = apply_filters( 'mailpoet_is_email_editor_page', false ); if ( $is_editor_page ) { $this->extend_email_post_api(); } add_action( 'rest_api_init', array( $this, 'register_email_editor_api_routes' ) ); add_filter( 'mailpoet_email_editor_send_preview_email', array( $this->send_preview_email, 'send_preview_email' ), 11, 1 ); // allow for other filter methods to take precedent. add_filter( 'single_template', array( $this, 'load_email_preview_template' ) ); } /** * Register block templates. * * @return void */ private function register_block_templates(): void { // Since we cannot currently disable blocks in the editor for specific templates, disable templates when viewing site editor. @see https://github.com/WordPress/gutenberg/issues/41062. if ( strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ?? '' ) ), 'site-editor.php' ) === false ) { $post_types = array_column( $this->get_post_types(), 'name' ); $this->templates->initialize( $post_types ); } } /** * Register block patterns. * * @return void */ private function register_block_patterns(): void { $this->patterns->initialize(); } /** * Register all custom post types that should be edited via the email editor * The post types are added via mailpoet_email_editor_post_types filter. * * @return void */ private function register_email_post_types(): void { foreach ( $this->get_post_types() as $post_type ) { register_post_type( $post_type['name'], array_merge( $this->get_default_email_post_args(), $post_type['args'] ) ); } } /** * Register all personalization tags registered via * the mailpoet_email_editor_register_personalization_tags filter. * * @return void */ private function register_personalization_tags(): void { $this->personalization_tags_registry->initialize(); } /** * Returns the email post types. * * @return array * @phpstan-return EmailPostType[] */ private function get_post_types(): array { $post_types = array(); return apply_filters( 'mailpoet_email_editor_post_types', $post_types ); } /** * Returns the default arguments for email post types. * * @return array */ private function get_default_email_post_args(): array { return array( 'public' => false, 'hierarchical' => false, 'show_ui' => true, 'show_in_menu' => false, 'show_in_nav_menus' => false, 'supports' => array( 'editor', 'title', 'custom-fields' ), // 'custom-fields' is required for loading meta fields via API. 'has_archive' => true, 'show_in_rest' => true, // Important to enable Gutenberg editor. 'default_rendering_mode' => 'template-locked', 'publicly_queryable' => true, // required by the preview in new tab feature. ); } /** * Register the 'sent' post status for emails. * * @return void */ private function register_email_post_sent_status(): void { $default_args = array( 'public' => false, 'exclude_from_search' => true, 'internal' => true, // for now, we hide it, if we use the status in the listings we may flip this and following values. 'show_in_admin_all_list' => false, 'show_in_admin_status_list' => false, 'private' => true, // required by the preview in new tab feature for sent post (newsletter). Posts are only visible to site admins and editors. ); $args = apply_filters( 'mailpoet_email_editor_post_sent_status_args', $default_args ); register_post_status( 'sent', $args ); } /** * Extends the email post types with email specific data. * * @return void */ public function extend_email_post_api() { $email_post_types = array_column( $this->get_post_types(), 'name' ); register_rest_field( $email_post_types, 'email_data', array( 'get_callback' => array( $this->email_api_controller, 'get_email_data' ), 'update_callback' => array( $this->email_api_controller, 'save_email_data' ), 'schema' => $this->email_api_controller->get_email_data_schema(), ) ); } /** * Registers the API route endpoint for the email editor * * @return void */ public function register_email_editor_api_routes() { register_rest_route( 'mailpoet-email-editor/v1', '/send_preview_email', array( 'methods' => 'POST', 'callback' => array( $this->email_api_controller, 'send_preview_email_data' ), 'permission_callback' => function () { return current_user_can( 'edit_posts' ); }, ) ); register_rest_route( 'mailpoet-email-editor/v1', '/get_personalization_tags', array( 'methods' => 'GET', 'callback' => array( $this->email_api_controller, 'get_personalization_tags' ), 'permission_callback' => function () { return current_user_can( 'edit_posts' ); }, ) ); } /** * Extends the email theme styles with the email specific styles. * * @param WP_Theme_JSON $theme Email theme styles. * @param WP_Post $post Email post object. * @return WP_Theme_JSON */ public function extend_email_theme_styles( WP_Theme_JSON $theme, WP_Post $post ): WP_Theme_JSON { $email_theme = get_post_meta( $post->ID, self::MAILPOET_EMAIL_META_THEME_TYPE, true ); if ( $email_theme && is_array( $email_theme ) ) { $theme->merge( new WP_Theme_JSON( $email_theme ) ); } return $theme; } /** * Get the current post object * * @return array|mixed|WP_Post|null */ public function get_current_post() { if ( isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $current_post = get_post( intval( $_GET['post'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- data valid } else { $current_post = $GLOBALS['post']; } return $current_post; } /** * Use a custom page template for the email editor frontend rendering. * * @param string $template post template. * @return string */ public function load_email_preview_template( $template ) { $post = $this->get_current_post(); if ( ! $post instanceof \WP_Post ) { return $template; } $current_post_type = $post->post_type; $email_post_types = array_column( $this->get_post_types(), 'name' ); if ( ! in_array( $current_post_type, $email_post_types, true ) ) { return $template; } add_filter( 'mailpoet_email_editor_preview_post_template_html', function () use ( $post ) { // Generate HTML content for email editor post. return $this->send_preview_email->render_html( $post ); } ); return __DIR__ . '/Templates/single-email-post-template.php'; } }