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

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