PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.12
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.12
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
formidable / classes / models / FrmStyle.php

FrmStyle.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.12, at classes/models/FrmStyle.php

794 lines 23.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmStyle {
7 /**
8 * Unique ID number of the current instance.
9 *
10 * @var int
11 */
12 public $number = false;
13
14 /**
15 * The id of the post.
16 *
17 * @var int|string
18 */
19 public $id = 0;
20
21 /**
22 * @param int|string $id The id of the stylsheet or 'default'.
23 */
24 public function __construct( $id = 0 ) {
25 $this->id = $id;
26 }
27
28 /**
29 * @return stdClass
30 */
31 public function get_new() {
32 $this->id = 0;
33
34 $max_slug_value = 2147483647;
35 // We want to have at least 2 characters in the slug.
36 $min_slug_value = 37;
37 $key = base_convert( rand( $min_slug_value, $max_slug_value ), 10, 36 );
38
39 $style = array(
40 'post_type' => FrmStylesController::$post_type,
41 'ID' => '',
42 'post_title' => __( 'New Style', 'formidable' ),
43 'post_name' => $key,
44 'post_content' => $this->get_defaults(),
45 'menu_order' => '',
46 'post_status' => 'publish',
47 );
48
49 return (object) $style;
50 }
51
52 /**
53 * @param array $settings
54 * @return int|WP_Error
55 */
56 public function save( $settings ) {
57 return FrmDb::save_settings( $settings, 'frm_styles' );
58 }
59
60 /**
61 * @return void
62 */
63 public function duplicate( $id ) {
64 // Duplicating is a pro feature. This is handled in FrmProStyle::duplicate instead.
65 }
66
67 /**
68 * Handle save actions in the visual styler edit page.
69 *
70 * @param mixed $id
71 * @return array<int|WP_Error>
72 */
73 public function update( $id = 'default' ) {
74 $all_instances = $this->get_all();
75
76 if ( ! $id ) {
77 $new_style = (array) $this->get_new();
78 $all_instances[] = $new_style;
79 }
80
81 $action_ids = array();
82
83 foreach ( $all_instances as $new_instance ) {
84 $new_instance = (array) $new_instance;
85 $this->id = $new_instance['ID'];
86
87 if ( $id != $this->id || ! $_POST || ! isset( $_POST['frm_style_setting'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
88 // Don't continue if not saving this style.
89 continue;
90 }
91
92 // Custom CSS is no longer used from the default style, but it is still checked if the Global Setting is missing.
93 // Preserve the previous value in case Custom CSS has not been saved as a Global Setting yet.
94 $custom_css = isset( $new_instance['post_content']['custom_css'] ) ? $new_instance['post_content']['custom_css'] : '';
95
96 // phpcs:ignore WordPress.Security.NonceVerification.Missing
97 if ( ! empty( $_POST['frm_style_setting']['post_title'] ) ) {
98 // The nonce check happens in FrmStylesController::save_style before this is called.
99 // phpcs:ignore WordPress.Security.NonceVerification.Missing
100 $new_instance['post_title'] = sanitize_text_field( wp_unslash( $_POST['frm_style_setting']['post_title'] ) );
101 }
102
103 $new_instance['post_content'] = isset( $_POST['frm_style_setting']['post_content'] ) ? $this->sanitize_post_content( wp_unslash( $_POST['frm_style_setting']['post_content'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
104 $new_instance['post_content']['custom_css'] = $custom_css;
105 unset( $custom_css );
106
107 $new_instance['post_type'] = FrmStylesController::$post_type;
108 $new_instance['post_status'] = 'publish';
109
110 if ( ! $id ) {
111 $new_instance['post_name'] = $new_instance['post_title'];
112 }
113
114 $default_settings = $this->get_defaults();
115
116 foreach ( $default_settings as $setting => $default ) {
117 if ( ! isset( $new_instance['post_content'][ $setting ] ) ) {
118 $new_instance['post_content'][ $setting ] = $default;
119 }
120
121 if ( $this->is_color( $setting ) ) {
122 $color_val = $new_instance['post_content'][ $setting ];
123 if ( $color_val !== '' && false !== strpos( $color_val, 'rgb' ) ) {
124 // Maybe sanitize if invalid rgba value is entered.
125 $this->maybe_sanitize_rgba_value( $color_val );
126 }
127 $new_instance['post_content'][ $setting ] = str_replace( '#', '', $color_val );
128 } elseif ( in_array( $setting, array( 'submit_style', 'important_style', 'auto_width' ), true ) && ! isset( $new_instance['post_content'][ $setting ] ) ) {
129 $new_instance['post_content'][ $setting ] = 0;
130 } elseif ( $setting === 'font' ) {
131 $new_instance['post_content'][ $setting ] = $this->force_balanced_quotation( $new_instance['post_content'][ $setting ] );
132 }
133 }
134
135 $action_ids[] = $this->save( $new_instance );
136 }//end foreach
137
138 $this->save_settings();
139
140 return $action_ids;
141 }
142
143 /**
144 * Sanitize custom color values and convert it to valid one filling missing values.
145 *
146 * @since 5.3.2
147 *
148 * @param string $color_val The color value, by reference.
149 * @return void
150 */
151 private function maybe_sanitize_rgba_value( &$color_val ) {
152 if ( preg_match( '/(rgb|rgba)\(/', $color_val ) !== 1 ) {
153 return;
154 }
155
156 $color_val = trim( $color_val );
157 // Remove leading braces so (rgba(1,1,1,1) doesn't cause inconsistent braces.
158 $color_val = ltrim( $color_val, '(' );
159 $patterns = array( '/rgba\((\s*\d+\s*,){3}[[0-1]\.]+\)/', '/rgb\((\s*\d+\s*,){2}\s*[\d]+\)/' );
160 foreach ( $patterns as $pattern ) {
161 if ( preg_match( $pattern, $color_val ) === 1 ) {
162 return;
163 }
164 }
165
166 // Remove all leading ')' braces, then add one back. This way there's always a single brace.
167 $color_val = rtrim( $color_val, ')' );
168 $color_val .= ')';
169
170 $color_rgba = substr( $color_val, strpos( $color_val, '(' ) + 1, strlen( $color_val ) - strpos( $color_val, '(' ) - 2 );
171 // Remove any excessive braces from the rgba like rgba((.
172 $color_rgba = trim( $color_rgba, '()' );
173 $length_of_color_codes = strpos( $color_val, '(' );
174 $new_color_values = array();
175
176 // replace empty values by 0 or 1 (if alpha position).
177 foreach ( explode( ',', $color_rgba ) as $index => $value ) {
178 $new_value = null;
179 $value_is_empty_string = '' === trim( $value ) || '' === $value;
180
181 if ( 3 === $length_of_color_codes || ( $index !== $length_of_color_codes - 1 ) ) {
182 // Insert a value for r, g, or b.
183 if ( $value < 0 ) {
184 $new_value = 0;
185 } elseif ( $value > 255 ) {
186 $new_value = 255;
187 } elseif ( $value_is_empty_string ) {
188 $new_value = 0;
189 } else {
190 $new_value = absint( $value );
191 }
192 } else {
193 // Insert a value for alpha.
194 if ( $value_is_empty_string ) {
195 $new_value = 4 === $length_of_color_codes ? 1 : 0;
196 } elseif ( $value > 1 || $value < 0 ) {
197 $new_value = 1;
198 } else {
199 $new_value = floatval( $value );
200 }
201 }//end if
202
203 $new_color_values[] = null === $new_value ? $value : $new_value;
204 }//end foreach
205
206 // add more 0s and 1 (if alpha position) if needed.
207 $missing_values = $length_of_color_codes - count( $new_color_values );
208 if ( $missing_values > 1 ) {
209 $insert_values = array_fill( 0, $missing_values - 1, 0 );
210 $last_value = 4 === $length_of_color_codes ? 1 : 0;
211 array_push( $insert_values, $last_value );
212 } elseif ( $missing_values === 1 ) {
213 $insert_values = 4 === $length_of_color_codes ? array( 1 ) : array( 0 );
214 }
215 if ( ! empty( $insert_values ) ) {
216 $new_color_values = array_merge( $new_color_values, $insert_values );
217 }
218
219 $new_color = implode( ',', $new_color_values );
220 $prefix = substr( $color_val, 0, strpos( $color_val, '(' ) + 1 );
221 // Limit the number of opening braces after rgb/rgba. There should only be one.
222 $prefix = rtrim( $prefix, '(' ) . '(';
223 $new_color = $prefix . $new_color . ')';
224
225 $color_val = $new_color;
226 }
227
228 /**
229 * @since 5.0.13
230 *
231 * @param array $settings
232 * @return array
233 */
234 public function sanitize_post_content( $settings ) {
235 $defaults = $this->get_defaults();
236 $valid_keys = array_keys( $defaults );
237 $sanitized_settings = array();
238 foreach ( $valid_keys as $key ) {
239 if ( isset( $settings[ $key ] ) ) {
240 $sanitized_settings[ $key ] = sanitize_textarea_field( $settings[ $key ] );
241 } else {
242 $sanitized_settings[ $key ] = $defaults[ $key ];
243 }
244
245 if ( 'custom_css' !== $key ) {
246 $sanitized_settings[ $key ] = $this->strip_invalid_characters( $sanitized_settings[ $key ] );
247 }
248 }
249 return $sanitized_settings;
250 }
251
252 /**
253 * Remove any characters that should not be used in CSS.
254 *
255 * @since 6.2.3
256 *
257 * @param string $setting
258 * @return string
259 */
260 private function strip_invalid_characters( $setting ) {
261 $characters_to_remove = array( '{', '}', ';', '[', ']' );
262
263 // RGB is handled instead in self::maybe_sanitize_rgba_value.
264 if ( 0 !== strpos( $setting, 'rgb' ) ) {
265 $setting = $this->maybe_fix_braces( $setting, $characters_to_remove );
266 }
267
268 return str_replace( $characters_to_remove, '', $setting );
269 }
270
271 /**
272 * @since 6.2.3
273 *
274 * @param string $setting
275 * @param array $characters_to_remove
276 * @return string
277 */
278 private function maybe_fix_braces( $setting, &$characters_to_remove ) {
279 $number_of_opening_braces = substr_count( $setting, '(' );
280 $number_of_closing_braces = substr_count( $setting, ')' );
281
282 if ( $number_of_opening_braces === $number_of_closing_braces ) {
283 return $this->trim_braces( $setting );
284 }
285
286 if ( $this->should_remove_every_brace( $setting ) ) {
287 // Add to $characters_to_remove to remove when str_replace is called.
288 array_push( $characters_to_remove, '(', ')' );
289 return $setting;
290 }
291
292 return $this->trim_braces( $setting );
293 }
294
295 /**
296 * @since 6.2.3
297 *
298 * @param string $input
299 * @return string
300 */
301 private function trim_braces( $input ) {
302 $output = $input;
303 // Remove any ( from the start of the string as no CSS values expect at the first character.
304 if ( $output && in_array( $output[0], array( '(', ')' ), true ) ) {
305 $output = ltrim( $output, '()' );
306 }
307 // Remove extra braces from the end.
308 if ( in_array( substr( $output, -1 ), array( '(', ')' ), true ) ) {
309 $output = rtrim( $output, '()' );
310 if ( false !== strpos( $output, '(' ) ) {
311 $output .= ')';
312 }
313 }
314 return $output;
315 }
316
317 /**
318 * @since 6.2.3
319 *
320 * @param string $setting
321 * @return bool
322 */
323 private function should_remove_every_brace( $setting ) {
324 if ( 0 === strpos( trim( $setting, '()' ), 'calc' ) ) {
325 // Support calc() sizes. We do not want to remove all braces when calc is used.
326 return false;
327 }
328
329 // Matches hex values but also checks for unexpected ( and ).
330 $looks_like_a_hex_value = preg_match( '/^(?:\()?(?!#?[a-fA-F0-9]*[^\(#\)\da-fA-F])[a-fA-F0-9\(\)]*(?:\))?$/', $setting );
331 if ( $looks_like_a_hex_value ) {
332 return true;
333 }
334
335 // Matches size values but also checks for unexpected ( and ).
336 // This is case insensitive so it will catch PX, PT, etc, as well.
337 $looks_like_a_size = preg_match( '/\(?[+-]?\d*\.?\d+(?:px|%|em|rem|ex|pt|pc|mm|cm|in)\)?/i', $setting );
338 if ( $looks_like_a_size ) {
339 return true;
340 }
341
342 return false;
343 }
344
345 /**
346 * @since 3.01.01
347 *
348 * @param string $setting
349 * @return bool
350 */
351 private function is_color( $setting ) {
352 $extra_colors = array( 'error_bg', 'error_border', 'error_text' );
353 return strpos( $setting, 'color' ) !== false || in_array( $setting, $extra_colors, true );
354 }
355
356 /**
357 * @since 3.01.01
358 *
359 * @return array
360 */
361 public function get_color_settings() {
362 $defaults = $this->get_defaults();
363 $settings = array_keys( $defaults );
364
365 return array_filter( $settings, array( $this, 'is_color' ) );
366 }
367
368 /**
369 * Create static CSS file and update the CSS transient alternative.
370 *
371 * @return void
372 */
373 public function save_settings() {
374 $filename = FrmAppHelper::plugin_path() . '/css/custom_theme.css.php';
375 update_option( 'frm_last_style_update', gmdate( 'njGi' ) );
376
377 if ( ! is_file( $filename ) ) {
378 return;
379 }
380
381 $this->clear_cache();
382
383 $css = $this->get_css_content( $filename );
384 $create_file = new FrmCreateFile(
385 array(
386 'file_name' => FrmStylesController::get_file_name(),
387 'new_file_path' => FrmAppHelper::plugin_path() . '/css',
388 )
389 );
390 $create_file->create_file( $css );
391
392 update_option( 'frmpro_css', $css, 'no' );
393 set_transient( 'frmpro_css', $css, MONTH_IN_SECONDS );
394 }
395
396 /**
397 * @param string $filename
398 * @return string
399 */
400 private function get_css_content( $filename ) {
401 $css = '/* ' . __( 'WARNING: Any changes made to this file will be lost when your Formidable settings are updated', 'formidable' ) . ' */' . "\n";
402
403 $saving = true;
404 $frm_style = $this;
405
406 ob_start();
407 include $filename;
408 $css .= preg_replace( '/\/\*(.|\s)*?\*\//', '', str_replace( array( "\r\n", "\r", "\n", "\t", ' ' ), '', ob_get_contents() ) );
409 ob_end_clean();
410
411 return FrmStylesController::replace_relative_url( $css );
412 }
413
414 /**
415 * @return void
416 */
417 private function clear_cache() {
418 $default_post_atts = array(
419 'post_type' => FrmStylesController::$post_type,
420 'post_status' => 'publish',
421 'numberposts' => 99,
422 'orderby' => 'title',
423 'order' => 'ASC',
424 );
425
426 FrmDb::delete_cache_and_transient( json_encode( $default_post_atts ), 'frm_styles' );
427 FrmDb::cache_delete_group( 'frm_styles' );
428 FrmDb::delete_cache_and_transient( 'frmpro_css' );
429 }
430
431 /**
432 * Delete a style by its post ID.
433 *
434 * @param int $id
435 * @return false|WP_Post|null
436 */
437 public function destroy( $id ) {
438 if ( $id === $this->get_default_style()->ID ) {
439 return false;
440 }
441 return wp_delete_post( $id );
442 }
443
444 /**
445 * @return stdClass|WP_Post
446 */
447 public function get_one() {
448 if ( 'default' === $this->id ) {
449 $style = $this->get_default_style();
450 if ( $style ) {
451 $this->id = $style->ID;
452 } else {
453 $this->id = 0;
454 }
455
456 return $style;
457 }
458
459 $style = get_post( $this->id );
460
461 if ( ! $style ) {
462 return $style;
463 }
464
465 $style->post_content = FrmAppHelper::maybe_json_decode( $style->post_content );
466
467 $default_values = $this->get_defaults();
468
469 // fill default values
470 $style->post_content = $this->override_defaults( $style->post_content );
471 $style->post_content = wp_parse_args( $style->post_content, $default_values );
472
473 return $style;
474 }
475
476 /**
477 * @param string $orderby
478 * @param string $order
479 * @param int $limit
480 * @return array
481 */
482 public function get_all( $orderby = 'title', $order = 'ASC', $limit = 99 ) {
483 $post_atts = array(
484 'post_type' => FrmStylesController::$post_type,
485 'post_status' => 'publish',
486 'numberposts' => $limit,
487 'orderby' => $orderby,
488 'order' => $order,
489 );
490
491 $temp_styles = FrmDb::check_cache( json_encode( $post_atts ), 'frm_styles', $post_atts, 'get_posts' );
492
493 if ( empty( $temp_styles ) ) {
494 global $wpdb;
495 // make sure there wasn't a conflict with the query
496 $query = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->posts . ' WHERE post_type=%s AND post_status=%s ORDER BY post_title ASC LIMIT 99', FrmStylesController::$post_type, 'publish' );
497 $temp_styles = FrmDb::check_cache( 'frm_backup_style_check', 'frm_styles', $query, 'get_results' );
498
499 if ( empty( $temp_styles ) ) {
500 // create a new style if there are none
501 $new = $this->get_new();
502 $new->post_title = __( 'Formidable Style', 'formidable' );
503 $new->post_name = $new->post_title;
504 $new->menu_order = 1;
505 $new = $this->save( (array) $new );
506 $this->update( 'default' );
507
508 $post_atts['include'] = $new;
509
510 $temp_styles = get_posts( $post_atts );
511 }
512 }
513
514 $default_values = $this->get_defaults();
515 $default_style = false;
516
517 $styles = array();
518 foreach ( $temp_styles as $style ) {
519 $this->id = $style->ID;
520 if ( $style->menu_order ) {
521 if ( $default_style ) {
522 // only return one default
523 $style->menu_order = 0;
524 } else {
525 // check for a default style
526 $default_style = $style->ID;
527 }
528 }
529
530 $style->post_content = FrmAppHelper::maybe_json_decode( $style->post_content );
531
532 // fill default values
533 $style->post_content = $this->override_defaults( $style->post_content );
534 $style->post_content = wp_parse_args( $style->post_content, $default_values );
535
536 $styles[ $style->ID ] = $style;
537 }
538
539 if ( ! $default_style ) {
540 $default_style = reset( $styles );
541
542 $styles[ $default_style->ID ]->menu_order = 1;
543 }
544
545 return $styles;
546 }
547
548 /**
549 * @param array|null $styles
550 */
551 public function get_default_style( $styles = null ) {
552 if ( ! isset( $styles ) ) {
553 $styles = $this->get_all( 'menu_order', 'DESC', 1 );
554 }
555
556 foreach ( $styles as $style ) {
557 if ( $style->menu_order ) {
558 return $style;
559 }
560 }
561 }
562
563 /**
564 * @param mixed $settings
565 * @return mixed
566 */
567 public function override_defaults( $settings ) {
568 if ( ! is_array( $settings ) ) {
569 return $settings;
570 }
571
572 $settings['line_height'] = ! isset( $settings['field_height'] ) || $settings['field_height'] == '' || $settings['field_height'] === 'auto' ? 'normal' : $settings['field_height'];
573
574 if ( ! isset( $settings['form_desc_size'] ) && isset( $settings['description_font_size'] ) ) {
575 $settings['form_desc_size'] = $settings['description_font_size'];
576 $settings['form_desc_color'] = $settings['description_color'];
577 $settings['title_color'] = $settings['label_color'];
578 }
579
580 if ( ! isset( $settings['section_color'] ) && isset( $settings['label_color'] ) ) {
581 $settings['section_color'] = $settings['label_color'];
582 $settings['section_border_color'] = $settings['border_color'];
583 }
584
585 if ( ! isset( $settings['submit_hover_bg_color'] ) && isset( $settings['submit_bg_color'] ) ) {
586 $settings['submit_hover_bg_color'] = $settings['submit_bg_color'];
587 $settings['submit_hover_color'] = $settings['submit_text_color'];
588 $settings['submit_hover_border_color'] = $settings['submit_border_color'];
589
590 $settings['submit_active_bg_color'] = $settings['submit_bg_color'];
591 $settings['submit_active_color'] = $settings['submit_text_color'];
592 $settings['submit_active_border_color'] = $settings['submit_border_color'];
593 }
594
595 return apply_filters( 'frm_override_default_styles', $settings );
596 }
597
598 /**
599 * @return array
600 */
601 public function get_defaults() {
602 $defaults = array(
603 'theme_css' => 'ui-lightness',
604 'theme_name' => 'UI Lightness',
605
606 'center_form' => '',
607 'form_width' => '100%',
608 'form_align' => 'left',
609 'direction' => is_rtl() ? 'rtl' : 'ltr',
610 'fieldset' => '0px',
611 'fieldset_color' => '000000',
612 'fieldset_padding' => '0 0 15px 0',
613 'fieldset_bg_color' => '',
614
615 'title_size' => '40px',
616 'title_color' => '444444',
617 'title_margin_top' => '10px',
618 'title_margin_bottom' => '60px',
619 'form_desc_size' => '14px',
620 'form_desc_color' => '98A2B3',
621 'form_desc_margin_top' => '10px',
622 'form_desc_margin_bottom' => '25px',
623 'form_desc_padding' => '0',
624
625 'font' => '',
626 'font_size' => '15px',
627 'label_color' => '344054',
628 'weight' => 'normal',
629 'position' => 'none',
630 'align' => 'left',
631 'width' => '150px',
632 'required_color' => 'F04438',
633 'required_weight' => 'bold',
634 'label_padding' => '0 0 5px 0',
635
636 'description_font_size' => '12px',
637 'description_color' => '667085',
638 'description_weight' => 'normal',
639 'description_style' => 'normal',
640 'description_align' => 'left',
641 'description_margin' => '0',
642
643 'field_font_size' => '14px',
644 'field_height' => '36px',
645 'line_height' => 'normal',
646 'field_width' => '100%',
647 'auto_width' => false,
648 'field_pad' => '8px 12px',
649 'field_margin' => '20px',
650 'field_weight' => 'normal',
651 'text_color' => '1D2939',
652 // 'border_color_hv' => 'cccccc',
653 'border_color' => 'D0D5DD',
654 'field_border_width' => '1px',
655 'field_border_style' => 'solid',
656
657 'bg_color' => 'ffffff',
658 // 'bg_color_hv' => 'ffffff',
659 'remove_box_shadow' => '',
660 'bg_color_active' => 'ffffff',
661 'border_color_active' => '4199FD',
662 'remove_box_shadow_active' => '',
663 'text_color_error' => '444444',
664 'bg_color_error' => 'ffffff',
665 'border_color_error' => 'F04438',
666 'border_width_error' => '1px',
667 'border_style_error' => 'solid',
668 'bg_color_disabled' => 'F9FAFB',
669 'border_color_disabled' => 'D0D5DD',
670 'text_color_disabled' => '667085',
671
672 'radio_align' => 'block',
673 'check_align' => 'block',
674 'check_font_size' => '14px',
675 'check_label_color' => '1D2939',
676 'check_weight' => 'normal',
677
678 'section_font_size' => '18px',
679 'section_color' => '344054',
680 'section_weight' => 'bold',
681 'section_pad' => '32px 0 3px 0',
682 'section_mar_top' => '30px',
683 'section_mar_bottom' => '30px',
684 'section_bg_color' => '',
685 'section_border_color' => 'EAECF0',
686 'section_border_width' => '1px',
687 'section_border_style' => 'solid',
688 'section_border_loc' => '-top',
689 'collapse_icon' => '6',
690 'collapse_pos' => 'after',
691 'repeat_icon' => '1',
692 'repeat_icon_color' => 'ffffff',
693
694 'submit_style' => false,
695 'submit_font_size' => '14px',
696 'submit_width' => 'auto',
697 'submit_height' => 'auto',
698 'submit_bg_color' => '4199FD',
699 'submit_border_color' => '4199FD',
700 'submit_border_width' => '1px',
701 'submit_text_color' => 'ffffff',
702 'submit_weight' => 'normal',
703 'submit_border_radius' => '8px',
704 'submit_bg_img' => '',
705 'submit_margin' => '10px',
706 'submit_padding' => '8px 16px',
707 'submit_shadow_color' => 'eeeeee',
708 'submit_hover_bg_color' => '3680D3',
709 'submit_hover_color' => 'ffffff',
710 'submit_hover_border_color' => '3680D3',
711 'submit_active_bg_color' => '3680D3',
712 'submit_active_color' => 'ffffff',
713 'submit_active_border_color' => '3680D3',
714
715 'border_radius' => '8px',
716 'error_bg' => 'FEE4E2',
717 'error_border' => 'F5B8AA',
718 'error_text' => 'F04438',
719 'error_font_size' => '14px',
720
721 'success_bg_color' => 'DFF0D8',
722 'success_border_color' => 'D6E9C6',
723 'success_text_color' => '468847',
724 'success_font_size' => '14px',
725
726 'important_style' => false,
727
728 'progress_bg_color' => 'EAECF0',
729 'progress_color' => '1D2939',
730 'progress_active_bg_color' => '4199FD',
731 'progress_active_color' => 'ffffff',
732 'progress_border_color' => 'EAECF0',
733 'progress_border_size' => '1px',
734 'progress_size' => '30px',
735 'custom_css' => '',
736 );
737
738 return apply_filters( 'frm_default_style_settings', $defaults );
739 }
740
741 /**
742 * Get a name attribute value for a style setting input.
743 *
744 * @param string $field_name
745 * @param string $post_field
746 * @return string
747 */
748 public function get_field_name( $field_name, $post_field = 'post_content' ) {
749 return 'frm_style_setting' . ( empty( $post_field ) ? '' : '[' . $post_field . ']' ) . '[' . $field_name . ']';
750 }
751
752 /**
753 * @return array
754 */
755 public static function get_bold_options() {
756 return array(
757 100 => 100,
758 200 => 200,
759 300 => 300,
760 'normal' => __( 'normal', 'formidable' ),
761 500 => 500,
762 600 => 600,
763 'bold' => __( 'bold', 'formidable' ),
764 800 => 800,
765 900 => 900,
766 );
767 }
768
769 /**
770 * Don't let imbalanced font families ruin the whole stylesheet.
771 *
772 * @param string $value
773 * @return string
774 */
775 public function force_balanced_quotation( $value ) {
776 $balanced_characters = array( '"', "'" );
777 foreach ( $balanced_characters as $char ) {
778 $char_count = substr_count( $value, $char );
779 $is_balanced = $char_count % 2 == 0;
780
781 if ( $is_balanced ) {
782 continue;
783 }
784
785 if ( $value && $char === $value[ strlen( $value ) - 1 ] ) {
786 $value = $char . $value;
787 } else {
788 $value .= $char;
789 }
790 }
791 return $value;
792 }
793 }
794