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

812 lines 23.7 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 $number => $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 * Unslash everything in post_content but custom_css
230 *
231 * @since 5.0.13
232 *
233 * @param array $settings
234 * @return array
235 */
236 private function unslash_post_content( $settings ) {
237 $custom_css = isset( $settings['custom_css'] ) ? $settings['custom_css'] : '';
238 $settings = wp_unslash( $settings );
239 $settings['custom_css'] = $custom_css;
240 return $settings;
241 }
242
243 /**
244 * @since 5.0.13
245 *
246 * @param array $settings
247 * @return array
248 */
249 public function sanitize_post_content( $settings ) {
250 $defaults = $this->get_defaults();
251 $valid_keys = array_keys( $defaults );
252 $sanitized_settings = array();
253 foreach ( $valid_keys as $key ) {
254 if ( isset( $settings[ $key ] ) ) {
255 $sanitized_settings[ $key ] = sanitize_textarea_field( $settings[ $key ] );
256 } else {
257 $sanitized_settings[ $key ] = $defaults[ $key ];
258 }
259
260 if ( 'custom_css' !== $key ) {
261 $sanitized_settings[ $key ] = $this->strip_invalid_characters( $sanitized_settings[ $key ] );
262 }
263 }
264 return $sanitized_settings;
265 }
266
267 /**
268 * Remove any characters that should not be used in CSS.
269 *
270 * @since 6.2.3
271 *
272 * @param string $setting
273 * @return string
274 */
275 private function strip_invalid_characters( $setting ) {
276 $characters_to_remove = array( '{', '}', ';', '[', ']' );
277
278 // RGB is handled instead in self::maybe_sanitize_rgba_value.
279 if ( 0 !== strpos( $setting, 'rgb' ) ) {
280 $setting = $this->maybe_fix_braces( $setting, $characters_to_remove );
281 }
282
283 return str_replace( $characters_to_remove, '', $setting );
284 }
285
286 /**
287 * @since 6.2.3
288 *
289 * @param string $setting
290 * @param array $characters_to_remove
291 * @return string
292 */
293 private function maybe_fix_braces( $setting, &$characters_to_remove ) {
294 $number_of_opening_braces = substr_count( $setting, '(' );
295 $number_of_closing_braces = substr_count( $setting, ')' );
296
297 if ( $number_of_opening_braces === $number_of_closing_braces ) {
298 return $this->trim_braces( $setting );
299 }
300
301 if ( $this->should_remove_every_brace( $setting ) ) {
302 // Add to $characters_to_remove to remove when str_replace is called.
303 array_push( $characters_to_remove, '(', ')' );
304 return $setting;
305 }
306
307 return $this->trim_braces( $setting );
308 }
309
310 /**
311 * @since 6.2.3
312 *
313 * @param string $input
314 * @return string
315 */
316 private function trim_braces( $input ) {
317 $output = $input;
318 // Remove any ( from the start of the string as no CSS values expect at the first character.
319 if ( $output ) {
320 if ( in_array( $output[0], array( '(', ')' ), true ) ) {
321 $output = ltrim( $output, '()' );
322 }
323 }
324 // Remove extra braces from the end.
325 if ( in_array( substr( $output, -1 ), array( '(', ')' ), true ) ) {
326 $output = rtrim( $output, '()' );
327 if ( false !== strpos( $output, '(' ) ) {
328 $output .= ')';
329 }
330 }
331 return $output;
332 }
333
334 /**
335 * @since 6.2.3
336 *
337 * @param string $setting
338 * @return bool
339 */
340 private function should_remove_every_brace( $setting ) {
341 if ( 0 === strpos( trim( $setting, '()' ), 'calc' ) ) {
342 // Support calc() sizes. We do not want to remove all braces when calc is used.
343 return false;
344 }
345
346 // Matches hex values but also checks for unexpected ( and ).
347 $looks_like_a_hex_value = preg_match( '/^(?:\()?(?!#?[a-fA-F0-9]*[^\(#\)\da-fA-F])[a-fA-F0-9\(\)]*(?:\))?$/', $setting );
348 if ( $looks_like_a_hex_value ) {
349 return true;
350 }
351
352 // Matches size values but also checks for unexpected ( and ).
353 // This is case insensitive so it will catch PX, PT, etc, as well.
354 $looks_like_a_size = preg_match( '/\(?[+-]?\d*\.?\d+(?:px|%|em|rem|ex|pt|pc|mm|cm|in)\)?/i', $setting );
355 if ( $looks_like_a_size ) {
356 return true;
357 }
358
359 return false;
360 }
361
362 /**
363 * @since 3.01.01
364 *
365 * @param string $setting
366 * @return bool
367 */
368 private function is_color( $setting ) {
369 $extra_colors = array( 'error_bg', 'error_border', 'error_text' );
370 return strpos( $setting, 'color' ) !== false || in_array( $setting, $extra_colors, true );
371 }
372
373 /**
374 * @since 3.01.01
375 *
376 * @return array
377 */
378 public function get_color_settings() {
379 $defaults = $this->get_defaults();
380 $settings = array_keys( $defaults );
381
382 return array_filter( $settings, array( $this, 'is_color' ) );
383 }
384
385 /**
386 * Create static CSS file and update the CSS transient alternative.
387 *
388 * @return void
389 */
390 public function save_settings() {
391 $filename = FrmAppHelper::plugin_path() . '/css/custom_theme.css.php';
392 update_option( 'frm_last_style_update', gmdate( 'njGi' ) );
393
394 if ( ! is_file( $filename ) ) {
395 return;
396 }
397
398 $this->clear_cache();
399
400 $css = $this->get_css_content( $filename );
401 $create_file = new FrmCreateFile(
402 array(
403 'file_name' => FrmStylesController::get_file_name(),
404 'new_file_path' => FrmAppHelper::plugin_path() . '/css',
405 )
406 );
407 $create_file->create_file( $css );
408
409 update_option( 'frmpro_css', $css, 'no' );
410 set_transient( 'frmpro_css', $css, MONTH_IN_SECONDS );
411 }
412
413 /**
414 * @param string $filename
415 * @return string
416 */
417 private function get_css_content( $filename ) {
418 $css = '/* ' . __( 'WARNING: Any changes made to this file will be lost when your Formidable settings are updated', 'formidable' ) . ' */' . "\n";
419
420 $saving = true;
421 $frm_style = $this;
422
423 ob_start();
424 include $filename;
425 $css .= preg_replace( '/\/\*(.|\s)*?\*\//', '', str_replace( array( "\r\n", "\r", "\n", "\t", ' ' ), '', ob_get_contents() ) );
426 ob_end_clean();
427
428 return FrmStylesController::replace_relative_url( $css );
429 }
430
431 /**
432 * @return void
433 */
434 private function clear_cache() {
435 $default_post_atts = array(
436 'post_type' => FrmStylesController::$post_type,
437 'post_status' => 'publish',
438 'numberposts' => 99,
439 'orderby' => 'title',
440 'order' => 'ASC',
441 );
442
443 FrmDb::delete_cache_and_transient( json_encode( $default_post_atts ), 'frm_styles' );
444 FrmDb::cache_delete_group( 'frm_styles' );
445 FrmDb::delete_cache_and_transient( 'frmpro_css' );
446 }
447
448 /**
449 * Delete a style by its post ID.
450 *
451 * @param int $id
452 * @return WP_Post|false|null
453 */
454 public function destroy( $id ) {
455 if ( $id === $this->get_default_style()->ID ) {
456 return false;
457 }
458 return wp_delete_post( $id );
459 }
460
461 /**
462 * @return WP_Post|stdClass
463 */
464 public function get_one() {
465 if ( 'default' === $this->id ) {
466 $style = $this->get_default_style();
467 if ( $style ) {
468 $this->id = $style->ID;
469 } else {
470 $this->id = 0;
471 }
472
473 return $style;
474 }
475
476 $style = get_post( $this->id );
477
478 if ( ! $style ) {
479 return $style;
480 }
481
482 $style->post_content = FrmAppHelper::maybe_json_decode( $style->post_content );
483
484 $default_values = $this->get_defaults();
485
486 // fill default values
487 $style->post_content = $this->override_defaults( $style->post_content );
488 $style->post_content = wp_parse_args( $style->post_content, $default_values );
489
490 return $style;
491 }
492
493 /**
494 * @param string $orderby
495 * @param string $order
496 * @param int $limit
497 * @return array
498 */
499 public function get_all( $orderby = 'title', $order = 'ASC', $limit = 99 ) {
500 $post_atts = array(
501 'post_type' => FrmStylesController::$post_type,
502 'post_status' => 'publish',
503 'numberposts' => $limit,
504 'orderby' => $orderby,
505 'order' => $order,
506 );
507
508 $temp_styles = FrmDb::check_cache( json_encode( $post_atts ), 'frm_styles', $post_atts, 'get_posts' );
509
510 if ( empty( $temp_styles ) ) {
511 global $wpdb;
512 // make sure there wasn't a conflict with the query
513 $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' );
514 $temp_styles = FrmDb::check_cache( 'frm_backup_style_check', 'frm_styles', $query, 'get_results' );
515
516 if ( empty( $temp_styles ) ) {
517 // create a new style if there are none
518 $new = $this->get_new();
519 $new->post_title = __( 'Formidable Style', 'formidable' );
520 $new->post_name = $new->post_title;
521 $new->menu_order = 1;
522 $new = $this->save( (array) $new );
523 $this->update( 'default' );
524
525 $post_atts['include'] = $new;
526
527 $temp_styles = get_posts( $post_atts );
528 }
529 }
530
531 $default_values = $this->get_defaults();
532 $default_style = false;
533
534 $styles = array();
535 foreach ( $temp_styles as $style ) {
536 $this->id = $style->ID;
537 if ( $style->menu_order ) {
538 if ( $default_style ) {
539 // only return one default
540 $style->menu_order = 0;
541 } else {
542 // check for a default style
543 $default_style = $style->ID;
544 }
545 }
546
547 $style->post_content = FrmAppHelper::maybe_json_decode( $style->post_content );
548
549 // fill default values
550 $style->post_content = $this->override_defaults( $style->post_content );
551 $style->post_content = wp_parse_args( $style->post_content, $default_values );
552
553 $styles[ $style->ID ] = $style;
554 }
555
556 if ( ! $default_style ) {
557 $default_style = reset( $styles );
558
559 $styles[ $default_style->ID ]->menu_order = 1;
560 }
561
562 return $styles;
563 }
564
565 /**
566 * @param array|null $styles
567 */
568 public function get_default_style( $styles = null ) {
569 if ( ! isset( $styles ) ) {
570 $styles = $this->get_all( 'menu_order', 'DESC', 1 );
571 }
572
573 foreach ( $styles as $style ) {
574 if ( $style->menu_order ) {
575 return $style;
576 }
577 }
578 }
579
580 /**
581 * @param mixed $settings
582 * @return mixed
583 */
584 public function override_defaults( $settings ) {
585 if ( ! is_array( $settings ) ) {
586 return $settings;
587 }
588
589 $settings['line_height'] = ( ! isset( $settings['field_height'] ) || $settings['field_height'] == '' || $settings['field_height'] == 'auto' ) ? 'normal' : $settings['field_height'];
590
591 if ( ! isset( $settings['form_desc_size'] ) && isset( $settings['description_font_size'] ) ) {
592 $settings['form_desc_size'] = $settings['description_font_size'];
593 $settings['form_desc_color'] = $settings['description_color'];
594 $settings['title_color'] = $settings['label_color'];
595 }
596
597 if ( ! isset( $settings['section_color'] ) && isset( $settings['label_color'] ) ) {
598 $settings['section_color'] = $settings['label_color'];
599 $settings['section_border_color'] = $settings['border_color'];
600 }
601
602 if ( ! isset( $settings['submit_hover_bg_color'] ) && isset( $settings['submit_bg_color'] ) ) {
603 $settings['submit_hover_bg_color'] = $settings['submit_bg_color'];
604 $settings['submit_hover_color'] = $settings['submit_text_color'];
605 $settings['submit_hover_border_color'] = $settings['submit_border_color'];
606
607 $settings['submit_active_bg_color'] = $settings['submit_bg_color'];
608 $settings['submit_active_color'] = $settings['submit_text_color'];
609 $settings['submit_active_border_color'] = $settings['submit_border_color'];
610 }
611
612 return apply_filters( 'frm_override_default_styles', $settings );
613 }
614
615 /**
616 * @return array
617 */
618 public function get_defaults() {
619 $defaults = array(
620 'theme_css' => 'ui-lightness',
621 'theme_name' => 'UI Lightness',
622
623 'center_form' => '',
624 'form_width' => '100%',
625 'form_align' => 'left',
626 'direction' => is_rtl() ? 'rtl' : 'ltr',
627 'fieldset' => '0px',
628 'fieldset_color' => '000000',
629 'fieldset_padding' => '0 0 15px 0',
630 'fieldset_bg_color' => '',
631
632 'title_size' => '40px',
633 'title_color' => '444444',
634 'title_margin_top' => '10px',
635 'title_margin_bottom' => '60px',
636 'form_desc_size' => '14px',
637 'form_desc_color' => '666666',
638 'form_desc_margin_top' => '10px',
639 'form_desc_margin_bottom' => '25px',
640 'form_desc_padding' => '0',
641
642 'font' => '',
643 'font_size' => '15px',
644 'label_color' => '3f4b5b',
645 'weight' => 'normal',
646 'position' => 'none',
647 'align' => 'left',
648 'width' => '150px',
649 'required_color' => 'B94A48',
650 'required_weight' => 'bold',
651 'label_padding' => '0 0 3px 0',
652
653 'description_font_size' => '12px',
654 'description_color' => '666666',
655 'description_weight' => 'normal',
656 'description_style' => 'normal',
657 'description_align' => 'left',
658 'description_margin' => '0',
659
660 'field_font_size' => '14px',
661 'field_height' => '32px',
662 'line_height' => 'normal',
663 'field_width' => '100%',
664 'auto_width' => false,
665 'field_pad' => '6px 10px',
666 'field_margin' => '20px',
667 'field_weight' => 'normal',
668 'text_color' => '555555',
669 // 'border_color_hv' => 'cccccc',
670 'border_color' => 'BFC3C8',
671 'field_border_width' => '1px',
672 'field_border_style' => 'solid',
673
674 'bg_color' => 'ffffff',
675 // 'bg_color_hv' => 'ffffff',
676 'remove_box_shadow' => '',
677 'bg_color_active' => 'ffffff',
678 'border_color_active' => '66afe9',
679 'remove_box_shadow_active' => '',
680 'text_color_error' => '444444',
681 'bg_color_error' => 'ffffff',
682 'border_color_error' => 'B94A48',
683 'border_width_error' => '1px',
684 'border_style_error' => 'solid',
685 'bg_color_disabled' => 'ffffff',
686 'border_color_disabled' => 'E5E5E5',
687 'text_color_disabled' => 'A1A1A1',
688
689 'radio_align' => 'block',
690 'check_align' => 'block',
691 'check_font_size' => '13px',
692 'check_label_color' => '444444',
693 'check_weight' => 'normal',
694
695 'section_font_size' => '18px',
696 'section_color' => '444444',
697 'section_weight' => 'bold',
698 'section_pad' => '15px 0 3px 0',
699 'section_mar_top' => '15px',
700 'section_mar_bottom' => '30px',
701 'section_bg_color' => '',
702 'section_border_color' => 'e8e8e8',
703 'section_border_width' => '2px',
704 'section_border_style' => 'solid',
705 'section_border_loc' => '-top',
706 'collapse_icon' => '6',
707 'collapse_pos' => 'after',
708 'repeat_icon' => '1',
709 'repeat_icon_color' => 'ffffff',
710
711 'submit_style' => false,
712 'submit_font_size' => '15px',
713 'submit_width' => 'auto',
714 'submit_height' => 'auto',
715 'submit_bg_color' => '579AF6',
716 'submit_border_color' => '579AF6',
717 'submit_border_width' => '1px',
718 'submit_text_color' => 'ffffff',
719 'submit_weight' => 'normal',
720 'submit_border_radius' => '4px',
721 'submit_bg_img' => '',
722 'submit_margin' => '10px',
723 'submit_padding' => '10px 20px',
724 'submit_shadow_color' => 'eeeeee',
725 'submit_hover_bg_color' => 'efefef',
726 'submit_hover_color' => '444444',
727 'submit_hover_border_color' => 'cccccc',
728 'submit_active_bg_color' => 'efefef',
729 'submit_active_color' => '444444',
730 'submit_active_border_color' => 'cccccc',
731
732 'border_radius' => '4px',
733 'error_bg' => 'F2DEDE',
734 'error_border' => 'EBCCD1',
735 'error_text' => 'B94A48',
736 'error_font_size' => '14px',
737
738 'success_bg_color' => 'DFF0D8',
739 'success_border_color' => 'D6E9C6',
740 'success_text_color' => '468847',
741 'success_font_size' => '14px',
742
743 'important_style' => false,
744
745 'progress_bg_color' => 'eaeaea',
746 'progress_active_color' => 'ffffff',
747 'progress_active_bg_color' => '579AF6',
748 'progress_color' => '3f4b5b',
749 'progress_border_color' => 'E5E5E5',
750 'progress_border_size' => '2px',
751 'progress_size' => '24px',
752
753 'custom_css' => '',
754 );
755
756 return apply_filters( 'frm_default_style_settings', $defaults );
757 }
758
759 /**
760 * Get a name attribute value for a style setting input.
761 *
762 * @param string $field_name
763 * @param string $post_field
764 * @return string
765 */
766 public function get_field_name( $field_name, $post_field = 'post_content' ) {
767 return 'frm_style_setting' . ( empty( $post_field ) ? '' : '[' . $post_field . ']' ) . '[' . $field_name . ']';
768 }
769
770 /**
771 * @return array
772 */
773 public static function get_bold_options() {
774 return array(
775 100 => 100,
776 200 => 200,
777 300 => 300,
778 'normal' => __( 'normal', 'formidable' ),
779 500 => 500,
780 600 => 600,
781 'bold' => __( 'bold', 'formidable' ),
782 800 => 800,
783 900 => 900,
784 );
785 }
786
787 /**
788 * Don't let imbalanced font families ruin the whole stylesheet.
789 *
790 * @param string $value
791 * @return string
792 */
793 public function force_balanced_quotation( $value ) {
794 $balanced_characters = array( '"', "'" );
795 foreach ( $balanced_characters as $char ) {
796 $char_count = substr_count( $value, $char );
797 $is_balanced = $char_count % 2 == 0;
798
799 if ( $is_balanced ) {
800 continue;
801 }
802
803 if ( $value && $char === $value[ strlen( $value ) - 1 ] ) {
804 $value = $char . $value;
805 } else {
806 $value .= $char;
807 }
808 }
809 return $value;
810 }
811 }
812