PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.28
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.28
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 / FrmSettings.php

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

671 lines 14.2 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 #[\AllowDynamicProperties]
7 class FrmSettings {
8
9 /**
10 * @var string
11 */
12 public $option_name = 'frm_options';
13
14 /**
15 * @var int
16 */
17 public $menu;
18
19 /**
20 * @var int
21 */
22 public $mu_menu;
23
24 /**
25 * @var int
26 */
27 public $fade_form;
28
29 /**
30 * @var bool
31 */
32 public $admin_bar;
33
34 /**
35 * @var string
36 */
37 public $success_msg;
38
39 /**
40 * @var string
41 */
42 public $blank_msg;
43
44 /**
45 * @var string
46 */
47 public $unique_msg;
48
49 /**
50 * @var string
51 */
52 public $invalid_msg;
53
54 /**
55 * @var string
56 */
57 public $failed_msg;
58
59 /**
60 * @var string
61 */
62 public $submit_value;
63
64 /**
65 * @var string
66 */
67 public $login_msg;
68
69 /**
70 * @var string
71 */
72 public $admin_permission;
73
74 /**
75 * @var string
76 */
77 public $email_to;
78
79 /**
80 * @var string|null
81 */
82 public $load_style;
83
84 /**
85 * @var bool|int|null
86 */
87 public $custom_style;
88
89 /**
90 * @var string|null
91 */
92 public $active_captcha;
93
94 /**
95 * Settings for reCAPTCHA.
96 */
97
98 /**
99 * @var string|null
100 */
101 public $pubkey;
102
103 /**
104 * @var string|null
105 */
106 public $privkey;
107
108 /**
109 * @var string|null
110 */
111 public $re_lang;
112
113 /**
114 * @var string|null
115 */
116 public $re_type;
117
118 /**
119 * @var string
120 */
121 public $re_msg;
122
123 /**
124 * @var bool
125 */
126 public $re_multi;
127
128 /**
129 * @var float|string|null
130 */
131 public $re_threshold;
132
133 /**
134 * Settings for hCaptcha.
135 */
136
137 /**
138 * @var string
139 */
140 public $hcaptcha_pubkey;
141
142 /**
143 * @var string|null
144 */
145 public $hcaptcha_privkey;
146
147 /**
148 * Settings for Turnstile.
149 */
150
151 /**
152 * @var string
153 */
154 public $turnstile_pubkey;
155
156 /**
157 * @var string|null
158 */
159 public $turnstile_privkey;
160
161 /**
162 * @var bool
163 */
164 public $no_ips;
165
166 /**
167 * @var string
168 */
169 public $custom_header_ip;
170
171 /**
172 * @var int
173 */
174 public $current_form = 0;
175
176 /**
177 * @var bool|int
178 */
179 public $tracking;
180
181 /**
182 * @var bool
183 */
184 public $summary_emails;
185
186 /**
187 * @var string
188 */
189 public $summary_emails_recipients;
190
191 /**
192 * @var string|null
193 */
194 public $default_email;
195
196 /**
197 * @var string
198 */
199 public $from_email;
200
201 /**
202 * @var string|null
203 */
204 public $currency;
205
206 /**
207 * @since 6.0
208 *
209 * @var false|string|null
210 */
211 public $custom_css;
212
213 /**
214 * @var int
215 */
216 public $honeypot;
217
218 /**
219 * @var bool
220 */
221 public $wp_spam_check;
222
223 /**
224 * @var bool
225 */
226 public $denylist_check;
227
228 /**
229 * @since 6.25.1
230 *
231 * @var int|null 1 if installed after welcome tour update, null otherwise.
232 */
233 public $installed_after_welcome_tour_update;
234
235 /**
236 * @var string
237 */
238 public $disallowed_words;
239
240 /**
241 * @var string
242 */
243 public $allowed_words;
244
245 /**
246 * @param array $args
247 */
248 public function __construct( $args = array() ) {
249 if ( ! defined( 'ABSPATH' ) ) {
250 die( 'You are not allowed to call this page directly.' );
251 }
252
253 $settings = get_option( $this->option_name );
254
255 if ( ! is_object( $settings ) ) {
256 $settings = $this->translate_settings( $settings );
257 }
258
259 foreach ( $settings as $setting_name => $setting ) {
260 $this->{$setting_name} = $setting;
261 unset( $setting_name, $setting );
262 }
263
264 $this->set_default_options();
265
266 $this->maybe_filter_for_form( $args );
267 }
268
269 /**
270 * @param false|object $settings
271 *
272 * @return object
273 */
274 private function translate_settings( $settings ) {
275 if ( $settings ) {
276 // Workaround for W3 total cache conflict.
277 return unserialize( serialize( $settings ) );
278 }
279
280 // If unserializing didn't work.
281 $settings = $this;
282
283 update_option( $this->option_name, $settings, true );
284
285 return $settings;
286 }
287
288 /**
289 * @return array
290 */
291 public function default_options() {
292 return array(
293 'menu' => apply_filters( 'frm_default_menu', 'Formidable' ),
294 'mu_menu' => 0,
295 'fade_form' => false,
296 'admin_bar' => false,
297
298 're_multi' => 1,
299
300 'success_msg' => __( 'Your responses were successfully submitted. Thank you!', 'formidable' ),
301 // translators: %s: [field_name] shortcode.
302 'blank_msg' => sprintf( __( '%s cannot be blank.', 'formidable' ), '[field_name]' ),
303 // translators: %s: [field_name] shortcode.
304 'unique_msg' => sprintf( __( '%s must be unique.', 'formidable' ), '[field_name]' ),
305 'invalid_msg' => __( 'There was a problem with your submission. Errors are marked below.', 'formidable' ),
306 'failed_msg' => __( 'We\'re sorry. It looks like you\'ve already submitted that.', 'formidable' ),
307 'submit_value' => __( 'Submit', 'formidable' ),
308 'login_msg' => __( 'You do not have permission to view this form.', 'formidable' ),
309 'admin_permission' => __( 'You do not have permission to do that', 'formidable' ),
310 'new_tab_msg' => __( 'The page has been opened in a new tab.', 'formidable' ),
311
312 'email_to' => '[admin_email]',
313 'enable_gdpr' => 0,
314 'no_gdpr_cookies' => 0,
315 'no_ips' => 0,
316 'custom_header_ip' => 0,
317 'tracking' => FrmAppHelper::pro_is_installed(),
318 // Only enable this by default for the main site.
319 'summary_emails' => get_current_blog_id() === get_main_site_id(),
320 'summary_emails_recipients' => '[admin_email]',
321
322 // Normally custom CSS is a string. A false value is used when nothing has been set.
323 // When it is false, we try to use the old custom_key value from the default style's post_content array.
324 'custom_css' => false,
325 'honeypot' => 1,
326 'wp_spam_check' => 0,
327 'denylist_check' => 0,
328 'disallowed_words' => '',
329 'allowed_words' => '',
330 'email_style' => 'classic',
331 );
332 }
333
334 /**
335 * @return void
336 */
337 private function set_default_options() {
338 $this->fill_captcha_settings();
339
340 if ( ! isset( $this->load_style ) ) {
341 if ( ! isset( $this->custom_style ) ) {
342 $this->custom_style = true;
343 }
344
345 $this->load_style = 'all';
346 }
347
348 $this->fill_with_defaults();
349
350 if ( is_multisite() && is_admin() ) {
351 $mu_menu = get_site_option( 'frm_admin_menu_name' );
352
353 if ( $mu_menu && $mu_menu ) {
354 $this->menu = $mu_menu;
355 $this->mu_menu = 1;
356 }
357 }
358
359 $frm_roles = FrmAppHelper::frm_capabilities( 'pro' );
360
361 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
362 if ( ! isset( $this->$frm_role ) ) {
363 $this->$frm_role = 'administrator';
364 }
365 }
366
367 if ( ! isset( $this->default_email ) ) {
368 $this->default_email = get_option( 'admin_email' );
369 }
370
371 if ( ! isset( $this->currency ) ) {
372 $this->currency = 'USD';
373 }
374 }
375
376 /**
377 * @param array $params
378 *
379 * @return void
380 */
381 public function fill_with_defaults( $params = array() ) {
382 $settings = $this->default_options();
383 $filter_html = ! FrmAppHelper::allow_unfiltered_html();
384
385 if ( $filter_html ) {
386 $filter_keys = array( 'failed_msg', 'blank_msg', 'invalid_msg', 'admin_permission', 'unique_msg', 'success_msg', 'submit_value', 'login_msg', 'menu' );
387
388 if ( ! empty( $params['additional_filter_keys'] ) ) {
389 $filter_keys = array_merge( $filter_keys, $params['additional_filter_keys'] );
390 }
391 } else {
392 $filter_keys = array();
393 }
394
395 foreach ( $settings as $setting => $default ) {
396 if ( isset( $params[ 'frm_' . $setting ] ) ) {
397 $this->{$setting} = $params[ 'frm_' . $setting ];
398 } elseif ( ! isset( $this->{$setting} ) ) {
399 $this->{$setting} = $default;
400 }
401
402 if ( $setting === 'menu' && empty( $this->{$setting} ) ) {
403 $this->{$setting} = $default;
404 }
405
406 $this->{$setting} = $this->maybe_sanitize_global_setting( $this->{$setting}, $setting, $filter_keys );
407 unset( $setting, $default );
408 }
409 }
410
411 /**
412 * Handle sanitizing for a target global setting key.
413 *
414 * @since 6.0
415 *
416 * @param mixed $value The unsanitized global setting value.
417 * @param string $key The key of the global setting being saved.
418 * @param array $filter_keys These keys that are filtered with kses.
419 *
420 * @return mixed
421 */
422 private function maybe_sanitize_global_setting( $value, $key, $filter_keys ) {
423 if ( 'custom_css' === $key ) {
424 if ( false === $value ) {
425 // Avoid changing the false default value to an empty string.
426 return $value;
427 }
428
429 return sanitize_textarea_field( $value );
430 }
431
432 if ( in_array( $key, $filter_keys, true ) ) {
433 return FrmAppHelper::kses( $value, 'all' );
434 }
435
436 return $value;
437 }
438
439 /**
440 * @return void
441 */
442 private function fill_captcha_settings() {
443 if ( ! isset( $this->active_captcha ) ) {
444 $this->active_captcha = 'recaptcha';
445 }
446
447 $privkey = '';
448 $re_lang = '';
449
450 if ( ! isset( $this->hcaptcha_privkey ) ) {
451 $this->hcaptcha_privkey = '';
452 }
453
454 if ( ! isset( $this->turnstile_privkey ) ) {
455 $this->turnstile_privkey = '';
456 }
457
458 if ( ! isset( $this->pubkey ) ) {
459 // Get the options from the database.
460 $recaptcha_opt = is_multisite() ? get_site_option( 'recaptcha' ) : get_option( 'recaptcha' );
461 $this->pubkey = $recaptcha_opt['pubkey'] ?? '';
462 $privkey = $recaptcha_opt['privkey'] ?? $privkey;
463 $re_lang = $recaptcha_opt['re_lang'] ?? $re_lang;
464 }
465
466 if ( empty( $this->re_msg ) ) {
467 $this->re_msg = __( 'The CAPTCHA was not entered correctly', 'formidable' );
468 }
469
470 if ( ! isset( $this->privkey ) ) {
471 $this->privkey = $privkey;
472 }
473
474 if ( ! isset( $this->re_lang ) ) {
475 $this->re_lang = $re_lang;
476 }
477
478 if ( ! isset( $this->re_type ) ) {
479 $this->re_type = '';
480 }
481
482 if ( ! isset( $this->re_threshold ) ) {
483 $this->re_threshold = .5;
484 }
485 }
486
487 /**
488 * Get values that may be shown on the front-end without an override in the form settings.
489 *
490 * @since 3.06.01
491 *
492 * @return string[]
493 */
494 public function translatable_strings() {
495 return array(
496 'invalid_msg',
497 'admin_permission',
498 'failed_msg',
499 'login_msg',
500 );
501 }
502
503 /**
504 * Allow strings to be filtered when a specific form may be displaying them.
505 *
506 * @since 3.06.01
507 *
508 * @param array $args
509 *
510 * @return void
511 */
512 public function maybe_filter_for_form( $args ) {
513 if ( isset( $args['current_form'] ) && is_numeric( $args['current_form'] ) ) {
514 $this->current_form = $args['current_form'];
515
516 foreach ( $this->translatable_strings() as $string ) {
517 $this->{$string} = apply_filters( 'frm_global_setting', $this->{$string}, $string, $this );
518 $this->{$string} = apply_filters( 'frm_global_' . $string, $this->{$string}, $this );
519 }
520 }
521 }
522
523 /**
524 * @param array $params
525 * @param array $errors
526 *
527 * @return array
528 */
529 public function validate( $params, $errors ) {
530 return apply_filters( 'frm_validate_settings', $errors, $params );
531 }
532
533 /**
534 * @param array $params
535 *
536 * @return void
537 */
538 public function update( $params ) {
539 $this->fill_with_defaults( $params );
540 $this->update_settings( $params );
541
542 if ( $this->mu_menu ) {
543 update_site_option( 'frm_admin_menu_name', $this->menu );
544 } elseif ( current_user_can( 'administrator' ) ) {
545 update_site_option( 'frm_admin_menu_name', false );
546 }
547
548 $this->update_roles( $params );
549
550 do_action( 'frm_update_settings', $params );
551
552 if ( ! function_exists( 'get_filesystem_method' ) ) {
553 return;
554 }
555
556 // Save styling settings in case fallback setting changes.
557 $frm_style = new FrmStyle();
558 $frm_style->update( 'default' );
559 }
560
561 /**
562 * @param array $params
563 *
564 * @return void
565 */
566 private function update_settings( $params ) {
567 $this->active_captcha = $params['frm_active_captcha'];
568 $this->pubkey = trim( $params['frm_pubkey'] );
569 $this->privkey = trim( $params['frm_privkey'] );
570 $this->re_type = $params['frm_re_type'];
571 $this->re_lang = $params['frm_re_lang'];
572 $this->re_threshold = floatval( $params['frm_re_threshold'] );
573 $this->hcaptcha_pubkey = trim( $params['frm_hcaptcha_pubkey'] );
574 $this->hcaptcha_privkey = trim( $params['frm_hcaptcha_privkey'] );
575 $this->turnstile_pubkey = trim( $params['frm_turnstile_pubkey'] );
576 $this->turnstile_privkey = trim( $params['frm_turnstile_privkey'] );
577 $this->load_style = $params['frm_load_style'];
578 $this->custom_css = $params['frm_custom_css'];
579 $this->default_email = $params['frm_default_email'];
580 $this->from_email = $params['frm_from_email'];
581 $this->currency = $params['frm_currency'];
582
583 $checkboxes = array(
584 'mu_menu',
585 're_multi',
586 'fade_form',
587 'no_ips',
588 'no_gdpr_cookies',
589 'enable_gdpr',
590 'custom_header_ip',
591 'tracking',
592 'admin_bar',
593 'summary_emails',
594 'honeypot',
595 'wp_spam_check',
596 'denylist_check',
597 );
598
599 foreach ( $checkboxes as $set ) {
600 $this->$set = isset( $params[ 'frm_' . $set ] ) ? absint( $params[ 'frm_' . $set ] ) : 0;
601 }
602 }
603
604 /**
605 * @param array $params
606 *
607 * @return void
608 */
609 private function update_roles( $params ) {
610 global $wp_roles;
611
612 $frm_roles = FrmAppHelper::frm_capabilities();
613 $roles = get_editable_roles();
614
615 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
616 $this->$frm_role = (array) ( $params[ $frm_role ] ?? 'administrator' );
617
618 // Make sure administrators always have permissions
619 if ( ! in_array( 'administrator', $this->$frm_role, true ) ) {
620 array_push( $this->$frm_role, 'administrator' );
621 }
622
623 foreach ( $roles as $role => $details ) {
624 if ( in_array( $role, $this->$frm_role, true ) ) {
625 $wp_roles->add_cap( $role, $frm_role );
626 } else {
627 $wp_roles->remove_cap( $role, $frm_role );
628 }
629 }
630 }
631 }
632
633 /**
634 * Updates a single setting with specified sanitization.
635 *
636 * @since 6.9
637 *
638 * @param string $key The setting key to update.
639 * @param mixed $value The new value for the setting.
640 * @param string $sanitize The name of the sanitization function to apply to the new value.
641 *
642 * @return bool True on success, false on failure.
643 */
644 public function update_setting( $key, $value, $sanitize ) {
645 if ( ! property_exists( $this, $key ) || ! is_callable( $sanitize ) ) {
646 // Setting does not exist or sanitization function name is not callable.
647 return false;
648 }
649
650 // Update the property value.
651 FrmAppHelper::sanitize_value( $sanitize, $value );
652 $this->{$key} = $value;
653
654 return true;
655 }
656
657 /**
658 * @return void
659 */
660 public function store() {
661 // Save the posted value in the database
662
663 update_option( 'frm_options', $this );
664
665 delete_transient( 'frm_options' );
666 set_transient( 'frm_options', $this );
667
668 do_action( 'frm_store_settings' );
669 }
670 }
671