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

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