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

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