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

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