PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.36.0
MailPoet – Newsletters, Email Marketing, and Automation v5.36.0
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor / woocommerce / email-editor / src / Engine / class-email-editor.php
mailpoet / vendor / woocommerce / email-editor / src / Engine Last commit date
Logger 11 months ago Patterns 11 months ago PersonalizationTags 3 days ago Renderer 3 days ago Templates 4 months ago class-assets-manager.php 5 months ago class-dependency-check.php 11 months ago class-email-api-controller.php 6 months ago class-email-editor.php 3 days ago class-email-styles-schema.php 11 months ago class-personalizer.php 3 days ago class-send-preview-email.php 5 months ago class-settings-controller.php 3 months ago class-site-style-sync-controller.php 4 months ago class-theme-controller.php 3 months ago class-user-theme.php 11 months ago content-editor.css 2 weeks ago content-shared.css 11 months ago index.php 11 months ago theme.json 3 months ago
class-email-editor.php
243 lines
1 <?php
2 declare(strict_types = 1);
3 namespace Automattic\WooCommerce\EmailEditor\Engine;
4 if (!defined('ABSPATH')) exit;
5 use Automattic\WooCommerce\EmailEditor\Engine\Patterns\Patterns;
6 use Automattic\WooCommerce\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry;
7 use Automattic\WooCommerce\EmailEditor\Engine\Templates\Templates;
8 use Automattic\WooCommerce\EmailEditor\Engine\Logger\Email_Editor_Logger;
9 use WP_Post;
10 use WP_REST_Request;
11 use WP_Theme_JSON;
12 class Email_Editor {
13 public const WOOCOMMERCE_EMAIL_META_THEME_TYPE = 'woocommerce_email_theme';
14 private Email_Api_Controller $email_api_controller;
15 private Templates $templates;
16 private Patterns $patterns;
17 private Send_Preview_Email $send_preview_email;
18 private Personalization_Tags_Registry $personalization_tags_registry;
19 private Email_Editor_Logger $logger;
20 private Assets_Manager $assets_manager;
21 public function __construct(
22 Email_Api_Controller $email_api_controller,
23 Templates $templates,
24 Patterns $patterns,
25 Send_Preview_Email $send_preview_email,
26 Personalization_Tags_Registry $personalization_tags_controller,
27 Email_Editor_Logger $logger,
28 Assets_Manager $assets_manager
29 ) {
30 $this->email_api_controller = $email_api_controller;
31 $this->templates = $templates;
32 $this->patterns = $patterns;
33 $this->send_preview_email = $send_preview_email;
34 $this->personalization_tags_registry = $personalization_tags_controller;
35 $this->logger = $logger;
36 $this->assets_manager = $assets_manager;
37 }
38 public function initialize(): void {
39 $this->logger->info( 'Initializing email editor' );
40 do_action( 'woocommerce_email_editor_initialized' );
41 add_filter( 'woocommerce_email_editor_rendering_theme_styles', array( $this, 'extend_email_theme_styles' ), 10, 2 );
42 $this->register_block_patterns();
43 $this->register_email_post_types();
44 $this->register_block_templates();
45 $this->register_email_post_sent_status();
46 $this->register_personalization_tags();
47 $is_editor_page = apply_filters( 'woocommerce_is_email_editor_page', false );
48 if ( $is_editor_page ) {
49 $this->extend_email_post_api();
50 // Initialize the assets manager.
51 $this->assets_manager->initialize();
52 }
53 add_action( 'rest_api_init', array( $this, 'register_email_editor_api_routes' ) );
54 add_filter( 'woocommerce_email_editor_send_preview_email', array( $this->send_preview_email, 'send_preview_email' ), 11, 1 ); // allow for other filter methods to take precedent.
55 add_filter( 'single_template', array( $this, 'load_email_preview_template' ) );
56 add_filter( 'preview_post_link', array( $this, 'update_preview_post_link' ), 10, 2 );
57 $this->logger->info( 'Email editor initialized successfully' );
58 }
59 private function register_block_templates(): void {
60 // 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.
61 $request_uri = '';
62 if ( isset( $_SERVER['REQUEST_URI'] ) && is_string( $_SERVER['REQUEST_URI'] ) ) {
63 $request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
64 }
65 if ( strstr( $request_uri, 'site-editor.php' ) === false ) {
66 $post_types = array_column( $this->get_post_types(), 'name' );
67 $this->templates->initialize( $post_types );
68 }
69 }
70 private function register_block_patterns(): void {
71 $this->patterns->initialize();
72 }
73 private function register_email_post_types(): void {
74 foreach ( $this->get_post_types() as $post_type ) {
75 register_post_type(
76 $post_type['name'],
77 array_merge( $this->get_default_email_post_args(), $post_type['args'] )
78 );
79 }
80 }
81 private function register_personalization_tags(): void {
82 $this->personalization_tags_registry->initialize();
83 }
84 private function get_post_types(): array {
85 $post_types = array();
86 return apply_filters( 'woocommerce_email_editor_post_types', $post_types );
87 }
88 private function get_default_email_post_args(): array {
89 return array(
90 'public' => false,
91 'hierarchical' => false,
92 'show_ui' => true,
93 'show_in_menu' => false,
94 'show_in_nav_menus' => false,
95 'supports' => array(
96 'editor' => array(
97 'default-mode' => 'template-locked',
98 ),
99 'title',
100 'custom-fields',
101 ), // 'custom-fields' is required for loading meta fields via API.
102 'has_archive' => true,
103 'show_in_rest' => true, // Important to enable Gutenberg editor.
104 'default_rendering_mode' => 'template-locked',
105 'publicly_queryable' => true, // required by the preview in new tab feature.
106 );
107 }
108 private function register_email_post_sent_status(): void {
109 $default_args = array(
110 'public' => false,
111 'exclude_from_search' => true,
112 'internal' => true, // for now, we hide it, if we use the status in the listings we may flip this and following values.
113 'show_in_admin_all_list' => false,
114 'show_in_admin_status_list' => false,
115 'private' => true, // required by the preview in new tab feature for sent post (newsletter). Posts are only visible to site admins and editors.
116 );
117 $args = apply_filters( 'woocommerce_email_editor_post_sent_status_args', $default_args );
118 register_post_status(
119 'sent',
120 $args
121 );
122 }
123 public function extend_email_post_api() {
124 $email_post_types = array_column( $this->get_post_types(), 'name' );
125 register_rest_field(
126 $email_post_types,
127 'email_data',
128 array(
129 'get_callback' => array( $this->email_api_controller, 'get_email_data' ),
130 'update_callback' => array( $this->email_api_controller, 'save_email_data' ),
131 'schema' => $this->email_api_controller->get_email_data_schema(),
132 )
133 );
134 }
135 public function register_email_editor_api_routes() {
136 register_rest_route(
137 'woocommerce-email-editor/v1',
138 '/send_preview_email',
139 array(
140 'methods' => 'POST',
141 'callback' => array( $this->email_api_controller, 'send_preview_email_data' ),
142 'permission_callback' => function ( WP_REST_Request $request ) {
143 if ( ! current_user_can( 'edit_posts' ) ) {
144 return false;
145 }
146 $post_id = $request->get_param( 'postId' );
147 if ( is_numeric( $post_id ) && (int) $post_id > 0 ) {
148 return current_user_can( 'edit_post', (int) $post_id );
149 }
150 return (bool) apply_filters( 'woocommerce_email_editor_send_preview_email_without_post_permission', false, $request );
151 },
152 )
153 );
154 register_rest_route(
155 'woocommerce-email-editor/v1',
156 '/get_personalization_tags',
157 array(
158 'methods' => 'GET',
159 'callback' => array( $this->email_api_controller, 'get_personalization_tags' ),
160 'permission_callback' => function () {
161 return current_user_can( 'edit_posts' );
162 },
163 )
164 );
165 register_rest_route(
166 'woocommerce-email-editor/v1',
167 '/personalization_tags',
168 array(
169 'methods' => 'GET',
170 'callback' => array( $this->email_api_controller, 'get_personalization_tags_collection' ),
171 'permission_callback' => function () {
172 return current_user_can( 'edit_posts' );
173 },
174 'args' => array(
175 'post_id' => array(
176 'description' => __( 'The post ID for context-aware tag filtering.', 'woocommerce' ),
177 'type' => 'integer',
178 'required' => false,
179 'sanitize_callback' => 'absint',
180 ),
181 ),
182 )
183 );
184 }
185 public function extend_email_theme_styles( WP_Theme_JSON $theme, WP_Post $post ): WP_Theme_JSON {
186 $email_theme = get_post_meta( $post->ID, self::WOOCOMMERCE_EMAIL_META_THEME_TYPE, true );
187 if ( $email_theme && is_array( $email_theme ) ) {
188 $theme->merge( new WP_Theme_JSON( $email_theme ) );
189 }
190 return $theme;
191 }
192 public function get_current_post() {
193 if ( isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
194 $post_id = 0;
195 if ( is_string( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- data valid
196 $post_id = intval( $_GET['post'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- data valid
197 }
198 $current_post = get_post( $post_id );
199 } else {
200 $current_post = $GLOBALS['post'];
201 }
202 return $current_post;
203 }
204 private function current_post_is_email_post_type( $current_post_type ): bool {
205 if ( ! $current_post_type ) {
206 return false;
207 }
208 $email_post_types = array_column( $this->get_post_types(), 'name' );
209 return in_array( $current_post_type, $email_post_types, true );
210 }
211 public function load_email_preview_template( $template ) {
212 $post = $this->get_current_post();
213 if ( ! $post instanceof \WP_Post ) {
214 return $template;
215 }
216 if ( ! $this->current_post_is_email_post_type( $post->post_type ) ) {
217 return $template;
218 }
219 // Anyone can see a published email. For other statuses the user must be able to read the post.
220 if ( ! is_post_publicly_viewable( $post ) && ! current_user_can( 'read_post', $post->ID ) ) {
221 return $template;
222 }
223 add_filter(
224 'woocommerce_email_editor_preview_post_template_html',
225 function () use ( $post ) {
226 // Generate HTML content for email editor post.
227 return $this->send_preview_email->render_html( $post );
228 }
229 );
230 return __DIR__ . '/Templates/single-email-post-template.php';
231 }
232 public function update_preview_post_link( $preview_link, $post ) {
233 if ( ! $post instanceof \WP_Post ) {
234 return $preview_link;
235 }
236 if ( ! $this->current_post_is_email_post_type( $post->post_type ) ) {
237 return $preview_link;
238 }
239 // Remove preview_nonce from the link.
240 return remove_query_arg( 'preview_nonce', $preview_link );
241 }
242 }
243