PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.32
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.32
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/controllers/FrmStylesController.php +453 -131 6.36.32 View file →
@@ -5,22 +5,34 @@
5 5
6 6 class FrmStylesController {
7 7
8 8 /**
9 - * @var string $post_type
9 + * @var string
10 10 */
11 11 public static $post_type = 'frm_styles';
12 12
13 13 /**
14 - * @var string $screen
14 + * @var string
15 15 */
16 16 public static $screen = 'formidable_page_formidable-styles';
17 17
18 18 /**
19 - * @var string|null $message
19 + * @var string|null
20 20 */
21 21 private static $message;
22 22
23 + /**
24 + * Cache of the active style object keyed by form ID.
25 + *
26 + * @since 6.32
27 + *
28 + * @var array
29 + */
30 + private static $active_style = array();
31 +
32 + /**
33 + * @return void
34 + */
23 35 public static function load_pro_hooks() {
24 36 if ( FrmAppHelper::pro_is_installed() ) {
25 37 FrmProStylesController::load_pro_hooks();
26 38 }
@@ -25,8 +37,11 @@
25 37 FrmProStylesController::load_pro_hooks();
26 38 }
27 39 }
28 40
41 + /**
42 + * @return void
43 + */
29 44 public static function register_post_types() {
30 45 register_post_type(
31 46 self::$post_type,
32 47 array(
@@ -67,10 +82,10 @@
67 82 *
68 83 * @return void
69 84 */
70 85 public static function menu() {
71 - add_submenu_page( 'formidable', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Styles', 'formidable' ), 'frm_change_settings', 'formidable-styles', 'FrmStylesController::route' );
72 - add_submenu_page( 'themes.php', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Forms', 'formidable' ), 'frm_change_settings', 'formidable-styles2', 'FrmStylesController::route' );
86 + add_submenu_page( 'formidable', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Styles', 'formidable' ), 'frm_change_settings', 'formidable-styles', 'FrmStylesController::route' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
87 + add_submenu_page( 'themes.php', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Forms', 'formidable' ), 'frm_change_settings', 'formidable-styles2', 'FrmStylesController::route' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
73 88 }
74 89
75 90 /**
76 91 * Remove filters for the visual styler preview.
@@ -95,9 +110,9 @@
95 110 *
96 111 * @return void
97 112 */
98 113 private static function disable_form_css() {
99 - add_filter( 'get_frm_stylesheet', '__return_false' );
114 + add_filter( 'get_frm_stylesheet', '__return_empty_array' );
100 115 }
101 116
102 117 /**
103 118 * Removing this action prevents front end JavaScript from loading.
@@ -119,22 +134,23 @@
119 134 if ( ! FrmAppHelper::is_style_editor_page() ) {
120 135 return;
121 136 }
122 137
138 + FrmStyleComponent::register_assets();
123 139 self::load_pro_hooks();
124 140
125 141 $version = FrmAppHelper::plugin_version();
126 - wp_enqueue_script( 'jquery-ui-datepicker' );
127 142
128 143 if ( FrmAppHelper::is_style_editor_page( 'edit' ) ) {
129 144 wp_enqueue_style( 'wp-color-picker' );
130 145 }
131 146
132 - wp_enqueue_style( 'frm-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_css' ), array(), $version );
147 + wp_enqueue_style( 'frm-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_css&frm_scope_custom_css=1' ), array(), $version );
133 148
134 149 $style = apply_filters( 'frm_style_head', false );
150 +
135 151 if ( $style ) {
136 - wp_enqueue_style( 'frm-single-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_load_css&flat=1' ) . '&' . http_build_query( $style->post_content ), array(), $version );
152 + wp_enqueue_style( 'frm-single-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_load_css&flat=1' ) . '&' . http_build_query( $style->post_content ), array(), $version ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
137 153 }
138 154 }
139 155
140 156 /**
@@ -152,9 +168,9 @@
152 168 'frm_update_settings',
153 169 /**
154 170 * Update the form data on the "Manage Styles" tab after global settings are saved.
155 171 */
156 - function() {
172 + function () {
157 173 self::manage_styles();
158 174 }
159 175 );
160 176 }
@@ -161,8 +177,9 @@
161 177
162 178 /**
163 179 * @param string $register Either 'enqueue' or 'register'.
164 180 * @param bool $force True to enqueue/register the style if a form has not been loaded.
181 + *
165 182 * @return void
166 183 */
167 184 public static function enqueue_css( $register = 'enqueue', $force = false ) {
168 185 global $frm_vars;
@@ -174,8 +191,9 @@
174 191 return;
175 192 }
176 193
177 194 $frm_settings = FrmAppHelper::get_settings();
195 +
178 196 if ( $frm_settings->load_style === 'none' ) {
179 197 return;
180 198 }
181 199
@@ -191,9 +209,10 @@
191 209 wp_register_style( $css_key, $file, array(), $this_version );
192 210 }
193 211
194 212 $load_on_all = ! FrmAppHelper::is_admin() && 'all' === $frm_settings->load_style;
195 - if ( $load_on_all || $register != 'register' ) {
213 +
214 + if ( $load_on_all || $register !== 'register' ) {
196 215 wp_enqueue_style( $css_key );
197 216 }
198 217 unset( $css_key, $file );
199 218 }
@@ -200,9 +219,9 @@
200 219
201 220 if ( $frm_settings->load_style === 'all' ) {
202 221 $frm_vars['css_loaded'] = true;
203 222 }
204 - }
223 + }//end if
205 224 unset( $css );
206 225
207 226 add_filter( 'style_loader_tag', 'FrmStylesController::add_tags_to_css', 10, 2 );
208 227 }
@@ -223,18 +242,22 @@
223 242 }
224 243
225 244 /**
226 245 * @param array $stylesheet_urls
246 + *
227 247 * @return void
228 248 */
229 249 private static function get_url_to_custom_style( &$stylesheet_urls ) {
230 - $file_name = '/css/' . self::get_file_name();
231 - if ( is_readable( FrmAppHelper::plugin_path() . $file_name ) ) {
232 - $url = FrmAppHelper::plugin_url() . $file_name;
233 - } else {
234 - $url = admin_url( 'admin-ajax.php?action=frmpro_css' );
250 + $add_css_to_uploads_dir = FrmStyle::add_css_to_uploads_dir();
251 + $file_path = FrmStyle::get_generated_css_file_path( $add_css_to_uploads_dir ) . '/' . self::get_file_name();
252 +
253 + if ( ! is_readable( $file_path ) ) {
254 + $stylesheet_urls['formidable'] = admin_url( 'admin-ajax.php?action=frmpro_css' );
255 + return;
235 256 }
236 - $stylesheet_urls['formidable'] = $url;
257 +
258 + $base_url = $add_css_to_uploads_dir ? wp_upload_dir()['baseurl'] . '/formidable/css/' : FrmAppHelper::plugin_url() . '/css/';
259 + $stylesheet_urls['formidable'] = $base_url . self::get_file_name();
237 260 }
238 261
239 262 /**
240 263 * Use a different stylesheet per site in a multisite install
@@ -239,39 +262,44 @@
239 262 /**
240 263 * Use a different stylesheet per site in a multisite install
241 264 *
242 265 * @since 3.0.03
266 + *
267 + * @return string
243 268 */
244 269 public static function get_file_name() {
245 270 if ( is_multisite() ) {
246 - $blog_id = get_current_blog_id();
247 - $name = 'formidableforms' . absint( $blog_id ) . '.css';
248 - } else {
249 - $name = 'formidableforms.css';
271 + return 'formidableforms' . absint( get_current_blog_id() ) . '.css';
250 272 }
251 273
252 - return $name;
274 + return 'formidableforms.css';
253 275 }
254 276
277 + /**
278 + * @param string $css_key
279 + * @param string $version
280 + *
281 + * @return string
282 + */
255 283 private static function get_css_version( $css_key, $version ) {
256 - if ( 'formidable' == $css_key ) {
257 - $this_version = get_option( 'frm_last_style_update' );
258 - if ( ! $this_version ) {
259 - $this_version = $version;
260 - }
261 - } else {
262 - $this_version = $version;
284 + if ( 'formidable' !== $css_key ) {
285 + return $version;
263 286 }
264 287
265 - return $this_version;
288 + $this_version = get_option( 'frm_last_style_update' );
289 +
290 + return $this_version ? $this_version : $version;
266 291 }
267 292
293 + /**
294 + * @param string $tag
295 + * @param string $handle
296 + *
297 + * @return string
298 + */
268 299 public static function add_tags_to_css( $tag, $handle ) {
269 - if ( ( 'formidable' == $handle || 'jquery-theme' == $handle ) && strpos( $tag, ' property=' ) === false ) {
270 - $frm_settings = FrmAppHelper::get_settings();
271 - if ( $frm_settings->use_html ) {
272 - $tag = str_replace( ' type="', ' property="stylesheet" type="', $tag );
273 - }
300 + if ( ( 'formidable' === $handle || 'jquery-theme' === $handle ) && ! str_contains( $tag, ' property=' ) ) {
301 + return str_replace( ' type="', ' property="stylesheet" type="', $tag );
274 302 }
275 303
276 304 return $tag;
277 305 }
@@ -319,25 +347,39 @@
319 347
320 348 self::setup_styles_and_scripts_for_styler();
321 349
322 350 $style_id = self::get_style_id_for_styler();
351 +
323 352 if ( ! $style_id ) {
324 - wp_die( esc_html__( 'Invalid route', 'formidable' ), esc_html__( 'Invalid route', 'formidable' ), 400 );
353 + $error_args = array(
354 + 'title' => __( 'No styles', 'formidable' ),
355 + 'body' => __( 'You must have a style to use the Visual Styler.', 'formidable' ),
356 + 'cancel_url' => admin_url( 'admin.php?page=formidable' ),
357 + );
358 + FrmAppController::show_error_modal( $error_args );
359 + return;
325 360 }
326 361
327 362 $form_id = FrmAppHelper::simple_get( 'form', 'absint', 0 );
363 +
328 364 if ( ! $form_id ) {
329 365 $form_id = self::get_form_id_for_style( $style_id );
330 366 }
331 367
332 368 $form = FrmForm::getOne( $form_id );
369 +
333 370 if ( ! is_object( $form ) ) {
334 - wp_die( esc_html__( 'Invalid route', 'formidable' ), esc_html__( 'Invalid route', 'formidable' ), 400 );
371 + $error_args = array(
372 + 'title' => __( 'No forms', 'formidable' ),
373 + 'body' => __( 'You must have a form to use the Visual Styler.', 'formidable' ),
374 + 'cancel_url' => admin_url( 'admin.php?page=formidable' ),
375 + );
376 + FrmAppController::show_error_modal( $error_args );
377 + return;
335 378 }
336 379
337 - $frm_style = new FrmStyle( $style_id );
338 - $active_style = $frm_style->get_one();
339 - $default_style = self::get_default_style();
380 + $frm_style = new FrmStyle( $style_id );
381 + $active_style = $frm_style->get_one();
340 382
341 383 self::disable_admin_page_styling_on_submit_buttons();
342 384
343 385 /**
@@ -342,15 +384,13 @@
342 384
343 385 /**
344 386 * @since 6.0
345 387 *
346 - * @param array {
347 - * @type stdClass $form
348 - * }
388 + * @param array{form:\stdClass} $data
349 389 */
350 390 do_action( 'frm_before_render_style_page', compact( 'form' ) );
351 391
352 - self::render_style_page( $active_style, $form, $default_style );
392 + self::render_style_page( $active_style, $form, self::get_default_style() );
353 393 }
354 394
355 395 /**
356 396 * @since 6.0
@@ -358,8 +398,9 @@
358 398 * @return int
359 399 */
360 400 private static function get_style_id_for_styler() {
361 401 $action = FrmAppHelper::simple_get( 'frm_action' );
402 +
362 403 if ( 'duplicate' === $action ) {
363 404 // The duplicate action uses style_id instead of id for better backward compatibility.
364 405 return FrmAppHelper::simple_get( 'style_id', 'absint', 0 );
365 406 }
@@ -364,8 +405,9 @@
364 405 return FrmAppHelper::simple_get( 'style_id', 'absint', 0 );
365 406 }
366 407
367 408 $style_id = FrmAppHelper::simple_get( 'id', 'absint', 0 );
409 +
368 410 if ( $style_id ) {
369 411 // Always use the style ID from the URL if one is specified.
370 412 return $style_id;
371 413 }
@@ -370,8 +412,9 @@
370 412 return $style_id;
371 413 }
372 414
373 415 $request_form_id = FrmAppHelper::simple_get( 'form', 'absint', 0 );
416 +
374 417 if ( $request_form_id && is_callable( 'FrmProStylesController::get_active_style_for_form' ) ) {
375 418 return FrmProStylesController::get_active_style_for_form( $request_form_id )->ID;
376 419 }
377 420
@@ -383,8 +426,9 @@
383 426 *
384 427 * @since 6.0
385 428 *
386 429 * @param int $style_id
430 + *
387 431 * @return int
388 432 */
389 433 private static function get_form_id_for_style( $style_id ) {
390 434 $check = serialize( array( 'custom_style' => (string) $style_id ) );
@@ -397,13 +441,13 @@
397 441 )
398 442 );
399 443
400 444 if ( ! $form_id ) {
401 - // TODO: Show a message why a random form is being shown (because no form is assigned to the style).
402 445 // Fallback to any form.
403 - $where = array(
446 + $where = array(
404 447 'status' => 'published',
405 - 'parent_form_id' => array( null, 0 ), // Make sure it's not a repeater.
448 + // Make sure it's not a repeater.
449 + 'parent_form_id' => array( null, 0 ),
406 450 );
407 451 $form_id = FrmDb::get_var( 'frm_forms', $where, 'id' );
408 452 }
409 453
@@ -417,9 +461,9 @@
417 461 */
418 462 private static function disable_admin_page_styling_on_submit_buttons() {
419 463 add_filter(
420 464 'frm_submit_button_class',
421 - function( $classes ) {
465 + function ( $classes ) {
422 466 $classes[] = 'frm_no_style_button';
423 467 return $classes;
424 468 }
425 469 );
@@ -430,11 +474,10 @@
430 474 *
431 475 * @return WP_Post
432 476 */
433 477 private static function get_default_style() {
434 - $frm_style = new FrmStyle( 'default' );
435 - $default_style = $frm_style->get_one();
436 - return $default_style;
478 + $frm_style = new FrmStyle( 'default' );
479 + return $frm_style->get_one();
437 480 }
438 481
439 482 /**
440 483 * Save style for form (from Styler list page) via a POST action.
@@ -444,13 +487,15 @@
444 487 * @return void
445 488 */
446 489 private static function save_form_style() {
447 490 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'frm_save_form_style', 'frm_save_form_style_nonce' );
491 +
448 492 if ( $permission_error !== false ) {
449 493 wp_die( 'Unable to save form', '', 403 );
450 494 }
451 495
452 496 $style_id = FrmAppHelper::get_post_param( 'style_id', 0, 'absint' );
497 +
453 498 if ( $style_id && ! self::confirm_style_exists_before_setting( $style_id ) ) {
454 499 wp_die( esc_html__( 'Invalid target style', 'formidable' ), esc_html__( 'Invalid target style', 'formidable' ), 400 );
455 500 return;
456 501 }
@@ -463,15 +508,16 @@
463 508 * @param int $style_id
464 509 */
465 510 $style_id = apply_filters( 'frm_saved_form_style_id', $style_id );
466 511
467 - if ( ! $style_id && '0' !== FrmAppHelper::get_post_param( 'style_id', 'sanitize_text_field', '' ) ) {
512 + if ( ! $style_id && '0' !== FrmAppHelper::get_post_param( 'style_id', '', 'sanitize_text_field' ) ) {
468 513 // "0" is a special value used for the enable/disable toggle.
469 514 wp_die( esc_html__( 'Invalid style value', 'formidable' ), esc_html__( 'Invalid style value', 'formidable' ), 400 );
470 515 return;
471 516 }
472 517
473 - $form_id = FrmAppHelper::get_post_param( 'form_id', 'absint', 0 );
518 + $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
519 +
474 520 if ( ! $form_id ) {
475 521 wp_die( esc_html__( 'No form specified', 'formidable' ), esc_html__( 'No form specified', 'formidable' ), 400 );
476 522 return;
477 523 }
@@ -476,28 +522,46 @@
476 522 return;
477 523 }
478 524
479 525 $form = FrmForm::getOne( $form_id );
526 +
480 527 if ( ! $form ) {
481 528 wp_die( esc_html__( 'Form does not exist', 'formidable' ), esc_html__( 'Form does not exist', 'formidable' ), 400 );
482 529 return;
483 530 }
484 531
532 + $previous_style_id = $form->options['custom_style'];
533 +
485 534 // If the default style is selected, use the "Always use default" legacy option instead of the default style.
486 535 // There's also a check here for conversational forms.
487 536 // Without the check it isn't possible to select "Default" because "Always use default" will convert to "Lines" dynamically.
488 - $default_style = self::get_default_style();
489 - if ( $style_id === $default_style->ID && empty( $form->options['chat'] ) ) {
537 +
538 + if ( $style_id === self::get_default_style()->ID && empty( $form->options['chat'] ) ) {
490 539 $style_id = 1;
491 540 }
492 541
493 - $form->options['custom_style'] = (string) $style_id; // We want to save a string for consistency. FrmStylesHelper::get_form_count_for_style expects the custom style ID is a string.
542 + // We want to save a string for consistency. FrmStylesHelper::get_form_count_for_style expects the custom style ID is a string.
543 + $form->options['custom_style'] = (string) $style_id;
494 544
545 + if ( $previous_style_id === $form->options['custom_style'] ) {
546 + // Exit early before updating DB if nothing actually changed.
547 + self::$message = __( 'Successfully updated style.', 'formidable' );
548 + return;
549 + }
550 +
495 551 global $wpdb;
496 552 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $form->options ) ), array( 'id' => $form->id ) );
497 553
498 554 FrmForm::clear_form_cache();
499 555
556 + /**
557 + * @since 6.25.1
558 + *
559 + * @param int $form_id
560 + * @param int $style_id
561 + */
562 + do_action( 'frm_after_changed_form_style', absint( $form_id ), absint( $style_id ) );
563 +
500 564 self::$message = __( 'Successfully updated style.', 'formidable' );
501 565 }
502 566
503 567 /**
@@ -503,8 +567,9 @@
503 567 /**
504 568 * Validate that we're assigning a form to a style that actually exists before assigning it to a form.
505 569 *
506 570 * @param int $style_id
571 + *
507 572 * @return bool True if the style actually exists.
508 573 */
509 574 private static function confirm_style_exists_before_setting( $style_id ) {
510 575 global $wpdb;
@@ -523,9 +588,9 @@
523 588 $plugin_url = FrmAppHelper::plugin_url();
524 589 $version = FrmAppHelper::plugin_version();
525 590 $js_dependencies = array( 'wp-i18n', 'wp-hooks', 'formidable_dom' );
526 591
527 - if ( FrmAppHelper::pro_is_installed() ) {
592 + if ( FrmAppHelper::pro_is_installed() && is_callable( 'FrmProAppHelper::use_jquery_datepicker' ) && FrmProAppHelper::use_jquery_datepicker() ) {
528 593 $js_dependencies[] = 'jquery-ui-datepicker';
529 594 }
530 595
531 596 wp_register_script( 'formidable_style', $plugin_url . '/js/admin/style.js', $js_dependencies, $version );
@@ -533,8 +598,9 @@
533 598 wp_print_styles( 'formidable_style' );
534 599
535 600 wp_print_styles( 'formidable' );
536 601 wp_enqueue_script( 'formidable_style' );
602 + wp_set_script_translations( 'formidable_style', 'formidable' );
537 603 }
538 604
539 605 /**
540 606 * Render the style page (with a more limited and typed scope than calling it from self::style directly).
@@ -541,20 +607,22 @@
541 607 *
542 608 * @since 6.0
543 609 *
544 610 * @param stdClass|WP_Post $active_style
545 - * @param array<WP_Post> $styles
546 611 * @param stdClass $form
547 612 * @param WP_Post $default_style
613 + *
548 614 * @return void
549 615 */
550 616 private static function render_style_page( $active_style, $form, $default_style ) {
551 617 $style_views_path = self::get_views_path();
552 - $view = FrmAppHelper::simple_get( 'frm_action', 'sanitize_text_field', 'list' ); // edit, list (default), new_style.
553 - $frm_style = new FrmStyle( $active_style->ID );
618 + // Edit, list (default), new_style.
619 + $view = FrmAppHelper::simple_get( 'frm_action', 'sanitize_text_field', 'list' );
620 + $frm_style = new FrmStyle( $active_style->ID );
554 621
555 622 if ( 'new_style' !== $view && ! FrmAppHelper::simple_get( 'form' ) && ! FrmAppHelper::simple_get( 'style_id' ) ) {
556 - $view = 'edit'; // Have the Appearance > Forms link fallback to the edit view. Otherwise we want to use 'list' as the default.
623 + // Have the Appearance > Forms link fallback to the edit view. Otherwise we want to use 'list' as the default.
624 + $view = 'edit';
557 625 }
558 626
559 627 if ( in_array( $view, array( 'edit', 'new_style', 'duplicate' ), true ) ) {
560 628 self::add_meta_boxes();
@@ -565,22 +633,44 @@
565 633 $style = $active_style;
566 634 break;
567 635
568 636 case 'duplicate':
569 - $style = clone $active_style;
570 - $new_style = $frm_style->get_new();
637 + $style = clone $active_style;
638 + $new_style = $frm_style->get_new();
639 + $new_name = self::get_new_style_post_name( $new_style->post_name );
640 +
641 + // The single style custom CSS is nested under the old style's scope. Re-scope it to the
642 + // new style's scope so it unnests correctly for display and re-nests correctly on save.
643 + if ( ! empty( $style->post_content['single_style_custom_css'] ) ) {
644 + $css_scope_helper = new FrmCssScopeHelper();
645 + $unnested_css = $css_scope_helper->unnest( $style->post_content['single_style_custom_css'], 'frm_style_' . $style->post_name ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
646 + $style->post_content['single_style_custom_css'] = $css_scope_helper->nest( $unnested_css, 'frm_style_' . $new_name );
647 + }
648 +
571 649 $style->ID = $new_style->ID;
572 - $style->post_name = $new_style->post_name;
573 - unset( $new_style );
650 + $style->post_name = $new_name;
651 + unset( $new_style, $new_name );
574 652 break;
575 653
576 654 case 'new_style':
577 - $style = $frm_style->get_new();
655 + $style = $frm_style->get_new();
656 + $style->post_name = self::get_new_style_post_name( $style->post_name );
578 657 break;
579 - }
658 + }//end switch
580 659
581 660 if ( in_array( $view, array( 'duplicate', 'new_style' ), true ) ) {
582 - $style->post_title = FrmAppHelper::simple_get( 'style_name' );
661 + // A new or duplicated style has no ID yet, so the Rename modal updates the post_title input
662 + // instead of calling an endpoint. Prefer that posted title over $_GET['style_name'] when present.
663 + $posted_title = '';
664 +
665 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
666 + if ( isset( $_POST['frm_style_setting']['post_title'] ) ) {
667 + // The nonce is verified in FrmStylesController::save_style before this renders.
668 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
669 + $posted_title = sanitize_text_field( wp_unslash( $_POST['frm_style_setting']['post_title'] ) );
670 + }
671 +
672 + $style->post_title = '' !== $posted_title ? $posted_title : FrmAppHelper::simple_get( 'style_name' );
583 673 $style->menu_order = 0;
584 674 }
585 675
586 676 if ( ! isset( $style ) ) {
@@ -604,8 +694,27 @@
604 694 include $style_views_path . 'show.php';
605 695 }
606 696
607 697 /**
698 + * Derive the temporary post_name (CSS scope slug) for a new or duplicated style from the chosen
699 + * style name so the displayed scope matches the slug WordPress will store on save.
700 + *
701 + * Falls back to the auto-generated key when no style name was provided so the scope is never empty.
702 + *
703 + * @since 6.32
704 + *
705 + * @param string $fallback The auto-generated post_name to use when no style name is chosen.
706 + *
707 + * @return string
708 + */
709 + private static function get_new_style_post_name( $fallback ) {
710 + $style_name = FrmAppHelper::simple_get( 'style_name' );
711 + $slug = $style_name ? sanitize_title( $style_name ) : '';
712 +
713 + return $slug ? $slug : $fallback;
714 + }
715 +
716 + /**
608 717 * @since 6.0
609 718 *
610 719 * @return string
611 720 */
@@ -617,22 +726,23 @@
617 726 * Filter form classes so the form uses the preview style, not the form's active style.
618 727 *
619 728 * @since 6.0
620 729 *
621 - * @param WP_Post|stdClass $style A new style is not a WP_Post object.
730 + * @param stdClass|WP_Post $style A new style is not a WP_Post object.
731 + *
622 732 * @return void
623 733 */
624 734 private static function force_form_style( $style ) {
625 735 add_filter(
626 736 'frm_add_form_style_class',
627 - function( $class ) use ( $style ) {
628 - $split = array_filter(
737 + function ( $class ) use ( $style ) {
738 + $split = array_filter(
629 739 explode( ' ', $class ),
630 740 /**
631 741 * @param string $class
632 742 */
633 - function( $class ) {
634 - return $class && 0 !== strpos( $class, 'frm_style_' );
743 + function ( $class ) {
744 + return $class && ! str_starts_with( $class, 'frm_style_' );
635 745 }
636 746 );
637 747 $split[] = 'frm_style_' . $style->post_name;
638 748 return implode( ' ', $split );
@@ -647,10 +757,11 @@
647 757 *
648 758 * @return void
649 759 */
650 760 public static function save_style() {
761 + FrmAppHelper::permission_check( 'frm_change_settings' );
762 +
651 763 $frm_style = new FrmStyle();
652 - $message = '';
653 764 $post_id = FrmAppHelper::get_post_param( 'ID', false, 'sanitize_title' );
654 765 $style_nonce = FrmAppHelper::get_post_param( 'frm_style', '', 'sanitize_text_field' );
655 766
656 767 if ( $post_id === false || ! wp_verify_nonce( $style_nonce, 'frm_style_nonce' ) ) {
@@ -659,13 +770,22 @@
659 770 return;
660 771 }
661 772
662 773 $id = $frm_style->update( $post_id );
774 +
663 775 if ( ! $post_id && $id ) {
664 776 self::maybe_redirect_after_save( $id );
665 - $post_id = reset( $id ); // Set the post id to the new style so it will be loaded for editing.
777 + // Set the post id to the new style so it will be loaded for editing.
778 + $post_id = reset( $id );
666 779 }
667 780
781 + /**
782 + * @since 6.25.1
783 + *
784 + * @param int $post_id
785 + */
786 + do_action( 'frm_after_saved_style', absint( $post_id ) );
787 +
668 788 self::$message = __( 'Your styling settings have been saved.', 'formidable' );
669 789 }
670 790
671 791 /**
@@ -684,19 +804,20 @@
684 804 *
685 805 * @since 6.0
686 806 *
687 807 * @param array $ids
808 + *
688 809 * @return void
689 810 */
690 811 private static function maybe_redirect_after_save( $ids ) {
691 - $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
692 - $parsed = parse_url( $referer );
693 - $query = $parsed['query'];
694 -
812 + $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
813 + $parsed = parse_url( $referer );
814 + $query = $parsed['query'];
695 815 $current_action = false;
696 816 $actions_to_redirect = array( 'duplicate', 'new_style' );
817 +
697 818 foreach ( $actions_to_redirect as $action ) {
698 - if ( false !== strpos( $query, 'frm_action=' . $action ) ) {
819 + if ( str_contains( $query, 'frm_action=' . $action ) ) {
699 820 $current_action = $action;
700 821 break;
701 822 }
702 823 }
@@ -706,10 +827,9 @@
706 827 return;
707 828 }
708 829
709 830 parse_str( $query, $parsed_query );
710 - $form_id = ! empty( $parsed_query['form'] ) ? absint( $parsed_query['form'] ) : 0;
711 -
831 + $form_id = ! empty( $parsed_query['form'] ) ? absint( $parsed_query['form'] ) : 0;
712 832 $style = new stdClass();
713 833 $style->ID = end( $ids );
714 834 wp_safe_redirect( esc_url_raw( FrmStylesHelper::get_edit_url( $style, $form_id ) ) );
715 835 die();
@@ -719,8 +839,9 @@
719 839 * @since 6.0
720 840 *
721 841 * @param string $message
722 842 * @param array|object $forms
843 + *
723 844 * @return void
724 845 */
725 846 public static function manage( $message = '', $forms = array() ) {
726 847 $frm_style = new FrmStyle();
@@ -725,8 +846,9 @@
725 846 public static function manage( $message = '', $forms = array() ) {
726 847 $frm_style = new FrmStyle();
727 848 $styles = $frm_style->get_all();
728 849 $default_style = $frm_style->get_default_style( $styles );
850 + $frm_settings = FrmAppHelper::get_settings();
729 851
730 852 if ( ! $forms ) {
731 853 $forms = FrmForm::get_published_forms();
732 854 }
@@ -743,15 +865,16 @@
743 865 private static function manage_styles() {
744 866 global $wpdb;
745 867
746 868 $forms = FrmForm::get_published_forms();
869 +
747 870 foreach ( $forms as $form ) {
748 - $new_style = ( isset( $_POST['style'] ) && isset( $_POST['style'][ $form->id ] ) ) ? sanitize_text_field( wp_unslash( $_POST['style'][ $form->id ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
749 - $previous_style = ( isset( $_POST['prev_style'] ) && isset( $_POST['prev_style'][ $form->id ] ) ) ? sanitize_text_field( wp_unslash( $_POST['prev_style'][ $form->id ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
750 - if ( $new_style == $previous_style ) {
871 + if ( ! isset( $_POST['style'] ) || ! isset( $_POST['style'][ $form->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
751 872 continue;
752 873 }
753 874
875 + $new_style = sanitize_text_field( wp_unslash( $_POST['style'][ $form->id ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
876 +
754 877 $form->options['custom_style'] = $new_style;
755 878 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $form->options ) ), array( 'id' => $form->id ) );
756 879 unset( $form );
757 880 }
@@ -760,15 +883,28 @@
760 883 /**
761 884 * Echo content for the Custom CSS page.
762 885 *
763 886 * @param string $message
887 + * @param array $extra_args An array of extra arguments.
888 + *
764 889 * @return void
765 890 */
766 - public static function custom_css( $message = '' ) {
767 - $settings = self::enqueue_codemirror();
768 - $id = $settings ? 'frm_codemirror_box' : 'frm_custom_css_box';
769 - $custom_css = self::get_custom_css();
891 + public static function custom_css( $message = '', $extra_args = array() ) {
892 + $id = $extra_args['id'] ?? 'frm_codemirror_box';
893 + $settings = self::enqueue_codemirror( $id, $extra_args['placeholder'] ?? '' );
894 + $id = $settings ? $id : 'frm_custom_css_box';
895 + $show_errors = $extra_args['show_errors'] ?? true;
896 + $custom_css = $extra_args['custom_css'] ?? self::get_custom_css();
897 + $heading = $extra_args['heading'] ?? __( 'You can add custom css here or in your theme style.css. Any CSS added here will be used anywhere the Formidable CSS is loaded.', 'formidable' ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
898 + $textarea_params = ! empty( $extra_args['textarea_params'] ) ? $extra_args['textarea_params'] : array(
899 + 'name' => 'frm_custom_css',
900 + 'id' => $id,
901 + );
770 902
903 + if ( $settings ) {
904 + $textarea_params['class'] = 'hide-if-js';
905 + }
906 +
771 907 include FrmAppHelper::plugin_path() . '/classes/views/styles/custom_css.php';
772 908 }
773 909
774 910 /**
@@ -775,22 +911,33 @@
775 911 * Get custom CSS code entered in the Custom CSS page.
776 912 *
777 913 * @since 6.0
778 914 *
915 + * @param array|null $single_style_settings The single style settings.
916 + *
779 917 * @return string
780 918 */
781 - public static function get_custom_css() {
919 + public static function get_custom_css( $single_style_settings = null ) {
920 + if ( $single_style_settings ) {
921 + // If the single style settings are passed, return the custom CSS from the single style settings.
922 + if ( ! empty( $single_style_settings['single_style_custom_css'] ) && ! empty( $single_style_settings['enable_style_custom_css'] ) ) {
923 + return $single_style_settings['single_style_custom_css'];
924 + }
925 +
926 + return '';
927 + }
928 +
782 929 $settings = FrmAppHelper::get_settings();
930 +
783 931 if ( is_string( $settings->custom_css ) ) {
784 932 return $settings->custom_css;
785 933 }
786 934
787 935 // If it does not exist, check the default style as a fallback.
788 - $frm_style = new FrmStyle();
789 - $style = $frm_style->get_default_style();
790 - $custom_css = $style->post_content['custom_css'];
936 + $frm_style = new FrmStyle();
937 + $style = $frm_style->get_default_style();
791 938
792 - return $custom_css;
939 + return $style->post_content['custom_css'];
793 940 }
794 941
795 942 /**
796 943 * Enqueue assets for codemirror, built into WordPress since 4.9.
@@ -797,11 +944,14 @@
797 944 * The Custom CSS page uses codemirror.
798 945 *
799 946 * @since 6.0 Previously this code was embedded in self::custom_css.
800 947 *
948 + * @param string $id The ID of the codemirror box.
949 + * @param string $placeholder The placeholder text for the codemirror box.
950 + *
801 951 * @return array|false
802 952 */
803 - private static function enqueue_codemirror() {
953 + private static function enqueue_codemirror( $id = 'frm_codemirror_box', $placeholder = '' ) {
804 954 if ( ! function_exists( 'wp_enqueue_code_editor' ) ) {
805 955 // The WordPress version is likely older than 4.9.
806 956 return false;
807 957 }
@@ -814,8 +964,9 @@
814 964 'tabSize' => 2,
815 965 // As the codemirror box only appears once you click into the Custom CSS tab, we need to auto-refresh.
816 966 // Otherwise the line numbers all end up with a 1px width causing overlap issues with the text in the content.
817 967 'autoRefresh' => true,
968 + 'placeholder' => $placeholder,
818 969 ),
819 970 )
820 971 );
821 972
@@ -822,9 +973,11 @@
822 973 if ( $settings ) {
823 974 wp_add_inline_script(
824 975 'code-editor',
825 976 sprintf(
826 - 'jQuery( function() { wp.codeEditor.initialize( \'frm_codemirror_box\', %s ); } );',
977 + 'jQuery( function() { window.%s_wp_editor = wp.codeEditor.initialize( \'%s\', %s ); } );',
978 + $id,
979 + $id,
827 980 wp_json_encode( $settings )
828 981 )
829 982 );
830 983 }
@@ -876,31 +1029,35 @@
876 1029 FrmAppHelper::permission_check( 'frm_change_settings' );
877 1030 check_ajax_referer( 'frm_ajax', 'nonce' );
878 1031
879 1032 $style_id = FrmAppHelper::get_post_param( 'style_id', '', 'absint' );
1033 +
880 1034 if ( ! $style_id ) {
881 1035 // A style ID is not sent when resetting on the edit page.
882 1036 // Instead of resetting the style, send the defaults back so the inputs can be updated with JavaScript.
883 1037 $frm_style = new FrmStyle();
884 - $defaults = $frm_style->get_defaults();
885 - echo json_encode( $defaults );
1038 + echo json_encode( $frm_style->get_defaults() );
886 1039 wp_die();
887 1040 }
888 1041
889 - $frm_style = new FrmStyle();
890 - $defaults = $frm_style->get_defaults();
891 - $default_post_content = FrmAppHelper::prepare_and_encode( $defaults );
892 - $where = array(
1042 + $frm_style = new FrmStyle();
1043 + $default_template_style = $frm_style->get_default_template_style( $style_id );
1044 + $where = array(
893 1045 'ID' => $style_id,
894 1046 'post_type' => self::$post_type,
895 1047 );
1048 +
1049 + $style_object = $frm_style->get_new();
1050 + $style_object->post_content = json_decode( $default_template_style, true );
1051 +
896 1052 global $wpdb;
897 - $wpdb->update( $wpdb->posts, array( 'post_content' => $default_post_content ), $where );
1053 + $wpdb->update( $wpdb->posts, array( 'post_content' => $default_template_style ), $where );
898 1054
899 - $frm_style->save_settings(); // Save the settings after resetting to default or the old style will still appear.
1055 + // Save the settings after resetting to default or the old style will still appear.
1056 + $frm_style->save_settings();
900 1057
901 1058 $data = array(
902 - 'style' => FrmStylesCardHelper::get_style_param_for_card( $frm_style->get_new() ),
1059 + 'style' => FrmStylesCardHelper::get_style_param_for_card( $style_object ),
903 1060 );
904 1061 wp_send_json_success( $data );
905 1062 wp_die();
906 1063 }
@@ -915,12 +1072,15 @@
915 1072 public static function change_styling() {
916 1073 FrmAppHelper::permission_check( 'frm_change_settings' );
917 1074 check_ajax_referer( 'frm_ajax', 'nonce' );
918 1075
919 - $frm_style = new FrmStyle();
920 - $defaults = false; // Intentionally avoid defaults here so nothing gets removed from our style.
921 - $style = '';
1076 + $is_loaded_via_ajax = true;
1077 + $frm_style = new FrmStyle();
922 1078
1079 + // Intentionally avoid defaults here so nothing gets removed from our style.
1080 + $defaults = array();
1081 + $style = '';
1082 +
923 1083 echo '<style type="text/css">';
924 1084 include FrmAppHelper::plugin_path() . '/css/_single_theme.css.php';
925 1085 echo '</style>';
926 1086 wp_die();
@@ -929,9 +1089,9 @@
929 1089 /**
930 1090 * @return void
931 1091 */
932 1092 public static function add_meta_boxes() {
933 - // setup meta boxes
1093 + // Setup meta boxes
934 1094 $meta_boxes = array(
935 1095 'general' => __( 'General', 'formidable' ),
936 1096 'form-title' => __( 'Form Title', 'formidable' ),
937 1097 'form-description' => __( 'Form Description', 'formidable' ),
@@ -961,8 +1121,9 @@
961 1121
962 1122 /**
963 1123 * @param array $atts
964 1124 * @param array $sec
1125 + *
965 1126 * @return void
966 1127 */
967 1128 public static function include_style_section( $atts, $sec ) {
968 1129 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
@@ -1025,9 +1186,9 @@
1025 1186 }
1026 1187
1027 1188 /**
1028 1189 * Add an extra style rule to hide a broken style warning.
1029 - * To avoid cluttering the front end with any unecessary styles this is only added when the referer URL matches the styler.
1190 + * To avoid cluttering the front end with any unnecessary styles this is only added when the referer URL matches the styler.
1030 1191 *
1031 1192 * @since 6.2.3
1032 1193 *
1033 1194 * @return void
@@ -1033,9 +1194,10 @@
1033 1194 * @return void
1034 1195 */
1035 1196 public static function maybe_hide_sample_form_error_message() {
1036 1197 $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
1037 - if ( false !== strpos( $referer, 'admin.php?page=formidable-styles' ) ) {
1198 +
1199 + if ( str_contains( $referer, 'admin.php?page=formidable-styles' ) ) {
1038 1200 echo '#frm_broken_styles_warning { display: none; }';
1039 1201 }
1040 1202 }
1041 1203
@@ -1044,8 +1206,9 @@
1044 1206 *
1045 1207 * @since 4.11.03
1046 1208 *
1047 1209 * @param string $css CSS content.
1210 + *
1048 1211 * @return string
1049 1212 */
1050 1213 public static function replace_relative_url( $css ) {
1051 1214 $plugin_url = trailingslashit( FrmAppHelper::plugin_url() );
@@ -1068,22 +1231,27 @@
1068 1231 * Check if the Formidable styling should be loaded,
1069 1232 * then enqueue it for the footer
1070 1233 *
1071 1234 * @since 2.0
1235 + *
1236 + * @return void
1072 1237 */
1073 1238 public static function enqueue_style() {
1074 1239 global $frm_vars;
1075 1240
1076 - if ( isset( $frm_vars['css_loaded'] ) && $frm_vars['css_loaded'] ) {
1241 + if ( ! empty( $frm_vars['css_loaded'] ) ) {
1077 1242 // The CSS has already been loaded.
1078 1243 return;
1079 1244 }
1080 1245
1081 1246 $frm_settings = FrmAppHelper::get_settings();
1082 - if ( $frm_settings->load_style != 'none' ) {
1083 - wp_enqueue_style( 'formidable' );
1084 - $frm_vars['css_loaded'] = true;
1247 +
1248 + if ( $frm_settings->load_style === 'none' ) {
1249 + return;
1085 1250 }
1251 +
1252 + wp_enqueue_style( 'formidable' );
1253 + $frm_vars['css_loaded'] = true;
1086 1254 }
1087 1255
1088 1256 /**
1089 1257 * Get the stylesheets for the form settings page
@@ -1091,23 +1259,23 @@
1091 1259 * @return array<WP_Post>
1092 1260 */
1093 1261 public static function get_style_opts() {
1094 1262 $frm_style = new FrmStyle();
1095 - $styles = $frm_style->get_all();
1096 -
1097 - return $styles;
1263 + return $frm_style->get_all();
1098 1264 }
1099 1265
1100 1266 /**
1101 1267 * Get the style post object for a target form.
1102 1268 *
1103 - * @param object|string|boolean $form
1269 + * @param bool|object|string $form
1270 + *
1104 1271 * @return WP_Post|null
1105 1272 */
1106 1273 public static function get_form_style( $form = 'default' ) {
1107 1274 $style = FrmFormsHelper::get_form_style( $form );
1108 1275
1109 - if ( empty( $style ) || 1 == $style ) {
1276 + // phpcs:ignore Universal.Operators.StrictComparisons
1277 + if ( ! $style || 1 == $style ) {
1110 1278 $style = 'default';
1111 1279 }
1112 1280
1113 1281 $frm_style = new FrmStyle( $style );
@@ -1114,12 +1282,59 @@
1114 1282 return $frm_style->get_one();
1115 1283 }
1116 1284
1117 1285 /**
1286 + * Get the active style object for a field's form.
1287 + *
1288 + * @since 6.32
1289 + *
1290 + * @param array|int $field The 'field' array.
1291 + *
1292 + * @return object
1293 + */
1294 + public static function get_active_style( $field ) {
1295 + if ( ! is_array( $field ) ) {
1296 + return new stdClass();
1297 + }
1298 +
1299 + $form_id = $field['parent_form_id'] ?? $field['form_id'];
1300 +
1301 + if ( isset( self::$active_style[ $form_id ] ) ) {
1302 + return self::$active_style[ $form_id ];
1303 + }
1304 +
1305 + $active_style = self::get_form_style( $form_id );
1306 +
1307 + if ( ! is_object( $active_style ) ) {
1308 + $active_style = new stdClass();
1309 + }
1310 +
1311 + self::$active_style[ $form_id ] = $active_style;
1312 +
1313 + return self::$active_style[ $form_id ];
1314 + }
1315 +
1316 + /**
1317 + * Get the style setting key that stores the alignment for a field type.
1318 + *
1319 + * @since 6.32
1320 + *
1321 + * @param string $field_type
1322 + *
1323 + * @return string
1324 + */
1325 + public static function get_align_key_for_style_settings( $field_type ) {
1326 + return 'checkbox' === $field_type ? 'check_align' : 'radio_align';
1327 + }
1328 +
1329 + /**
1118 1330 * @param string $class
1119 1331 * @param string $style
1332 + *
1333 + * @return string
1120 1334 */
1121 1335 public static function get_form_style_class( $class, $style ) {
1336 + // phpcs:ignore Universal.Operators.StrictComparisons
1122 1337 if ( 1 == $style ) {
1123 1338 $style = 'default';
1124 1339 }
1125 1340
@@ -1134,15 +1349,18 @@
1134 1349 return $class;
1135 1350 }
1136 1351
1137 1352 /**
1353 + * @since 3.0
1354 + *
1138 1355 * @param object $style
1139 1356 * @param string $class
1140 1357 *
1141 - * @since 3.0
1358 + * @return void
1142 1359 */
1143 1360 private static function maybe_add_rtl_class( $style, &$class ) {
1144 1361 $is_rtl = isset( $style->post_content['direction'] ) && 'rtl' === $style->post_content['direction'];
1362 +
1145 1363 if ( $is_rtl ) {
1146 1364 $class .= ' frm_rtl';
1147 1365 }
1148 1366 }
@@ -1147,17 +1365,28 @@
1147 1365 }
1148 1366 }
1149 1367
1150 1368 /**
1151 - * @param string $val
1369 + * @param string $val Style setting key.
1370 + * @param int|string $form Form ID or 'default'.
1371 + *
1372 + * @return mixed
1152 1373 */
1153 1374 public static function get_style_val( $val, $form = 'default' ) {
1154 1375 $style = self::get_form_style( $form );
1376 +
1155 1377 if ( $style && isset( $style->post_content[ $val ] ) ) {
1156 1378 return $style->post_content[ $val ];
1157 1379 }
1380 +
1381 + return null;
1158 1382 }
1159 1383
1384 + /**
1385 + * @param array $default_styles
1386 + *
1387 + * @return array
1388 + */
1160 1389 public static function show_entry_styles( $default_styles ) {
1161 1390 $frm_style = new FrmStyle( 'default' );
1162 1391 $style = $frm_style->get_one();
1163 1392
@@ -1166,13 +1395,15 @@
1166 1395 }
1167 1396
1168 1397 foreach ( $default_styles as $name => $val ) {
1169 1398 $setting = $name;
1170 - if ( 'border_width' == $name ) {
1399 +
1400 + if ( 'border_width' === $name ) {
1171 1401 $setting = 'field_border_width';
1172 - } elseif ( 'alt_bg_color' == $name ) {
1402 + } elseif ( 'alt_bg_color' === $name ) {
1173 1403 $setting = 'bg_color_active';
1174 1404 }
1405 +
1175 1406 $default_styles[ $name ] = $style->post_content[ $setting ];
1176 1407 unset( $name, $val );
1177 1408 }
1178 1409
@@ -1178,16 +1409,104 @@
1178 1409
1179 1410 return $default_styles;
1180 1411 }
1181 1412
1182 - public static function &important_style( $important, $field ) {
1183 - $important = self::get_style_val( 'important_style', $field['form_id'] );
1413 + /**
1414 + * @param string $important
1415 + * @param array $field
1416 + *
1417 + * @return string
1418 + */
1419 + public static function important_style( $important, $field ) {
1420 + return self::get_style_val( 'important_style', $field['form_id'] );
1421 + }
1184 1422
1185 - return $important;
1186 - }
1423 + /**
1424 + * Duplicate of WordPress do_accordion_section function, it adds an additional svg icon support.
1425 + *
1426 + * @since 6.8.3
1427 + *
1428 + * @param string|WP_Screen $screen Screen ID or screen object.
1429 + * @param string $context Meta box context.
1430 + * @param mixed $data_object Data object passed to callbacks.
1431 + *
1432 + * @return int
1433 + */
1434 + public static function do_accordion_sections( $screen, $context, $data_object ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
1435 + global $wp_meta_boxes;
1187 1436
1188 - public static function do_accordion_sections( $screen, $context, $object ) {
1189 - return do_accordion_sections( $screen, $context, $object );
1437 + // The symbol id from icons.svg
1438 + $icon_ids = array(
1439 + 'ranking-fields-style' => 'frm_chart_bar_icon',
1440 + 'section-fields-style' => 'frm-form-title-style',
1441 + );
1442 +
1443 + wp_enqueue_script( 'accordion' );
1444 +
1445 + if ( ! $screen ) {
1446 + $screen = get_current_screen();
1447 + } elseif ( is_string( $screen ) ) {
1448 + $screen = convert_to_screen( $screen );
1449 + }
1450 +
1451 + $page = $screen->id;
1452 +
1453 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
1454 + ?>
1455 + <div id="side-sortables" class="accordion-container">
1456 + <ul class="outer-border">
1457 + <?php
1458 + $i = 0;
1459 + $first_open = false;
1460 +
1461 + if ( isset( $wp_meta_boxes[ $page ][ $context ] ) ) {
1462 + foreach ( array( 'high', 'core', 'default', 'low' ) as $priority ) {
1463 + if ( ! isset( $wp_meta_boxes[ $page ][ $context ][ $priority ] ) ) {
1464 + continue;
1465 + }
1466 +
1467 + foreach ( $wp_meta_boxes[ $page ][ $context ][ $priority ] as $box ) {
1468 + if ( false === $box || ! $box['title'] ) {
1469 + continue;
1470 + }
1471 +
1472 + ++$i;
1473 + $icon_id = array_key_exists( $box['id'], $icon_ids ) ? $icon_ids[ $box['id'] ] : 'frm-' . $box['id'];
1474 + $open_class = '';
1475 +
1476 + if ( ! $first_open ) {
1477 + $first_open = true;
1478 + $open_class = 'open';
1479 + }
1480 +
1481 + $accordion_content_id = 'frm_style_section_' . $box['id'];
1482 + ?>
1483 + <li class="control-section accordion-section <?php echo esc_attr( $open_class ); ?> <?php echo esc_attr( $box['id'] ); ?>" id="<?php echo esc_attr( $box['id'] ); ?>"><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1484 + <h3 class="accordion-section-title hndle">
1485 + <?php
1486 + FrmAppHelper::icon_by_class( 'frmfont ' . $icon_id . ' frm_svg24' );
1487 + echo esc_html( $box['title'] );
1488 + ?>
1489 + <button type="button" aria-expanded="<?php echo esc_attr( 'open' === $open_class ? 'true' : 'false' ); ?>" aria-controls="<?php echo esc_attr( $accordion_content_id ); ?>" aria-label="<?php echo esc_attr( $box['title'] ); ?>"><?php // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong ?>
1490 + <?php FrmAppHelper::icon_by_class( 'frmfont frm_arrowdown8_icon' ); ?>
1491 + </button>
1492 + </h3>
1493 + <div class="accordion-section-content <?php postbox_classes( $box['id'], $page ); ?>" id="<?php echo esc_attr( $accordion_content_id ); ?>">
1494 + <div class="inside">
1495 + <?php call_user_func( $box['callback'], $data_object, $box ); ?>
1496 + </div><!-- .inside -->
1497 + </div><!-- .accordion-section-content -->
1498 + </li><!-- .accordion-section -->
1499 + <?php
1500 + }//end foreach
1501 + }//end foreach
1502 + }//end if
1503 + ?>
1504 + </ul><!-- .outer-border -->
1505 + </div><!-- .accordion-container -->
1506 + <?php
1507 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1508 + return $i;
1190 1509 }
1191 1510
1192 1511 /**
1193 1512 * Rename a style via an AJAX action.
@@ -1197,8 +1516,9 @@
1197 1516 * @return void
1198 1517 */
1199 1518 public static function rename_style() {
1200 1519 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'nonce', 'frm_ajax' );
1520 +
1201 1521 if ( $permission_error !== false ) {
1202 1522 $data = array(
1203 1523 'message' => __( 'Unable to rename style', 'formidable' ),
1204 1524 );
@@ -1217,8 +1537,9 @@
1217 1537 die();
1218 1538 }
1219 1539
1220 1540 $post = get_post( $style_id );
1541 +
1221 1542 if ( ! $post || $post->post_type !== self::$post_type ) {
1222 1543 $data = array(
1223 1544 'message' => __( 'The style you are renaming either does not exist or it is not a style', 'formidable' ),
1224 1545 );
@@ -1239,8 +1560,9 @@
1239 1560 *
1240 1561 * @since 6.0
1241 1562 *
1242 1563 * @param WP_Styles $styles
1564 + *
1243 1565 * @return void
1244 1566 */
1245 1567 public static function disable_conflicting_wp_admin_css( $styles ) {
1246 1568 if ( ! FrmAppHelper::is_style_editor_page() ) {