PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.8
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.8
2.12.8 2.12.7 2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 All 98 releases
← All changes | inc/gutenberg-hooks.php +113 -78 0.0.11 → 2.12.8 View file →
@@ -6,12 +6,9 @@
6 6 */
7 7
8 8 namespace SRFM\Inc;
9 9
10 -use Spec_Gb_Helper;
11 10 use SRFM\Inc\Traits\Get_Instance;
12 -use SRFM\Inc\Smart_Tags;
13 -use SRFM\Inc\Helper;
14 11
15 12 if ( ! defined( 'ABSPATH' ) ) {
16 13 exit; // Exit if accessed directly.
17 14 }
@@ -21,9 +18,9 @@
21 18 *
22 19 * @since 0.0.1
23 20 */
24 21 class Gutenberg_Hooks {
25 -
22 + use Get_Instance;
26 23 /**
27 24 * Block patterns to register.
28 25 *
29 26 * @var array<mixed>
@@ -29,10 +26,8 @@
29 26 * @var array<mixed>
30 27 */
31 28 protected $patterns = [];
32 29
33 - use Get_Instance;
34 -
35 30 /**
36 31 * Class constructor.
37 32 *
38 33 * @return void
@@ -52,20 +47,20 @@
52 47
53 48 // Initializing hooks.
54 49 add_action( 'enqueue_block_editor_assets', [ $this, 'form_editor_screen_assets' ] );
55 50 add_action( 'enqueue_block_editor_assets', [ $this, 'block_editor_assets' ] );
56 - add_filter( 'block_categories_all', [ $this, 'register_block_categories' ], 10, 1 );
57 - add_action( 'init', [ $this, 'register_block_patterns' ], 9 );
51 + add_filter( 'block_categories_all', [ $this, 'register_block_categories' ], 10, 2 );
58 52 add_filter( 'allowed_block_types_all', [ $this, 'disable_forms_wrapper_block' ], 10, 2 );
59 53 add_action( 'save_post_sureforms_form', [ $this, 'update_field_slug' ], 10, 2 );
54 + add_action( 'load-post.php', [ $this, 'maybe_migrate_form_stylings' ] );
60 55 }
61 56
62 57 /**
63 58 * Disable Sureforms_Form Block and allowed only sureforms block inside Sureform CPT editor.
64 59 *
65 - * @param bool|string[] $allowed_block_types Array of block types.
60 + * @param bool|array<string> $allowed_block_types Array of block types.
66 61 * @param \WP_Block_Editor_Context $editor_context The current block editor context.
67 - * @return array<mixed>|void
62 + * @return array<mixed>|bool
68 63 * @since 0.0.1
69 64 */
70 65 public function disable_forms_wrapper_block( $allowed_block_types, $editor_context ) {
71 66 if ( ! empty( $editor_context->post->post_type ) && 'sureforms_form' === $editor_context->post->post_type ) {
@@ -85,26 +80,31 @@
85 80 'srfm/icon',
86 81 'srfm/image',
87 82 'srfm/advanced-heading',
88 83 'srfm/inline-button',
84 + 'srfm/payment',
89 85 ];
90 86 // Apply a filter to the $allow_block_types types array.
91 - $allow_block_types = apply_filters( 'srfm_allowed_block_types', $allow_block_types, $editor_context );
92 - return $allow_block_types;
87 + return apply_filters( 'srfm_allowed_block_types', $allow_block_types, $editor_context );
93 88 }
89 +
90 + // Return the default $allowed_block_types value.
91 + return $allowed_block_types;
94 92 }
95 93
96 94 /**
97 95 * Register our custom block category.
98 96 *
99 - * @param array<mixed> $categories Array of categories.
97 + * @param array<mixed> $categories Array of categories.
98 + * @param \WP_Block_Editor_Context $block_editor_context The current block editor context.
100 99 * @return array<mixed>
101 100 * @since 0.0.1
102 101 */
103 - public function register_block_categories( $categories ) {
104 - $screen = get_current_screen();
102 + public function register_block_categories( $categories, $block_editor_context ) {
105 103
106 - if ( $screen && SRFM_FORMS_POST_TYPE === $screen->post_type ) {
104 + $post_type = $block_editor_context->post->post_type ?? '';
105 +
106 + if ( $post_type && SRFM_FORMS_POST_TYPE === $post_type ) {
107 107 $title = esc_html__( 'General Fields', 'sureforms' );
108 108 } else {
109 109 $title = esc_html__( 'SureForms', 'sureforms' );
110 110 }
@@ -122,52 +122,9 @@
122 122
123 123 return array_merge( $custom_categories, $categories );
124 124 }
125 125
126 -
127 126 /**
128 - * Register our block patterns.
129 - *
130 - * @return void
131 - * @since 0.0.1
132 - */
133 - public function register_block_patterns() {
134 - // Apply filters to the patterns.
135 - $this->patterns = apply_filters( 'srfm_block_patterns', $this->patterns );
136 -
137 - // Iterate over each block pattern.
138 - foreach ( $this->patterns as $block_pattern ) {
139 - // Attempt to register block pattern from the main directory.
140 - if ( ! $this->register_block_pattern_from_directory( $block_pattern, plugin_dir_path( SRFM_FILE ) . 'templates/forms/' ) ) {
141 - // If unsuccessful, attempt to register block pattern from the pro directory.
142 - if ( defined( 'SRFM_PRO_VER' ) && defined( 'SRFM_PRO_DIR' ) ) {
143 - $this->register_block_pattern_from_directory( $block_pattern, SRFM_PRO_DIR . 'templates/forms/' );
144 - }
145 - }
146 - }
147 - }
148 -
149 - /**
150 - * Register block pattern from the specified directory.
151 - *
152 - * @param string|mixed $block_pattern The block pattern name.
153 - * @param string $directory The directory path.
154 - * @since 0.0.2
155 - * @return bool True if the block pattern was registered, false otherwise.
156 - */
157 - private function register_block_pattern_from_directory( $block_pattern, $directory ) {
158 - $pattern_file = $directory . $block_pattern . '.php';
159 -
160 - if ( is_readable( $pattern_file ) ) {
161 - register_block_pattern( 'srfm/' . $block_pattern, require $pattern_file );
162 - return true;
163 - }
164 -
165 - return false;
166 - }
167 -
168 -
169 - /**
170 127 * Add Form Editor Scripts.
171 128 *
172 129 * @return void
173 130 * @since 0.0.1
@@ -190,9 +147,21 @@
190 147 'version' => SRFM_VER,
191 148 ];
192 149
193 150 wp_enqueue_script( SRFM_SLUG . $form_editor_script, SRFM_URL . 'assets/build/formEditor.js', $script_info['dependencies'], $script_info['version'], true );
151 + wp_localize_script( SRFM_SLUG . $form_editor_script, 'scIcons', [ 'path' => SRFM_URL . 'assets/build/icon-assets' ] );
194 152
153 + // Deep-link (#3030): the "Finish setting up" Thank You notice CTA opens this
154 + // editor with ?srfm_focus=… to auto-open a settings tab. Gutenberg strips
155 + // unrecognised query args client-side before the editor bundle can read them,
156 + // so surface the value from the server — where it is never stripped — as a
157 + // global the bundle reads at evaluation time. Validated to a known allowlist.
158 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only deep-link hint on an authenticated editor screen; no state change.
159 + $srfm_focus = isset( $_GET['srfm_focus'] ) ? sanitize_key( wp_unslash( $_GET['srfm_focus'] ) ) : '';
160 + if ( in_array( $srfm_focus, [ 'thankyou', 'notifications' ], true ) ) {
161 + wp_add_inline_script( SRFM_SLUG . $form_editor_script, 'window.srfmDeepLinkFocus = ' . wp_json_encode( $srfm_focus ) . ';', 'before' );
162 + }
163 +
195 164 // Enqueue the code editor for the Custom CSS Editor in SureForms.
196 165 wp_enqueue_code_editor( [ 'type' => 'text/css' ] );
197 166 wp_enqueue_script( 'wp-theme-plugin-editor' );
198 167 wp_enqueue_style( 'wp-codemirror' );
@@ -200,12 +169,15 @@
200 169 wp_localize_script(
201 170 SRFM_SLUG . $form_editor_script,
202 171 SRFM_SLUG . '_block_data',
203 172 [
204 - 'plugin_url' => SRFM_URL,
205 - 'admin_email' => get_option( 'admin_email' ),
173 + 'plugin_url' => SRFM_URL,
174 + 'admin_email' => get_option( 'admin_email' ),
175 + 'pro_plugin_name' => defined( 'SRFM_PRO_VER' ) && defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'free',
206 176 ]
207 177 );
178 +
179 + Helper::register_script_translations( SRFM_SLUG . $form_editor_script );
208 180 }
209 181
210 182 /**
211 183 * Register all editor scripts.
@@ -225,27 +197,43 @@
225 197 'version' => SRFM_VER,
226 198 ];
227 199 wp_enqueue_script( SRFM_SLUG . $all_screen_blocks, SRFM_URL . 'assets/build/blocks.js', $blocks_info['dependencies'], SRFM_VER, true );
228 200
229 - $plugin_path = 'sureforms-pro/sureforms-pro.php';
201 + Helper::register_script_translations( SRFM_SLUG . $all_screen_blocks );
230 202
203 + $site_url = Helper::get_string_value( wp_parse_url( esc_url( get_site_url() ), PHP_URL_HOST ) );
204 + $site_url = preg_replace( '/^www\./', '', $site_url );
205 +
231 206 wp_localize_script(
232 207 SRFM_SLUG . $all_screen_blocks,
233 208 SRFM_SLUG . '_block_data',
234 209 [
235 - 'template_picker_url' => admin_url( '/admin.php?page=add-new-form' ),
236 - 'plugin_url' => SRFM_URL,
237 - 'admin_email' => get_option( 'admin_email' ),
238 - 'post_url' => admin_url( 'post.php' ),
239 - 'current_screen' => $screen,
240 - 'smart_tags_array' => Smart_Tags::smart_tag_list(),
241 - 'smart_tags_array_email' => Smart_Tags::email_smart_tag_list(),
242 - 'srfm_form_markup_nonce' => wp_create_nonce( 'srfm_form_markup' ),
243 - 'get_form_markup_url' => 'sureforms/v1/generate-form-markup',
244 - 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
245 - 'get_default_dynamic_block_option' => get_option( 'get_default_dynamic_block_option', Helper::default_dynamic_block_option() ),
246 - 'form_selector_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
247 - 'is_admin_user' => current_user_can( 'manage_options' ),
210 + 'template_picker_url' => admin_url( '/admin.php?page=add-new-form' ),
211 + 'plugin_url' => SRFM_URL,
212 + 'admin_email' => get_option( 'admin_email' ),
213 + 'post_url' => admin_url( 'post.php' ),
214 + 'current_screen' => $screen,
215 + 'smart_tags_array' => Smart_Tags::smart_tag_list(),
216 + 'smart_tags_array_email' => Smart_Tags::email_smart_tag_list(),
217 + // No srfm_form_markup nonce: the generate-form-markup route is gated by a
218 + // capability check, not by holding a nonce. It used to be minted here for
219 + // every editor user and read from the query string, which is precisely how
220 + // that route ended up with no real authorization (#2995).
221 + 'get_form_markup_url' => 'sureforms/v1/generate-form-markup',
222 + 'is_pro_active' => Helper::has_pro(),
223 + 'srfm_default_dynamic_block_option' => wp_parse_args( Helper::get_array_value( get_option( 'srfm_default_dynamic_block_option', [] ) ), Helper::default_dynamic_block_option() ),
224 + 'form_selector_nonce' => Helper::current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
225 + 'is_admin_user' => Helper::current_user_can(),
226 + 'site_url' => $site_url,
227 + 'is_suremails_active' => is_plugin_active( 'suremails/suremails.php' ),
228 + 'upgrade_url' => add_query_arg(
229 + [ 'utm_medium' => 'embed_styling_upgrade' ],
230 + Helper::get_sureforms_website_url( 'pricing' )
231 + ),
232 + 'default_translations' => [
233 + 'gdpr_label' => __( 'I consent to have this website store my submitted information so they can respond to my inquiry.', 'sureforms' ),
234 + 'dropdown_placeholder' => __( 'Select an option', 'sureforms' ),
235 + ],
248 236 ]
249 237 );
250 238
251 239 // Localizing the field preview image links.
@@ -265,8 +253,9 @@
265 253 'phone_preview' => SRFM_URL . 'images/field-previews/phone.svg',
266 254 'dropdown_preview' => SRFM_URL . 'images/field-previews/dropdown.svg',
267 255 'address_preview' => SRFM_URL . 'images/field-previews/address.svg',
268 256 'sureforms_preview' => SRFM_URL . 'images/field-previews/sureforms.svg',
257 + 'payment_preview' => SRFM_URL . 'images/field-previews/payment.svg',
269 258 ]
270 259 )
271 260 );
272 261
@@ -305,21 +294,67 @@
305 294 * used to maintain uniqueness of slugs.
306 295 */
307 296 $slugs = [];
308 297
309 - list( $blocks, $slugs, $updated ) = Helper::process_blocks( $blocks, $slugs, $updated );
298 + [ $blocks, $slugs, $updated ] = Helper::process_blocks( $blocks, $slugs, $updated );
310 299
300 + // Process and store block configurations for form fields.
301 + Field_Validation::add_block_config( $blocks, $post_id );
302 +
311 303 if ( ! $updated ) {
312 304 return;
313 305 }
314 306
315 - $post_content = addslashes( serialize_blocks( $blocks ) );
307 + $post_content = serialize_blocks( $blocks );
316 308
309 + // Use wp_slash() to preserve unicode escapes (like \u003c for <) in block attributes.
310 + // Without this, wp_update_post() calls wp_unslash() which corrupts these escapes.
317 311 wp_update_post(
318 312 [
319 313 'ID' => $post_id,
320 - 'post_content' => $post_content,
314 + 'post_content' => wp_slash( $post_content ),
321 315 ]
322 316 );
323 317 }
324 318
319 + /**
320 + * Migrate the background type and associated values from
321 + * instant form settings to form styling meta.
322 + *
323 + * @since 1.4.4
324 + * @return void
325 + */
326 + public function maybe_migrate_form_stylings() {
327 + $post_id = isset( $_GET['post'] ) ? Helper::get_integer_value( sanitize_text_field( wp_unslash( $_GET['post'] ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['post'] does not provide nonce.
328 + if ( empty( $post_id ) || ! Helper::current_user_can() ) {
329 + return;
330 + }
331 +
332 + $post_type = get_post_type( $post_id );
333 + if ( SRFM_FORMS_POST_TYPE !== $post_type ) {
334 + return;
335 + }
336 +
337 + $instant_form_settings = get_post_meta( $post_id, '_srfm_instant_form_settings', true );
338 + if ( ! is_array( $instant_form_settings ) ) {
339 + return;
340 + }
341 +
342 + $form_styling = get_post_meta( $post_id, '_srfm_forms_styling', true );
343 + if ( ! is_array( $form_styling ) ) {
344 + $form_styling = [];
345 + }
346 +
347 + $migrated = false;
348 + $keys = [ 'bg_type', 'bg_color', 'bg_image', 'bg_image_id' ];
349 +
350 + foreach ( $keys as $key ) {
351 + if ( ! isset( $form_styling[ $key ] ) && isset( $instant_form_settings[ $key ] ) ) {
352 + $form_styling[ $key ] = $instant_form_settings[ $key ];
353 + $migrated = true;
354 + }
355 + }
356 + if ( $migrated ) {
357 + update_post_meta( $post_id, '_srfm_forms_styling', $form_styling );
358 + }
359 + }
325 360 }