PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0
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 +171 -1152 6.355.0 View file →
@@ -3,36 +3,11 @@
3 3 die( 'You are not allowed to call this page directly.' );
4 4 }
5 5
6 6 class FrmStylesController {
7 -
8 - /**
9 - * @var string
10 - */
11 7 public static $post_type = 'frm_styles';
12 -
13 - /**
14 - * @var string
15 - */
16 8 public static $screen = 'formidable_page_formidable-styles';
17 9
18 - /**
19 - * @var string|null
20 - */
21 - private static $message;
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 - */
35 10 public static function load_pro_hooks() {
36 11 if ( FrmAppHelper::pro_is_installed() ) {
37 12 FrmProStylesController::load_pro_hooks();
38 13 }
@@ -37,11 +12,8 @@
37 12 FrmProStylesController::load_pro_hooks();
38 13 }
39 14 }
40 15
41 - /**
42 - * @return void
43 - */
44 16 public static function register_post_types() {
45 17 register_post_type(
46 18 self::$post_type,
47 19 array(
@@ -73,119 +45,45 @@
73 45 )
74 46 );
75 47 }
76 48
77 - /**
78 - * Add two links for the visual styler.
79 - * There's a "Styles" submenu in the Formidable menu.
80 - * There's a second alternative "Forms" submenu in the Appearance menu.
81 - * This submenu links to a page to edit a form with the default style.
82 - *
83 - * @return void
84 - */
85 49 public static function menu() {
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
50 + add_submenu_page( 'formidable', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Styles', 'formidable' ), 'frm_change_settings', 'formidable-styles', 'FrmStylesController::route' );
51 + add_submenu_page( 'themes.php', 'Formidable | ' . __( 'Styles', 'formidable' ), __( 'Forms', 'formidable' ), 'frm_change_settings', 'formidable-styles2', 'FrmStylesController::route' );
88 52 }
89 53
90 - /**
91 - * Remove filters for the visual styler preview.
92 - * This triggers earlier than self::admin_init which is called too late.
93 - *
94 - * @return void
95 - */
96 - public static function plugins_loaded() {
97 - if ( ! FrmAppHelper::is_style_editor_page() ) {
54 + public static function admin_init() {
55 + if ( ! FrmAppHelper::is_admin_page( 'formidable-styles' ) && ! FrmAppHelper::is_admin_page( 'formidable-styles2' ) ) {
98 56 return;
99 57 }
100 58
101 - self::disable_form_css();
102 - self::prevent_form_scripts_from_loading();
103 - }
59 + self::load_pro_hooks();
104 60
105 - /**
106 - * Avoid loading CSS the normal way with the preview in the styler.
107 - * It gets loaded instead with the frmpro_css action set to the #frm-custom-theme-css element.
108 - *
109 - * @since 6.0
110 - *
111 - * @return void
112 - */
113 - private static function disable_form_css() {
114 - add_filter( 'get_frm_stylesheet', '__return_empty_array' );
115 - }
116 -
117 - /**
118 - * Removing this action prevents front end JavaScript from loading.
119 - *
120 - * @since 6.0
121 - *
122 - * @return void
123 - */
124 - private static function prevent_form_scripts_from_loading() {
125 - remove_action( 'init', 'FrmFormsController::front_head' );
126 - }
127 -
128 - /**
129 - * @return void
130 - */
131 - public static function admin_init() {
132 - self::maybe_hook_into_global_settings_save();
133 -
134 - if ( ! FrmAppHelper::is_style_editor_page() ) {
61 + $style_tab = FrmAppHelper::get_param( 'frm_action', '', 'get', 'sanitize_title' );
62 + if ( $style_tab == 'manage' || $style_tab == 'custom_css' ) {
63 + // we only need to load these styles/scripts on the styler page
135 64 return;
136 65 }
137 66
138 - FrmStyleComponent::register_assets();
139 - self::load_pro_hooks();
140 -
141 67 $version = FrmAppHelper::plugin_version();
68 + wp_enqueue_script( 'jquery-ui-datepicker' );
69 + wp_enqueue_style( 'wp-color-picker' );
70 + wp_enqueue_style( 'frm-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_css' ), array(), $version );
142 71
143 - if ( FrmAppHelper::is_style_editor_page( 'edit' ) ) {
144 - wp_enqueue_style( 'wp-color-picker' );
145 - }
146 -
147 - wp_enqueue_style( 'frm-custom-theme', admin_url( 'admin-ajax.php?action=frmpro_css&frm_scope_custom_css=1' ), array(), $version );
148 -
149 72 $style = apply_filters( 'frm_style_head', false );
150 -
151 73 if ( $style ) {
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
74 + 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 );
153 75 }
154 76 }
155 77
156 78 /**
157 - * @since 6.0
158 - *
159 - * @return void
160 - */
161 - private static function maybe_hook_into_global_settings_save() {
162 - if ( empty( $_POST ) || ! isset( $_POST['style'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
163 - // Avoid changing any style data if the style array is not sent in the request.
164 - return;
165 - }
166 -
167 - add_action(
168 - 'frm_update_settings',
169 - /**
170 - * Update the form data on the "Manage Styles" tab after global settings are saved.
171 - */
172 - function () {
173 - self::manage_styles();
174 - }
175 - );
176 - }
177 -
178 - /**
179 79 * @param string $register Either 'enqueue' or 'register'.
180 80 * @param bool $force True to enqueue/register the style if a form has not been loaded.
181 - *
182 - * @return void
183 81 */
184 82 public static function enqueue_css( $register = 'enqueue', $force = false ) {
185 83 global $frm_vars;
186 84
187 - $register_css = $register === 'register';
85 + $register_css = ( $register == 'register' );
188 86 $should_load = $force || ( ( $frm_vars['load_css'] || $register_css ) && ! FrmAppHelper::is_admin() );
189 87
190 88 if ( ! $should_load ) {
191 89 return;
@@ -191,17 +89,17 @@
191 89 return;
192 90 }
193 91
194 92 $frm_settings = FrmAppHelper::get_settings();
195 -
196 - if ( $frm_settings->load_style === 'none' ) {
93 + if ( $frm_settings->load_style == 'none' ) {
197 94 return;
198 95 }
199 96
200 97 $css = apply_filters( 'get_frm_stylesheet', self::custom_stylesheet() );
201 98
202 - if ( $css ) {
203 - $css = (array) $css;
99 + if ( ! empty( $css ) ) {
100 + $css = (array) $css;
101 +
204 102 $version = FrmAppHelper::plugin_version();
205 103
206 104 foreach ( $css as $css_key => $file ) {
207 105 if ( $register_css ) {
@@ -208,34 +106,30 @@
208 106 $this_version = self::get_css_version( $css_key, $version );
209 107 wp_register_style( $css_key, $file, array(), $this_version );
210 108 }
211 109
212 - $load_on_all = ! FrmAppHelper::is_admin() && 'all' === $frm_settings->load_style;
213 -
214 - if ( $load_on_all || $register !== 'register' ) {
110 + $load_on_all = ! FrmAppHelper::is_admin() && 'all' == $frm_settings->load_style;
111 + if ( $load_on_all || $register != 'register' ) {
215 112 wp_enqueue_style( $css_key );
216 113 }
217 114 unset( $css_key, $file );
218 115 }
219 116
220 - if ( $frm_settings->load_style === 'all' ) {
117 + if ( $frm_settings->load_style == 'all' ) {
221 118 $frm_vars['css_loaded'] = true;
222 119 }
223 - }//end if
120 + }
224 121 unset( $css );
225 122
226 123 add_filter( 'style_loader_tag', 'FrmStylesController::add_tags_to_css', 10, 2 );
227 124 }
228 125
229 - /**
230 - * @return array<string,string>
231 - */
232 126 public static function custom_stylesheet() {
233 127 global $frm_vars;
234 128 $stylesheet_urls = array();
235 129
236 - if ( empty( $frm_vars['css_loaded'] ) ) {
237 - // Include css in head.
130 + if ( ! isset( $frm_vars['css_loaded'] ) || ! $frm_vars['css_loaded'] ) {
131 + //include css in head
238 132 self::get_url_to_custom_style( $stylesheet_urls );
239 133 }
240 134
241 135 return $stylesheet_urls;
@@ -240,24 +134,16 @@
240 134
241 135 return $stylesheet_urls;
242 136 }
243 137
244 - /**
245 - * @param array $stylesheet_urls
246 - *
247 - * @return void
248 - */
249 138 private static function get_url_to_custom_style( &$stylesheet_urls ) {
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;
139 + $file_name = '/css/' . self::get_file_name();
140 + if ( is_readable( FrmAppHelper::plugin_path() . $file_name ) ) {
141 + $url = FrmAppHelper::plugin_url() . $file_name;
142 + } else {
143 + $url = admin_url( 'admin-ajax.php?action=frmpro_css' );
256 144 }
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();
145 + $stylesheet_urls['formidable'] = $url;
260 146 }
261 147
262 148 /**
263 149 * Use a different stylesheet per site in a multisite install
@@ -262,735 +148,195 @@
262 148 /**
263 149 * Use a different stylesheet per site in a multisite install
264 150 *
265 151 * @since 3.0.03
266 - *
267 - * @return string
268 152 */
269 153 public static function get_file_name() {
270 154 if ( is_multisite() ) {
271 - return 'formidableforms' . absint( get_current_blog_id() ) . '.css';
155 + $blog_id = get_current_blog_id();
156 + $name = 'formidableforms' . absint( $blog_id ) . '.css';
157 + } else {
158 + $name = 'formidableforms.css';
272 159 }
273 160
274 - return 'formidableforms.css';
161 + return $name;
275 162 }
276 163
277 - /**
278 - * @param string $css_key
279 - * @param string $version
280 - *
281 - * @return string
282 - */
283 164 private static function get_css_version( $css_key, $version ) {
284 - if ( 'formidable' !== $css_key ) {
285 - return $version;
165 + if ( 'formidable' == $css_key ) {
166 + $this_version = get_option( 'frm_last_style_update' );
167 + if ( ! $this_version ) {
168 + $this_version = $version;
169 + }
170 + } else {
171 + $this_version = $version;
286 172 }
287 173
288 - $this_version = get_option( 'frm_last_style_update' );
289 -
290 - return $this_version ? $this_version : $version;
174 + return $this_version;
291 175 }
292 176
293 - /**
294 - * @param string $tag
295 - * @param string $handle
296 - *
297 - * @return string
298 - */
299 177 public static function add_tags_to_css( $tag, $handle ) {
300 - if ( ( 'formidable' === $handle || 'jquery-theme' === $handle ) && ! str_contains( $tag, ' property=' ) ) {
301 - return str_replace( ' type="', ' property="stylesheet" type="', $tag );
178 + if ( ( 'formidable' == $handle || 'jquery-theme' == $handle ) && strpos( $tag, ' property=' ) === false ) {
179 + $frm_settings = FrmAppHelper::get_settings();
180 + if ( $frm_settings->use_html ) {
181 + $tag = str_replace( ' type="', ' property="stylesheet" type="', $tag );
182 + }
302 183 }
303 184
304 185 return $tag;
305 186 }
306 187
307 - /**
308 - * Route the edit route to the style function.
309 - *
310 - * @since 6.0 this function no longer has any parameter values.
311 - *
312 - * @return void
313 - */
314 - public static function edit() {
315 - self::load_styler();
188 + public static function new_style( $return = '' ) {
189 + self::load_styler( 'default' );
316 190 }
317 191
318 - /**
319 - * When a new style route is hit, show a new style with the defaults. There is no ID yet, it is created after the first save event.
320 - *
321 - * @return void
322 - */
323 - public static function new_style() {
324 - self::load_styler();
325 - }
326 -
327 - /**
328 - * When the duplicate route is hit, it just shows the visual styler with a copy of the target style. There is no ID yet, it is created after the first save event.
329 - *
330 - * @return void
331 - */
332 192 public static function duplicate() {
333 - self::load_styler();
193 + self::load_styler( 'default' );
334 194 }
335 195
336 - /**
337 - * Render the style page for a form for assigning a style to a form, and for updating a target style.
338 - *
339 - * @since 6.0 this function no longer takes parameters.
340 - *
341 - * @return void
342 - */
343 - public static function load_styler() {
344 - if ( 'assign_style' === FrmAppHelper::get_post_param( 'frm_action' ) ) {
345 - self::save_form_style();
346 - }
347 -
348 - self::setup_styles_and_scripts_for_styler();
349 -
350 - $style_id = self::get_style_id_for_styler();
351 -
196 + public static function edit( $style_id = false, $message = '' ) {
352 197 if ( ! $style_id ) {
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;
360 - }
361 -
362 - $form_id = FrmAppHelper::simple_get( 'form', 'absint', 0 );
363 -
364 - if ( ! $form_id ) {
365 - $form_id = self::get_form_id_for_style( $style_id );
366 - }
367 -
368 - $form = FrmForm::getOne( $form_id );
369 -
370 - if ( ! is_object( $form ) ) {
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;
378 - }
379 -
380 - $frm_style = new FrmStyle( $style_id );
381 - $active_style = $frm_style->get_one();
382 -
383 - self::disable_admin_page_styling_on_submit_buttons();
384 -
385 - /**
386 - * @since 6.0
387 - *
388 - * @param array{form:\stdClass} $data
389 - */
390 - do_action( 'frm_before_render_style_page', compact( 'form' ) );
391 -
392 - self::render_style_page( $active_style, $form, self::get_default_style() );
393 - }
394 -
395 - /**
396 - * @since 6.0
397 - *
398 - * @return int
399 - */
400 - private static function get_style_id_for_styler() {
401 - $action = FrmAppHelper::simple_get( 'frm_action' );
402 -
403 - if ( 'duplicate' === $action ) {
404 - // The duplicate action uses style_id instead of id for better backward compatibility.
405 - return FrmAppHelper::simple_get( 'style_id', 'absint', 0 );
406 - }
407 -
408 - $style_id = FrmAppHelper::simple_get( 'id', 'absint', 0 );
409 -
410 - if ( $style_id ) {
411 - // Always use the style ID from the URL if one is specified.
412 - return $style_id;
413 - }
414 -
415 - $request_form_id = FrmAppHelper::simple_get( 'form', 'absint', 0 );
416 -
417 - if ( $request_form_id && is_callable( 'FrmProStylesController::get_active_style_for_form' ) ) {
418 - return FrmProStylesController::get_active_style_for_form( $request_form_id )->ID;
419 - }
420 -
421 - return self::get_default_style()->ID;
422 - }
423 -
424 - /**
425 - * If a form ID is not being passed in the URL, try to get the best match.
426 - *
427 - * @since 6.0
428 - *
429 - * @param int $style_id
430 - *
431 - * @return int
432 - */
433 - private static function get_form_id_for_style( $style_id ) {
434 - $check = serialize( array( 'custom_style' => (string) $style_id ) );
435 - $check = substr( $check, 5, -1 );
436 - $form_id = FrmDb::get_var(
437 - 'frm_forms',
438 - array(
439 - 'options LIKE' => $check,
440 - 'status' => 'published',
441 - )
442 - );
443 -
444 - if ( ! $form_id ) {
445 - // Fallback to any form.
446 - $where = array(
447 - 'status' => 'published',
448 - // Make sure it's not a repeater.
449 - 'parent_form_id' => array( null, 0 ),
450 - );
451 - $form_id = FrmDb::get_var( 'frm_forms', $where, 'id' );
452 - }
453 -
454 - return $form_id;
455 - }
456 -
457 - /**
458 - * Add a frm_no_style_button class to all buttons to avoid some style rules like border-radius: 30px.
459 - *
460 - * @return void
461 - */
462 - private static function disable_admin_page_styling_on_submit_buttons() {
463 - add_filter(
464 - 'frm_submit_button_class',
465 - function ( $classes ) {
466 - $classes[] = 'frm_no_style_button';
467 - return $classes;
198 + $style_id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
199 + if ( empty( $style_id ) ) {
200 + $style_id = 'default';
468 201 }
469 - );
470 - }
471 -
472 - /**
473 - * @since 6.0
474 - *
475 - * @return WP_Post
476 - */
477 - private static function get_default_style() {
478 - $frm_style = new FrmStyle( 'default' );
479 - return $frm_style->get_one();
480 - }
481 -
482 - /**
483 - * Save style for form (from Styler list page) via a POST action.
484 - *
485 - * @since 6.0
486 - *
487 - * @return void
488 - */
489 - private static function save_form_style() {
490 - $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'frm_save_form_style', 'frm_save_form_style_nonce' );
491 -
492 - if ( $permission_error !== false ) {
493 - wp_die( 'Unable to save form', '', 403 );
494 202 }
495 203
496 - $style_id = FrmAppHelper::get_post_param( 'style_id', 0, 'absint' );
497 -
498 - if ( $style_id && ! self::confirm_style_exists_before_setting( $style_id ) ) {
499 - wp_die( esc_html__( 'Invalid target style', 'formidable' ), esc_html__( 'Invalid target style', 'formidable' ), 400 );
500 - return;
204 + if ( 'default' == $style_id ) {
205 + $style = 'default';
206 + } else {
207 + $frm_style = new FrmStyle( $style_id );
208 + $style = $frm_style->get_one();
209 + $style = $style->ID;
501 210 }
502 211
503 - /**
504 - * Hook into the saved style ID so Pro can import a style template by its key and return a new style ID.
505 - *
506 - * @since 6.0
507 - *
508 - * @param int $style_id
509 - */
510 - $style_id = apply_filters( 'frm_saved_form_style_id', $style_id );
511 -
512 - if ( ! $style_id && '0' !== FrmAppHelper::get_post_param( 'style_id', '', 'sanitize_text_field' ) ) {
513 - // "0" is a special value used for the enable/disable toggle.
514 - wp_die( esc_html__( 'Invalid style value', 'formidable' ), esc_html__( 'Invalid style value', 'formidable' ), 400 );
515 - return;
516 - }
517 -
518 - $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
519 -
520 - if ( ! $form_id ) {
521 - wp_die( esc_html__( 'No form specified', 'formidable' ), esc_html__( 'No form specified', 'formidable' ), 400 );
522 - return;
523 - }
524 -
525 - $form = FrmForm::getOne( $form_id );
526 -
527 - if ( ! $form ) {
528 - wp_die( esc_html__( 'Form does not exist', 'formidable' ), esc_html__( 'Form does not exist', 'formidable' ), 400 );
529 - return;
530 - }
531 -
532 - $previous_style_id = $form->options['custom_style'];
533 -
534 - // If the default style is selected, use the "Always use default" legacy option instead of the default style.
535 - // There's also a check here for conversational forms.
536 - // Without the check it isn't possible to select "Default" because "Always use default" will convert to "Lines" dynamically.
537 -
538 - if ( $style_id === self::get_default_style()->ID && empty( $form->options['chat'] ) ) {
539 - $style_id = 1;
540 - }
541 -
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;
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 -
551 - global $wpdb;
552 - $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $form->options ) ), array( 'id' => $form->id ) );
553 -
554 - FrmForm::clear_form_cache();
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 -
564 - self::$message = __( 'Successfully updated style.', 'formidable' );
212 + self::load_styler( $style, $message );
565 213 }
566 214
567 - /**
568 - * Validate that we're assigning a form to a style that actually exists before assigning it to a form.
569 - *
570 - * @param int $style_id
571 - *
572 - * @return bool True if the style actually exists.
573 - */
574 - private static function confirm_style_exists_before_setting( $style_id ) {
575 - global $wpdb;
576 - $post_type = FrmDb::get_var( $wpdb->posts, array( 'ID' => $style_id ), 'post_type' );
577 - return self::$post_type === $post_type;
578 - }
579 -
580 - /**
581 - * Register and enqueue styles and scripts for the style tab page.
582 - *
583 - * @since 6.0
584 - *
585 - * @return void
586 - */
587 - private static function setup_styles_and_scripts_for_styler() {
588 - $plugin_url = FrmAppHelper::plugin_url();
589 - $version = FrmAppHelper::plugin_version();
590 - $js_dependencies = array( 'wp-i18n', 'wp-hooks', 'formidable_dom' );
591 -
592 - if ( FrmAppHelper::pro_is_installed() && is_callable( 'FrmProAppHelper::use_jquery_datepicker' ) && FrmProAppHelper::use_jquery_datepicker() ) {
593 - $js_dependencies[] = 'jquery-ui-datepicker';
594 - }
595 -
596 - wp_register_script( 'formidable_style', $plugin_url . '/js/admin/style.js', $js_dependencies, $version );
597 - wp_register_style( 'formidable_style', $plugin_url . '/css/admin/style.css', array(), $version );
598 - wp_print_styles( 'formidable_style' );
599 -
600 - wp_print_styles( 'formidable' );
601 - wp_enqueue_script( 'formidable_style' );
602 - wp_set_script_translations( 'formidable_style', 'formidable' );
603 - }
604 -
605 - /**
606 - * Render the style page (with a more limited and typed scope than calling it from self::style directly).
607 - *
608 - * @since 6.0
609 - *
610 - * @param stdClass|WP_Post $active_style
611 - * @param stdClass $form
612 - * @param WP_Post $default_style
613 - *
614 - * @return void
615 - */
616 - private static function render_style_page( $active_style, $form, $default_style ) {
617 - $style_views_path = self::get_views_path();
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 );
621 -
622 - if ( 'new_style' !== $view && ! FrmAppHelper::simple_get( 'form' ) && ! FrmAppHelper::simple_get( 'style_id' ) ) {
623 - // Have the Appearance > Forms link fallback to the edit view. Otherwise we want to use 'list' as the default.
624 - $view = 'edit';
625 - }
626 -
627 - if ( in_array( $view, array( 'edit', 'new_style', 'duplicate' ), true ) ) {
628 - self::add_meta_boxes();
629 - }
630 -
631 - switch ( $view ) {
632 - case 'edit':
633 - $style = $active_style;
634 - break;
635 -
636 - case 'duplicate':
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 -
649 - $style->ID = $new_style->ID;
650 - $style->post_name = $new_name;
651 - unset( $new_style, $new_name );
652 - break;
653 -
654 - case 'new_style':
655 - $style = $frm_style->get_new();
656 - $style->post_name = self::get_new_style_post_name( $style->post_name );
657 - break;
658 - }//end switch
659 -
660 - if ( in_array( $view, array( 'duplicate', 'new_style' ), true ) ) {
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' );
673 - $style->menu_order = 0;
674 - }
675 -
676 - if ( ! isset( $style ) ) {
677 - $style = $active_style;
678 - }
679 -
680 - self::force_form_style( $style );
681 -
682 - if ( isset( self::$message ) ) {
683 - $message = self::$message;
684 - }
685 -
686 - $preview_helper = new FrmStylesPreviewHelper( $form->id );
687 - $preview_helper->adjust_form_for_preview();
688 -
689 - // Get form HTML before displaying warnings and notes so we can check global $frm_vars data without adding extra database calls.
690 - $target_form_preview_html = $preview_helper->get_html_for_form_preview();
691 - $warnings = $preview_helper->get_warnings_for_styler_preview( $style, $default_style, $view );
692 - $notes = $preview_helper->get_notes_for_styler_preview();
693 -
694 - include $style_views_path . 'show.php';
695 - }
696 -
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 - /**
717 - * @since 6.0
718 - *
719 - * @return string
720 - */
721 - private static function get_views_path() {
722 - return FrmAppHelper::plugin_path() . '/classes/views/styles/';
723 - }
724 -
725 - /**
726 - * Filter form classes so the form uses the preview style, not the form's active style.
727 - *
728 - * @since 6.0
729 - *
730 - * @param stdClass|WP_Post $style A new style is not a WP_Post object.
731 - *
732 - * @return void
733 - */
734 - private static function force_form_style( $style ) {
735 - add_filter(
736 - 'frm_add_form_style_class',
737 - function ( $class ) use ( $style ) {
738 - $split = array_filter(
739 - explode( ' ', $class ),
740 - /**
741 - * @param string $class
742 - */
743 - function ( $class ) {
744 - return $class && ! str_starts_with( $class, 'frm_style_' );
745 - }
746 - );
747 - $split[] = 'frm_style_' . $style->post_name;
748 - return implode( ' ', $split );
749 - }
750 - );
751 - }
752 -
753 - /**
754 - * Save style post object via a POST request submitted from the Visual styler "edit" page.
755 - *
756 - * @since 6.0
757 - *
758 - * @return void
759 - */
760 - public static function save_style() {
761 - FrmAppHelper::permission_check( 'frm_change_settings' );
762 -
215 + public static function save() {
763 216 $frm_style = new FrmStyle();
217 + $message = '';
764 218 $post_id = FrmAppHelper::get_post_param( 'ID', false, 'sanitize_title' );
765 219 $style_nonce = FrmAppHelper::get_post_param( 'frm_style', '', 'sanitize_text_field' );
766 220
767 - if ( $post_id === false || ! wp_verify_nonce( $style_nonce, 'frm_style_nonce' ) ) {
768 - // Exit early if the request isn't valid.
769 - // Since we're not dying, it should just reload the visual styler without any message.
770 - return;
221 + if ( $post_id !== false && wp_verify_nonce( $style_nonce, 'frm_style_nonce' ) ) {
222 + $id = $frm_style->update( $post_id );
223 + if ( empty( $post_id ) && ! empty( $id ) ) {
224 + // set the post id to the new style so it will be loaded for editing
225 + $post_id = reset( $id );
226 + }
227 + // include the CSS that includes this style
228 + echo '<link href="' . esc_url( admin_url( 'admin-ajax.php?action=frmpro_css' ) ) . '" type="text/css" rel="Stylesheet" class="frm-custom-theme" />';
229 + $message = __( 'Your styling settings have been saved.', 'formidable' );
771 230 }
772 231
773 - $id = $frm_style->update( $post_id );
774 -
775 - if ( ! $post_id && $id ) {
776 - self::maybe_redirect_after_save( $id );
777 - // Set the post id to the new style so it will be loaded for editing.
778 - $post_id = reset( $id );
779 - }
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 -
788 - self::$message = __( 'Your styling settings have been saved.', 'formidable' );
232 + return self::edit( $post_id, $message );
789 233 }
790 234
791 - /**
792 - * Show the edit view after saving.
793 - * The save event is triggered earlier, on admin init where self::save_style is called.
794 - * This happens earlier because there is a possible redirect (to adjust the URL for a new or duplicated style).
795 - *
796 - * @return void
797 - */
798 - public static function save() {
799 - self::edit();
800 - }
235 + public static function load_styler( $style, $message = '' ) {
236 + global $frm_settings;
801 237
802 - /**
803 - * Force a redirect after duplicating or creating a new style to avoid an old stale URL that could result in more styles than intended.
804 - *
805 - * @since 6.0
806 - *
807 - * @param array $ids
808 - *
809 - * @return void
810 - */
811 - private static function maybe_redirect_after_save( $ids ) {
812 - $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
813 - $parsed = parse_url( $referer );
814 - $query = $parsed['query'];
815 - $current_action = false;
816 - $actions_to_redirect = array( 'duplicate', 'new_style' );
238 + $frm_style = new FrmStyle();
239 + $styles = $frm_style->get_all();
817 240
818 - foreach ( $actions_to_redirect as $action ) {
819 - if ( str_contains( $query, 'frm_action=' . $action ) ) {
820 - $current_action = $action;
821 - break;
822 - }
241 + if ( is_numeric( $style ) ) {
242 + $style = $styles[ $style ];
243 + } elseif ( 'default' == $style ) {
244 + $style = $frm_style->get_default_style( $styles );
823 245 }
824 246
825 - if ( false === $current_action ) {
826 - // Do not redirect as the referer URL did not match $actions_to_redirect.
827 - return;
828 - }
247 + self::add_meta_boxes();
829 248
830 - parse_str( $query, $parsed_query );
831 - $form_id = ! empty( $parsed_query['form'] ) ? absint( $parsed_query['form'] ) : 0;
832 - $style = new stdClass();
833 - $style->ID = end( $ids );
834 - wp_safe_redirect( esc_url_raw( FrmStylesHelper::get_edit_url( $style, $form_id ) ) );
835 - die();
249 + include( FrmAppHelper::plugin_path() . '/classes/views/styles/show.php' );
836 250 }
837 251
838 252 /**
839 - * @since 6.0
840 - *
841 - * @param string $message
253 + * @param string $message
842 254 * @param array|object $forms
843 - *
844 - * @return void
845 255 */
846 - public static function manage( $message = '', $forms = array() ) {
256 + private static function manage( $message = '', $forms = array() ) {
847 257 $frm_style = new FrmStyle();
848 258 $styles = $frm_style->get_all();
849 259 $default_style = $frm_style->get_default_style( $styles );
850 - $frm_settings = FrmAppHelper::get_settings();
851 260
852 - if ( ! $forms ) {
261 + if ( empty( $forms ) ) {
853 262 $forms = FrmForm::get_published_forms();
854 263 }
855 264
856 - include FrmAppHelper::plugin_path() . '/classes/views/styles/manage.php';
265 + include( FrmAppHelper::plugin_path() . '/classes/views/styles/manage.php' );
857 266 }
858 267
859 - /**
860 - * Handle saving for the page rendered in self::manage which is included in Global Settings in the "Manage Styles" tab.
861 - * This gets called from the frm_update_settings hook which is called after saving Global settings.
862 - *
863 - * @return void
864 - */
865 268 private static function manage_styles() {
269 + $style_nonce = FrmAppHelper::get_post_param( 'frm_manage_style', '', 'sanitize_text_field' );
270 + if ( ! $_POST || ! isset( $_POST['style'] ) || ! wp_verify_nonce( $style_nonce, 'frm_manage_style_nonce' ) ) {
271 + return self::manage();
272 + }
273 +
866 274 global $wpdb;
867 275
868 276 $forms = FrmForm::get_published_forms();
869 -
870 277 foreach ( $forms as $form ) {
871 - if ( ! isset( $_POST['style'] ) || ! isset( $_POST['style'][ $form->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
278 + $new_style = ( isset( $_POST['style'] ) && isset( $_POST['style'][ $form->id ] ) ) ? sanitize_text_field( wp_unslash( $_POST['style'][ $form->id ] ) ) : '';
279 + $previous_style = ( isset( $_POST['prev_style'] ) && isset( $_POST['prev_style'][ $form->id ] ) ) ? sanitize_text_field( wp_unslash( $_POST['prev_style'][ $form->id ] ) ) : '';
280 + if ( $new_style == $previous_style ) {
872 281 continue;
873 282 }
874 283
875 - $new_style = sanitize_text_field( wp_unslash( $_POST['style'][ $form->id ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
284 + $form->options['custom_style'] = $new_style;
876 285
877 - $form->options['custom_style'] = $new_style;
878 286 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $form->options ) ), array( 'id' => $form->id ) );
879 287 unset( $form );
880 288 }
881 - }
882 289
883 - /**
884 - * Echo content for the Custom CSS page.
885 - *
886 - * @param string $message
887 - * @param array $extra_args An array of extra arguments.
888 - *
889 - * @return void
890 - */
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 - );
290 + $message = __( 'Your form styles have been saved.', 'formidable' );
902 291
903 - if ( $settings ) {
904 - $textarea_params['class'] = 'hide-if-js';
905 - }
906 -
907 - include FrmAppHelper::plugin_path() . '/classes/views/styles/custom_css.php';
292 + return self::manage( $message, $forms );
908 293 }
909 294
910 - /**
911 - * Get custom CSS code entered in the Custom CSS page.
912 - *
913 - * @since 6.0
914 - *
915 - * @param array|null $single_style_settings The single style settings.
916 - *
917 - * @return string
918 - */
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 '';
295 + public static function custom_css( $message = '', $style = null ) {
296 + if ( function_exists( 'wp_enqueue_code_editor' ) ) {
297 + $id = 'frm_codemirror_box';
298 + $settings = wp_enqueue_code_editor(
299 + array(
300 + 'type' => 'text/css',
301 + 'codemirror' => array(
302 + 'indentUnit' => 2,
303 + 'tabSize' => 2,
304 + ),
305 + )
306 + );
307 + } else {
308 + _deprecated_function( 'Codemirror v4.7', 'WordPress 4.9', 'Update WordPress' );
309 + $id = 'frm_custom_css_box';
310 + $settings = array();
311 + $codemirror = '4.7';
312 + wp_enqueue_style( 'codemirror', FrmAppHelper::plugin_url() . '/css/codemirror.css', array(), $codemirror );
313 + wp_enqueue_script( 'codemirror', FrmAppHelper::plugin_url() . '/js/codemirror/codemirror.js', array(), $codemirror );
314 + wp_enqueue_script( 'codemirror-css', FrmAppHelper::plugin_url() . '/js/codemirror/css.js', array( 'codemirror' ), $codemirror );
927 315 }
928 316
929 - $settings = FrmAppHelper::get_settings();
930 -
931 - if ( is_string( $settings->custom_css ) ) {
932 - return $settings->custom_css;
317 + if ( ! isset( $style ) ) {
318 + $frm_style = new FrmStyle();
319 + $style = $frm_style->get_default_style();
933 320 }
934 321
935 - // If it does not exist, check the default style as a fallback.
936 - $frm_style = new FrmStyle();
937 - $style = $frm_style->get_default_style();
938 -
939 - return $style->post_content['custom_css'];
322 + include( FrmAppHelper::plugin_path() . '/classes/views/styles/custom_css.php' );
940 323 }
941 324
942 - /**
943 - * Enqueue assets for codemirror, built into WordPress since 4.9.
944 - * The Custom CSS page uses codemirror.
945 - *
946 - * @since 6.0 Previously this code was embedded in self::custom_css.
947 - *
948 - * @param string $id The ID of the codemirror box.
949 - * @param string $placeholder The placeholder text for the codemirror box.
950 - *
951 - * @return array|false
952 - */
953 - private static function enqueue_codemirror( $id = 'frm_codemirror_box', $placeholder = '' ) {
954 - if ( ! function_exists( 'wp_enqueue_code_editor' ) ) {
955 - // The WordPress version is likely older than 4.9.
956 - return false;
957 - }
325 + public static function save_css() {
326 + $frm_style = new FrmStyle();
958 327
959 - $settings = wp_enqueue_code_editor(
960 - array(
961 - 'type' => 'text/css',
962 - 'codemirror' => array(
963 - 'indentUnit' => 2,
964 - 'tabSize' => 2,
965 - // As the codemirror box only appears once you click into the Custom CSS tab, we need to auto-refresh.
966 - // Otherwise the line numbers all end up with a 1px width causing overlap issues with the text in the content.
967 - 'autoRefresh' => true,
968 - 'placeholder' => $placeholder,
969 - ),
970 - )
971 - );
972 -
973 - if ( $settings ) {
974 - wp_add_inline_script(
975 - 'code-editor',
976 - sprintf(
977 - 'jQuery( function() { window.%s_wp_editor = wp.codeEditor.initialize( \'%s\', %s ); } );',
978 - $id,
979 - $id,
980 - wp_json_encode( $settings )
981 - )
982 - );
328 + $message = '';
329 + $post_id = FrmAppHelper::get_post_param( 'ID', false, 'sanitize_text_field' );
330 + $nonce = FrmAppHelper::get_post_param( 'frm_custom_css', '', 'sanitize_text_field' );
331 + if ( wp_verify_nonce( $nonce, 'frm_custom_css_nonce' ) ) {
332 + $frm_style->update( $post_id );
333 + $message = __( 'Your styling settings have been saved.', 'formidable' );
983 334 }
984 335
985 - return $settings;
336 + return self::custom_css( $message );
986 337 }
987 338
988 - /**
989 - * Handling routing for the visual styler.
990 - *
991 - * @return void
992 - */
993 339 public static function route() {
994 340 $action = FrmAppHelper::get_param( 'frm_action', '', 'get', 'sanitize_title' );
995 341 FrmAppHelper::include_svg();
996 342
@@ -996,102 +342,54 @@
996 342
997 343 switch ( $action ) {
998 344 case 'edit':
999 345 case 'save':
1000 - self::$action();
1001 - return;
346 + case 'manage':
347 + case 'manage_styles':
348 + case 'custom_css':
349 + case 'save_css':
350 + return self::$action();
1002 351 default:
1003 352 do_action( 'frm_style_action_route', $action );
1004 -
1005 353 if ( apply_filters( 'frm_style_stop_action_route', false, $action ) ) {
1006 354 return;
1007 355 }
1008 356
1009 - if ( in_array( $action, array( 'new_style', 'duplicate' ), true ) ) {
1010 - self::$action();
1011 - return;
357 + if ( 'new_style' == $action || 'duplicate' == $action ) {
358 + return self::$action();
1012 359 }
1013 360
1014 - self::edit();
1015 - return;
361 + return self::edit();
1016 362 }
1017 363 }
1018 364
1019 - /**
1020 - * Handle AJAX routing for frm_settings_reset for resetting styles to the default settings.
1021 - * From the edit view, it will return default styles and not actually update the style.
1022 - * On the list view, it does update the style immediately, and returns the default card style attributes so the style card can be reset as well.
1023 - *
1024 - * @since 6.0 When a style_id is passed to this action, the style will actually be reset.
1025 - *
1026 - * @return void
1027 - */
1028 365 public static function reset_styling() {
1029 366 FrmAppHelper::permission_check( 'frm_change_settings' );
1030 367 check_ajax_referer( 'frm_ajax', 'nonce' );
1031 368
1032 - $style_id = FrmAppHelper::get_post_param( 'style_id', '', 'absint' );
369 + $frm_style = new FrmStyle();
370 + $defaults = $frm_style->get_defaults();
1033 371
1034 - if ( ! $style_id ) {
1035 - // A style ID is not sent when resetting on the edit page.
1036 - // Instead of resetting the style, send the defaults back so the inputs can be updated with JavaScript.
1037 - $frm_style = new FrmStyle();
1038 - echo json_encode( $frm_style->get_defaults() );
1039 - wp_die();
1040 - }
1041 -
1042 - $frm_style = new FrmStyle();
1043 - $default_template_style = $frm_style->get_default_template_style( $style_id );
1044 - $where = array(
1045 - 'ID' => $style_id,
1046 - 'post_type' => self::$post_type,
1047 - );
1048 -
1049 - $style_object = $frm_style->get_new();
1050 - $style_object->post_content = json_decode( $default_template_style, true );
1051 -
1052 - global $wpdb;
1053 - $wpdb->update( $wpdb->posts, array( 'post_content' => $default_template_style ), $where );
1054 -
1055 - // Save the settings after resetting to default or the old style will still appear.
1056 - $frm_style->save_settings();
1057 -
1058 - $data = array(
1059 - 'style' => FrmStylesCardHelper::get_style_param_for_card( $style_object ),
1060 - );
1061 - wp_send_json_success( $data );
372 + echo json_encode( $defaults );
1062 373 wp_die();
1063 374 }
1064 375
1065 - /**
1066 - * Handle routing for the frm_change_styling AJAX action.
1067 - * This doesn't actually change styling. It just handles the events when someone changes a style.
1068 - * It responds with the new CSS required for the updated styler preview in the edit page.
1069 - *
1070 - * @return void
1071 - */
1072 376 public static function change_styling() {
1073 - FrmAppHelper::permission_check( 'frm_change_settings' );
1074 377 check_ajax_referer( 'frm_ajax', 'nonce' );
1075 378
1076 - $is_loaded_via_ajax = true;
1077 - $frm_style = new FrmStyle();
379 + $frm_style = new FrmStyle();
380 + $defaults = $frm_style->get_defaults();
381 + $style = '';
1078 382
1079 - // Intentionally avoid defaults here so nothing gets removed from our style.
1080 - $defaults = array();
1081 - $style = '';
1082 -
1083 383 echo '<style type="text/css">';
1084 - include FrmAppHelper::plugin_path() . '/css/_single_theme.css.php';
384 + include( FrmAppHelper::plugin_path() . '/css/_single_theme.css.php' );
1085 385 echo '</style>';
1086 386 wp_die();
1087 387 }
1088 388
1089 - /**
1090 - * @return void
1091 - */
1092 - public static function add_meta_boxes() {
1093 - // Setup meta boxes
389 + private static function add_meta_boxes() {
390 +
391 + // setup meta boxes
1094 392 $meta_boxes = array(
1095 393 'general' => __( 'General', 'formidable' ),
1096 394 'form-title' => __( 'Form Title', 'formidable' ),
1097 395 'form-description' => __( 'Form Description', 'formidable' ),
@@ -1107,10 +405,8 @@
1107 405 /**
1108 406 * Add custom boxes to the styling settings
1109 407 *
1110 408 * @since 2.3
1111 - *
1112 - * @param array $meta_boxes
1113 409 */
1114 410 $meta_boxes = apply_filters( 'frm_style_boxes', $meta_boxes );
1115 411
1116 412 foreach ( $meta_boxes as $nicename => $name ) {
@@ -1118,14 +414,8 @@
1118 414 unset( $nicename, $name );
1119 415 }
1120 416 }
1121 417
1122 - /**
1123 - * @param array $atts
1124 - * @param array $sec
1125 - *
1126 - * @return void
1127 - */
1128 418 public static function include_style_section( $atts, $sec ) {
1129 419 extract( $atts ); // phpcs:ignore WordPress.PHP.DontExtract
1130 420 $style = $atts['style'];
1131 421 FrmStylesHelper::prepare_color_output( $style->post_content, false );
@@ -1142,9 +432,9 @@
1142 432 */
1143 433 $file_name = apply_filters( 'frm_style_settings_' . $sec['args'], $file_name );
1144 434
1145 435 echo '<div class="frm_grid_container">';
1146 - include $file_name;
436 + include( $file_name );
1147 437 echo '</div>';
1148 438 }
1149 439
1150 440 public static function load_css() {
@@ -1153,62 +443,30 @@
1153 443 $frm_style = new FrmStyle();
1154 444 $defaults = $frm_style->get_defaults();
1155 445 $style = '';
1156 446
1157 - include FrmAppHelper::plugin_path() . '/css/_single_theme.css.php';
447 + include( FrmAppHelper::plugin_path() . '/css/_single_theme.css.php' );
1158 448 wp_die();
1159 449 }
1160 450
1161 - /**
1162 - * @return void
1163 - */
1164 451 public static function load_saved_css() {
1165 452 $css = get_transient( 'frmpro_css' );
1166 453
1167 454 ob_start();
1168 - include FrmAppHelper::plugin_path() . '/css/custom_theme.css.php';
455 + include( FrmAppHelper::plugin_path() . '/css/custom_theme.css.php' );
1169 456 $output = ob_get_clean();
1170 - $output = self::replace_relative_url( $output );
1171 457
1172 - /**
1173 - * The API needs to load font icons through a custom URL.
1174 - *
1175 - * @since 5.2
1176 - *
1177 - * @param string $output
1178 - */
1179 - $output = apply_filters( 'frm_saved_css', $output );
458 + echo self::replace_relative_url( $output ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1180 459
1181 - echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1182 -
1183 - self::maybe_hide_sample_form_error_message();
1184 -
1185 460 wp_die();
1186 461 }
1187 462
1188 463 /**
1189 - * Add an extra style rule to hide a broken style warning.
1190 - * To avoid cluttering the front end with any unnecessary styles this is only added when the referer URL matches the styler.
1191 - *
1192 - * @since 6.2.3
1193 - *
1194 - * @return void
1195 - */
1196 - public static function maybe_hide_sample_form_error_message() {
1197 - $referer = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
1198 -
1199 - if ( str_contains( $referer, 'admin.php?page=formidable-styles' ) ) {
1200 - echo '#frm_broken_styles_warning { display: none; }';
1201 - }
1202 - }
1203 -
1204 - /**
1205 464 * Replaces relative URL with absolute URL.
1206 465 *
1207 466 * @since 4.11.03
1208 467 *
1209 468 * @param string $css CSS content.
1210 - *
1211 469 * @return string
1212 470 */
1213 471 public static function replace_relative_url( $css ) {
1214 472 $plugin_url = trailingslashit( FrmAppHelper::plugin_url() );
@@ -1231,110 +489,51 @@
1231 489 * Check if the Formidable styling should be loaded,
1232 490 * then enqueue it for the footer
1233 491 *
1234 492 * @since 2.0
1235 - *
1236 - * @return void
1237 493 */
1238 494 public static function enqueue_style() {
1239 495 global $frm_vars;
1240 496
1241 - if ( ! empty( $frm_vars['css_loaded'] ) ) {
497 + if ( isset( $frm_vars['css_loaded'] ) && $frm_vars['css_loaded'] ) {
1242 498 // The CSS has already been loaded.
1243 499 return;
1244 500 }
1245 501
1246 502 $frm_settings = FrmAppHelper::get_settings();
1247 -
1248 - if ( $frm_settings->load_style === 'none' ) {
1249 - return;
503 + if ( $frm_settings->load_style != 'none' ) {
504 + wp_enqueue_style( 'formidable' );
505 + $frm_vars['css_loaded'] = true;
1250 506 }
1251 -
1252 - wp_enqueue_style( 'formidable' );
1253 - $frm_vars['css_loaded'] = true;
1254 507 }
1255 508
1256 509 /**
1257 510 * Get the stylesheets for the form settings page
1258 - *
1259 - * @return array<WP_Post>
1260 511 */
1261 512 public static function get_style_opts() {
1262 513 $frm_style = new FrmStyle();
1263 - return $frm_style->get_all();
514 + $styles = $frm_style->get_all();
515 +
516 + return $styles;
1264 517 }
1265 518
1266 - /**
1267 - * Get the style post object for a target form.
1268 - *
1269 - * @param bool|object|string $form
1270 - *
1271 - * @return WP_Post|null
1272 - */
1273 519 public static function get_form_style( $form = 'default' ) {
1274 520 $style = FrmFormsHelper::get_form_style( $form );
1275 521
1276 - // phpcs:ignore Universal.Operators.StrictComparisons
1277 - if ( ! $style || 1 == $style ) {
522 + if ( empty( $style ) || 1 == $style ) {
1278 523 $style = 'default';
1279 524 }
1280 525
1281 526 $frm_style = new FrmStyle( $style );
527 +
1282 528 return $frm_style->get_one();
1283 529 }
1284 530
1285 531 /**
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 - /**
1330 532 * @param string $class
1331 533 * @param string $style
1332 - *
1333 - * @return string
1334 534 */
1335 535 public static function get_form_style_class( $class, $style ) {
1336 - // phpcs:ignore Universal.Operators.StrictComparisons
1337 536 if ( 1 == $style ) {
1338 537 $style = 'default';
1339 538 }
1340 539
@@ -1349,18 +548,15 @@
1349 548 return $class;
1350 549 }
1351 550
1352 551 /**
1353 - * @since 3.0
1354 - *
1355 552 * @param object $style
1356 553 * @param string $class
1357 554 *
1358 - * @return void
555 + * @since 3.0
1359 556 */
1360 557 private static function maybe_add_rtl_class( $style, &$class ) {
1361 558 $is_rtl = isset( $style->post_content['direction'] ) && 'rtl' === $style->post_content['direction'];
1362 -
1363 559 if ( $is_rtl ) {
1364 560 $class .= ' frm_rtl';
1365 561 }
1366 562 }
@@ -1365,28 +561,17 @@
1365 561 }
1366 562 }
1367 563
1368 564 /**
1369 - * @param string $val Style setting key.
1370 - * @param int|string $form Form ID or 'default'.
1371 - *
1372 - * @return mixed
565 + * @param string $val
1373 566 */
1374 567 public static function get_style_val( $val, $form = 'default' ) {
1375 568 $style = self::get_form_style( $form );
1376 -
1377 569 if ( $style && isset( $style->post_content[ $val ] ) ) {
1378 570 return $style->post_content[ $val ];
1379 571 }
1380 -
1381 - return null;
1382 572 }
1383 573
1384 - /**
1385 - * @param array $default_styles
1386 - *
1387 - * @return array
1388 - */
1389 574 public static function show_entry_styles( $default_styles ) {
1390 575 $frm_style = new FrmStyle( 'default' );
1391 576 $style = $frm_style->get_one();
1392 577
@@ -1395,15 +580,13 @@
1395 580 }
1396 581
1397 582 foreach ( $default_styles as $name => $val ) {
1398 583 $setting = $name;
1399 -
1400 - if ( 'border_width' === $name ) {
584 + if ( 'border_width' == $name ) {
1401 585 $setting = 'field_border_width';
1402 - } elseif ( 'alt_bg_color' === $name ) {
586 + } elseif ( 'alt_bg_color' == $name ) {
1403 587 $setting = 'bg_color_active';
1404 588 }
1405 -
1406 589 $default_styles[ $name ] = $style->post_content[ $setting ];
1407 590 unset( $name, $val );
1408 591 }
1409 592
@@ -1409,178 +592,14 @@
1409 592
1410 593 return $default_styles;
1411 594 }
1412 595
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 - }
596 + public static function &important_style( $important, $field ) {
597 + $important = self::get_style_val( 'important_style', $field['form_id'] );
1422 598
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;
1436 -
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;
599 + return $important;
1509 600 }
1510 601
1511 - /**
1512 - * Rename a style via an AJAX action.
1513 - *
1514 - * @since 6.0
1515 - *
1516 - * @return void
1517 - */
1518 - public static function rename_style() {
1519 - $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'nonce', 'frm_ajax' );
1520 -
1521 - if ( $permission_error !== false ) {
1522 - $data = array(
1523 - 'message' => __( 'Unable to rename style', 'formidable' ),
1524 - );
1525 - wp_send_json_error( $data, 403 );
1526 - die();
1527 - }
1528 -
1529 - $style_id = FrmAppHelper::get_post_param( 'style_id', 0, 'absint' );
1530 - $style_name = FrmAppHelper::get_post_param( 'style_name', '', 'sanitize_text_field' );
1531 -
1532 - if ( ! $style_id || ! $style_name ) {
1533 - $data = array(
1534 - 'message' => __( 'Invalid route', 'formidable' ),
1535 - );
1536 - wp_send_json_error( $data, 400 );
1537 - die();
1538 - }
1539 -
1540 - /**
1541 - * @var WP_Post|null $post
1542 - */
1543 - $post = get_post( $style_id );
1544 -
1545 - if ( ! $post || $post->post_type !== self::$post_type ) {
1546 - $data = array(
1547 - 'message' => __( 'The style you are renaming either does not exist or it is not a style', 'formidable' ),
1548 - );
1549 - wp_send_json_error( $data, 404 );
1550 - die();
1551 - }
1552 -
1553 - global $wpdb;
1554 - $wpdb->update( $wpdb->posts, array( 'post_title' => $style_name ), array( 'ID' => $post->ID ) );
1555 -
1556 - $data = array();
1557 - wp_send_json_success( $data );
1558 - }
1559 -
1560 - /**
1561 - * Prevent the WordPress edit.css file from loading on the visual styler page.
1562 - * This way .form-field elements do not have border styles applied to them.
1563 - *
1564 - * @since 6.0
1565 - *
1566 - * @param WP_Styles $styles
1567 - *
1568 - * @return void
1569 - */
1570 - public static function disable_conflicting_wp_admin_css( $styles ) {
1571 - if ( ! FrmAppHelper::is_style_editor_page() ) {
1572 - return;
1573 - }
1574 -
1575 - FrmStylesPreviewHelper::disable_conflicting_wp_admin_css( $styles );
1576 - }
1577 -
1578 - /**
1579 - * @deprecated 6.1 Saving custom CSS has been moved into Global Settings.
1580 - *
1581 - * @return void
1582 - */
1583 - public static function save_css() {
1584 - _deprecated_function( __METHOD__, '6.1' );
602 + public static function do_accordion_sections( $screen, $context, $object ) {
603 + return do_accordion_sections( $screen, $context, $object );
1585 604 }
1586 605 }