PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.8
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.8
2.12.8 2.12.7 2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 All 98 releases
sureforms / inc / global-settings / global-settings.php

global-settings.php in SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz 2.12.8, at inc/global-settings/global-settings.php

807 lines 31.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Sureforms Global Settings.
4 *
5 * @package sureforms.
6 * @since 0.0.1
7 */
8
9 namespace SRFM\Inc\Global_Settings;
10
11 use SRFM\Inc\Client_Logger;
12 use SRFM\Inc\Events_Scheduler;
13 use SRFM\Inc\Helper;
14 use SRFM\Inc\Payments\Payment_Helper;
15 use SRFM\Inc\Traits\Get_Instance;
16 use WP_Error;
17 use WP_REST_Request;
18 use WP_REST_Response;
19 use WP_REST_Server;
20
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit;
23 }
24
25 /**
26 * Sureforms Global Settings.
27 *
28 * @since 0.0.1
29 */
30 class Global_Settings {
31 use Get_Instance;
32
33 /**
34 * Namespace.
35 *
36 * @var string
37 */
38 protected $namespace = 'sureforms/v1';
39
40 /**
41 * Constructor
42 *
43 * @since 0.0.1
44 */
45 public function __construct() {
46 add_action( 'rest_api_init', [ $this, 'register_custom_endpoint' ] );
47 }
48
49 /**
50 * Add custom API Route submit-form
51 *
52 * @return void
53 * @since 0.0.1
54 */
55 public function register_custom_endpoint() {
56 register_rest_route(
57 $this->namespace,
58 '/srfm-global-settings',
59 [
60 'methods' => WP_REST_Server::EDITABLE,
61 'callback' => [ $this, 'srfm_save_global_settings' ],
62 'permission_callback' => [ Helper::class, 'get_items_permissions_check' ],
63 ]
64 );
65 register_rest_route(
66 $this->namespace,
67 '/srfm-global-settings',
68 [
69 'methods' => WP_REST_Server::READABLE,
70 'callback' => [ $this, 'srfm_get_general_settings' ],
71 'permission_callback' => [ Helper::class, 'get_items_permissions_check' ],
72 ]
73 );
74 }
75
76 /**
77 * Save global settings options.
78 *
79 * @param WP_REST_Request $request Request object.
80 * @return WP_REST_Response|WP_Error
81 *
82 * @since 0.0.1
83 */
84 public static function srfm_save_global_settings( $request ) {
85
86 $nonce = Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) );
87
88 if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
89 return new WP_Error( 'rest_nonce_invalid', __( 'Nonce verification failed.', 'sureforms' ), [ 'status' => 403 ] );
90 }
91
92 $setting_options = $request->get_params();
93
94 $tab = $setting_options['srfm_tab'] ?? '';
95
96 unset( $setting_options['srfm_tab'] );
97
98 switch ( $tab ) {
99 case 'general-settings':
100 self::srfm_save_general_settings( $setting_options );
101 break;
102 case 'general-settings-dynamic-opt':
103 self::srfm_save_general_settings_dynamic_opt( $setting_options );
104 break;
105 case 'email-settings':
106 self::srfm_save_email_summary_settings( $setting_options );
107 break;
108 case 'security-settings':
109 self::srfm_save_security_settings( $setting_options );
110 break;
111 case 'payments-settings':
112 self::srfm_save_payments_settings( $setting_options );
113 break;
114 case 'mcp-settings':
115 self::srfm_save_mcp_settings( $setting_options );
116 break;
117 case 'form-restriction-settings':
118 self::srfm_save_form_restriction_settings( $setting_options );
119 break;
120 case 'compliance-settings':
121 self::srfm_save_compliance_settings( $setting_options );
122 break;
123 case 'form-confirmation-settings':
124 self::srfm_save_form_confirmation_settings( $setting_options );
125 break;
126 case 'email-notification-settings':
127 self::srfm_save_email_notification_settings( $setting_options );
128 break;
129 default:
130 return new WP_Error( 'srfm_invalid_tab', __( 'Invalid settings tab.', 'sureforms' ), [ 'status' => 400 ] );
131 }
132
133 // update_option() returns false when the stored value already matches
134 // the new value — that is not an error, so we only flag truly invalid
135 // tabs (handled in default above) and always return success here.
136 return new WP_REST_Response(
137 [
138 'data' => __( 'Settings Saved Successfully.', 'sureforms' ),
139 ]
140 );
141 }
142
143 /**
144 * Save General Settings
145 *
146 * @param array<mixed> $setting_options Setting options.
147 * @return bool
148 * @since 0.0.1
149 */
150 public static function srfm_save_general_settings( $setting_options ) {
151
152 $srfm_ip_log = $setting_options['srfm_ip_log'] ?? false;
153 $srfm_form_analytics = $setting_options['srfm_form_analytics'] ?? false;
154 $srfm_bsf_analytics = $setting_options['srfm_bsf_analytics'] ?? false;
155 $srfm_admin_notification = isset( $setting_options['srfm_admin_notification'] ) ? (bool) $setting_options['srfm_admin_notification'] : true;
156 $srfm_form_views_tracking = isset( $setting_options['srfm_form_views_tracking'] ) ? (bool) $setting_options['srfm_form_views_tracking'] : false;
157 // Absent means on, matching Client_Logger::is_enabled(). A save that omits
158 // the key must not be read as the site opting out.
159 $srfm_enable_logs = isset( $setting_options['srfm_enable_logs'] ) ? (bool) $setting_options['srfm_enable_logs'] : true;
160
161 $settings = [
162 'srfm_ip_log' => $srfm_ip_log,
163 'srfm_form_analytics' => $srfm_form_analytics,
164 'srfm_admin_notification' => $srfm_admin_notification,
165 'srfm_form_views_tracking' => $srfm_form_views_tracking,
166 'srfm_enable_logs' => $srfm_enable_logs,
167 ];
168
169 /**
170 * We are updating sureforms_analytics_optin option from the general settings as it has been introduced
171 * as part of general settings. Since the option sureforms_analytics_optin is already available from BSF analytics library
172 * We are updating this independently.
173 *
174 * @since 1.7.0
175 *
176 * @since 2.5.1 - Renamed sureforms_analytics_optin to sureforms_usage_optin.
177 */
178 $analytics_result = self::update_bsf_analytics( $srfm_bsf_analytics );
179
180 $general_result = update_option( 'srfm_general_settings_options', $settings );
181
182 /**
183 * Returns the output of update_bsf_analytics or srfm_general_settings_options option.
184 *
185 * @since 1.7.0
186 */
187 return $analytics_result || $general_result;
188 }
189
190 /**
191 * Toggle BSF analytics usage tracking in WP general settings.
192 *
193 * @param array<mixed> $settings general settings array.
194 * @return bool
195 * @since 1.7.0
196 */
197 public static function update_bsf_analytics( $settings ) {
198 if ( true === $settings ) {
199 $enable_tracking = 'yes';
200 } else {
201 $enable_tracking = '';
202 }
203
204 return update_option( 'sureforms_usage_optin', $enable_tracking );
205 }
206
207 /**
208 * Save General Settings Dynamic Options
209 *
210 * @param array<mixed> $setting_options Setting options.
211 * @return bool
212 * @since 0.0.1
213 */
214 public static function srfm_save_general_settings_dynamic_opt( $setting_options ) {
215 $options_keys = [
216 'srfm_url_block_required_text',
217 'srfm_input_block_required_text',
218 'srfm_input_block_unique_text',
219 'srfm_address_block_required_text',
220 'srfm_phone_block_required_text',
221 'srfm_phone_block_unique_text',
222 'srfm_number_block_required_text',
223 'srfm_textarea_block_required_text',
224 'srfm_multi_choice_block_required_text',
225 'srfm_checkbox_block_required_text',
226 'srfm_gdpr_block_required_text',
227 'srfm_email_block_required_text',
228 'srfm_email_block_unique_text',
229 'srfm_dropdown_block_required_text',
230 'srfm_valid_phone_number',
231 'srfm_valid_url',
232 'srfm_confirm_email_same',
233 'srfm_valid_email',
234 'srfm_textarea_min_chars',
235 'srfm_email_local_max_length',
236 'srfm_email_domain_max_length',
237 'srfm_input_min_value',
238 'srfm_input_max_value',
239 'srfm_dropdown_min_selections',
240 'srfm_dropdown_max_selections',
241 'srfm_multi_choice_min_selections',
242 'srfm_multi_choice_max_selections',
243 ];
244
245 $options_names = [];
246
247 foreach ( $options_keys as $key ) {
248 if ( isset( $setting_options[ $key ] ) ) {
249 $value = $setting_options[ $key ];
250 $options_names[ $key ] = sanitize_text_field( is_scalar( $value ) ? (string) $value : '' );
251 }
252 }
253
254 // Re-sanitize after filter so Pro-injected keys are also covered.
255 $options_to_save = apply_filters( 'srfm_general_dynamic_options_to_save', $options_names, $setting_options );
256 $options_to_save = array_map( 'sanitize_text_field', $options_to_save );
257 return update_option( 'srfm_default_dynamic_block_option', $options_to_save );
258 }
259
260 /**
261 * Save Email Summary Settings
262 *
263 * @param array<mixed> $setting_options Setting options.
264 * @return bool
265 * @since 0.0.1
266 */
267 public static function srfm_save_email_summary_settings( $setting_options ) {
268
269 $srfm_email_summary = $setting_options['srfm_email_summary'] ?? false;
270 $srfm_email_sent_to = sanitize_email( $setting_options['srfm_email_sent_to'] ?? get_option( 'admin_email' ) );
271 $srfm_schedule_report = $setting_options['srfm_schedule_report'] ?? __( 'Monday', 'sureforms' );
272
273 Events_Scheduler::unschedule_events( 'srfm_weekly_scheduled_events' );
274
275 if ( $srfm_email_summary ) {
276 Email_Summary::schedule_weekly_entries_email();
277 }
278
279 return update_option(
280 'srfm_email_summary_settings_options',
281 [
282 'srfm_email_summary' => $srfm_email_summary,
283 'srfm_email_sent_to' => $srfm_email_sent_to,
284 'srfm_schedule_report' => $srfm_schedule_report,
285 ]
286 );
287 }
288
289 /**
290 * Save Security Settings
291 *
292 * @param array<mixed> $setting_options Setting options.
293 * @return bool
294 * @since 0.0.1
295 */
296 public static function srfm_save_security_settings( $setting_options ) {
297
298 $srfm_v2_checkbox_site_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v2_checkbox_site_key'] ?? '' ) );
299 $srfm_v2_checkbox_secret_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v2_checkbox_secret_key'] ?? '' ) );
300 $srfm_v2_invisible_site_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v2_invisible_site_key'] ?? '' ) );
301 $srfm_v2_invisible_secret_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v2_invisible_secret_key'] ?? '' ) );
302 $srfm_v3_site_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v3_site_key'] ?? '' ) );
303 $srfm_v3_secret_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_v3_secret_key'] ?? '' ) );
304 $srfm_cf_appearance_mode = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_cf_appearance_mode'] ?? 'auto' ) );
305 $srfm_cf_turnstile_site_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_cf_turnstile_site_key'] ?? '' ) );
306 $srfm_cf_turnstile_secret_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_cf_turnstile_secret_key'] ?? '' ) );
307 $srfm_hcaptcha_site_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_hcaptcha_site_key'] ?? '' ) );
308 $srfm_hcaptcha_secret_key = sanitize_text_field( Helper::get_string_value( $setting_options['srfm_hcaptcha_secret_key'] ?? '' ) );
309 $srfm_honeypot = $setting_options['srfm_honeypot'] ?? false;
310
311 return update_option(
312 'srfm_security_settings_options',
313 [
314 'srfm_v2_checkbox_site_key' => $srfm_v2_checkbox_site_key,
315 'srfm_v2_checkbox_secret_key' => $srfm_v2_checkbox_secret_key,
316 'srfm_v2_invisible_site_key' => $srfm_v2_invisible_site_key,
317 'srfm_v2_invisible_secret_key' => $srfm_v2_invisible_secret_key,
318 'srfm_v3_site_key' => $srfm_v3_site_key,
319 'srfm_v3_secret_key' => $srfm_v3_secret_key,
320 'srfm_cf_appearance_mode' => $srfm_cf_appearance_mode,
321 'srfm_cf_turnstile_site_key' => $srfm_cf_turnstile_site_key,
322 'srfm_cf_turnstile_secret_key' => $srfm_cf_turnstile_secret_key,
323 'srfm_hcaptcha_site_key' => $srfm_hcaptcha_site_key,
324 'srfm_hcaptcha_secret_key' => $srfm_hcaptcha_secret_key,
325 'srfm_honeypot' => $srfm_honeypot,
326 ]
327 );
328 }
329
330 /**
331 * Save Payments Settings
332 *
333 * Handles saving of both global payment settings (currency, payment_mode) and
334 * gateway-specific settings based on the gateway parameter.
335 *
336 * @param array<mixed> $setting_options Setting options.
337 * @return bool
338 * @since 2.0.0
339 */
340 public static function srfm_save_payments_settings( $setting_options ) {
341 $gateway = isset( $setting_options['gateway'] ) && is_string( $setting_options['gateway'] )
342 ? sanitize_text_field( $setting_options['gateway'] )
343 : 'stripe';
344
345 // Handle global settings (currency, payment_mode).
346 if ( isset( $setting_options['currency'] ) && ! empty( $setting_options['currency'] ) && is_string( $setting_options['currency'] ) ) {
347 $currency = sanitize_text_field( $setting_options['currency'] );
348 Payment_Helper::update_global_setting( 'currency', $currency );
349 }
350
351 $payment_mode = null;
352 if ( isset( $setting_options['payment_mode'] ) && ! empty( $setting_options['payment_mode'] ) && is_string( $setting_options['payment_mode'] ) ) {
353 $payment_mode = sanitize_text_field( $setting_options['payment_mode'] );
354 Payment_Helper::update_global_setting( 'payment_mode', $payment_mode );
355 }
356
357 // Save currency sign position.
358 if ( isset( $setting_options['currency_sign_position'] ) && ! empty( $setting_options['currency_sign_position'] ) && is_string( $setting_options['currency_sign_position'] ) ) {
359 $currency_sign_position = sanitize_text_field( $setting_options['currency_sign_position'] );
360 Payment_Helper::update_global_setting( 'currency_sign_position', $currency_sign_position );
361 }
362
363 // Handle gateway-specific settings.
364 if ( 'stripe' === $gateway ) {
365 $current_stripe_settings = Payment_Helper::get_gateway_settings( 'stripe' );
366
367 // Update payment_mode in stripe settings as well (if provided).
368 if ( null !== $payment_mode ) {
369 $current_stripe_settings['payment_mode'] = $payment_mode;
370 }
371
372 // Connection data (keys, account info) is managed separately via OAuth.
373 return Payment_Helper::update_gateway_settings( 'stripe', $current_stripe_settings );
374 }
375
376 return true;
377 }
378
379 /**
380 * Save MCP Settings
381 *
382 * @param array<mixed> $setting_options Setting options.
383 * @return bool
384 * @since 2.6.0
385 */
386 public static function srfm_save_mcp_settings( $setting_options ) {
387 $srfm_abilities_api = ! empty( $setting_options['srfm_abilities_api'] );
388 $srfm_abilities_api_edit = ! empty( $setting_options['srfm_abilities_api_edit'] );
389 $srfm_abilities_api_delete = ! empty( $setting_options['srfm_abilities_api_delete'] );
390 $srfm_mcp_server = ! empty( $setting_options['srfm_mcp_server'] );
391
392 // Save as individual options for the Abilities API permission_callback.
393 update_option( 'srfm_abilities_api', $srfm_abilities_api );
394 update_option( 'srfm_abilities_api_edit', $srfm_abilities_api_edit );
395 update_option( 'srfm_abilities_api_delete', $srfm_abilities_api_delete );
396 update_option( 'srfm_mcp_server', $srfm_mcp_server );
397
398 // Save grouped option for the settings UI fetch.
399 return update_option(
400 'srfm_mcp_settings_options',
401 [
402 'srfm_abilities_api' => $srfm_abilities_api,
403 'srfm_abilities_api_edit' => $srfm_abilities_api_edit,
404 'srfm_abilities_api_delete' => $srfm_abilities_api_delete,
405 'srfm_mcp_server' => $srfm_mcp_server,
406 ]
407 );
408 }
409
410 /**
411 * Save Form Restriction Settings
412 *
413 * Handles saving of the free Maximum Entries subsection. Pro-only
414 * subsections (IP, Country, Keyword) are persisted via the Pro plugin's
415 * own REST endpoint and option key, so the existing values for those
416 * sub-keys are preserved here via array merge.
417 *
418 * @param array<mixed> $setting_options Setting options.
419 * @return bool
420 * @since 2.9.0
421 */
422 public static function srfm_save_form_restriction_settings( $setting_options ) {
423 $max_entries = isset( $setting_options['max_entries'] ) && is_array( $setting_options['max_entries'] ) ? $setting_options['max_entries'] : [];
424
425 $existing = get_option( 'srfm_form_restriction_settings_options', [] );
426 if ( ! is_array( $existing ) ) {
427 $existing = [];
428 }
429
430 $settings = $existing;
431 $settings['max_entries'] = [
432 'status' => isset( $max_entries['status'] ) ? (bool) $max_entries['status'] : false,
433 'maxEntries' => isset( $max_entries['maxEntries'] ) ? absint( $max_entries['maxEntries'] ) : 0,
434 'message' => isset( $max_entries['message'] ) ? sanitize_textarea_field( (string) $max_entries['message'] ) : __( "This form is now closed as we've received all the entries.", 'sureforms' ),
435 ];
436
437 return update_option( 'srfm_form_restriction_settings_options', $settings );
438 }
439
440 /**
441 * Save Compliance Settings
442 *
443 * Handles saving of global compliance settings that serve as defaults
444 * for newly created forms.
445 *
446 * @param array<mixed> $setting_options Setting options.
447 * @return bool
448 * @since 2.9.0
449 */
450 public static function srfm_save_compliance_settings( $setting_options ) {
451 $settings = [
452 'gdpr' => isset( $setting_options['gdpr'] ) ? (bool) $setting_options['gdpr'] : false,
453 'do_not_store_entries' => isset( $setting_options['do_not_store_entries'] ) ? (bool) $setting_options['do_not_store_entries'] : false,
454 'auto_delete_entries' => isset( $setting_options['auto_delete_entries'] ) ? (bool) $setting_options['auto_delete_entries'] : false,
455 'auto_delete_days' => isset( $setting_options['auto_delete_days'] ) ? absint( $setting_options['auto_delete_days'] ) : 30,
456 ];
457
458 return update_option( 'srfm_compliance_settings_options', $settings );
459 }
460
461 /**
462 * Get default compliance settings.
463 *
464 * @return array<string, mixed>
465 * @since 2.9.0
466 */
467 public static function get_default_compliance_settings() {
468 return [
469 'gdpr' => false,
470 'do_not_store_entries' => false,
471 'auto_delete_entries' => false,
472 'auto_delete_days' => 30,
473 ];
474 }
475
476 /**
477 * Save Form Confirmation Settings
478 *
479 * Handles saving of global form confirmation settings that serve as defaults
480 * for newly created forms.
481 *
482 * @param array<mixed> $setting_options Setting options.
483 * @return bool
484 * @since 2.9.0
485 */
486 public static function srfm_save_form_confirmation_settings( $setting_options ) {
487 $valid_confirmation_types = [ 'same page', 'different page', 'custom url' ];
488 $valid_submission_actions = [ 'hide form', 'reset form' ];
489
490 $message = isset( $setting_options['message'] ) ? wp_kses_post( Helper::get_string_value( $setting_options['message'] ) ) : __( 'Thank you for contacting us! We will be in touch with you shortly.', 'sureforms' );
491
492 // Sanitize query parameters — each item is a key-value object.
493 $query_params = [];
494 if ( isset( $setting_options['query_params'] ) && is_array( $setting_options['query_params'] ) ) {
495 foreach ( $setting_options['query_params'] as $param ) {
496 if ( is_array( $param ) ) {
497 $sanitized_param = [];
498 foreach ( $param as $key => $value ) {
499 $sanitized_param[ sanitize_text_field( $key ) ] = sanitize_text_field( $value );
500 }
501 $query_params[] = $sanitized_param;
502 }
503 }
504 }
505
506 $settings = [
507 'confirmation_type' => isset( $setting_options['confirmation_type'] ) && in_array( $setting_options['confirmation_type'], $valid_confirmation_types, true )
508 ? sanitize_text_field( $setting_options['confirmation_type'] )
509 : 'same page',
510 'message' => $message,
511 'submission_action' => isset( $setting_options['submission_action'] ) && in_array( $setting_options['submission_action'], $valid_submission_actions, true )
512 ? sanitize_text_field( $setting_options['submission_action'] )
513 : 'hide form',
514 'page_url' => isset( $setting_options['page_url'] ) ? esc_url_raw( $setting_options['page_url'] ) : '',
515 'custom_url' => isset( $setting_options['custom_url'] ) ? esc_url_raw( $setting_options['custom_url'] ) : '',
516 'enable_query_params' => ! empty( $setting_options['enable_query_params'] ),
517 'query_params' => $query_params,
518 ];
519
520 return update_option( 'srfm_form_confirmation_settings_options', $settings );
521 }
522
523 /**
524 * Get the default confirmation success message HTML.
525 *
526 * Builds the rich HTML block (icon + heading + description) used as the
527 * initial value for the form confirmation message field. Centralised here
528 * so both the settings GET endpoint and the form-defaults applier share
529 * exactly the same value without duplication.
530 *
531 * @return string
532 * @since 2.9.0
533 */
534 public static function get_default_confirmation_message() {
535 $check_icon = esc_url( plugins_url( 'images/check-icon.svg', SRFM_FILE ) );
536 return '<p style="text-align: center;"><img src="' . $check_icon . '" alt="" aria-hidden="true" /></p><h2 style="text-align: center;">'
537 . esc_html__( 'Thank you', 'sureforms' ) . '</h2><p style="text-align: center;">'
538 . esc_html__( 'Your form has been submitted successfully. We\'ll review your details and get back to you soon.', 'sureforms' ) . '</p>';
539 }
540
541 /**
542 * Get default form confirmation settings.
543 *
544 * @return array<string, mixed>
545 * @since 2.9.0
546 */
547 public static function get_default_form_confirmation_settings() {
548 return [
549 'confirmation_type' => 'same page',
550 'message' => self::get_default_confirmation_message(),
551 'submission_action' => 'hide form',
552 'page_url' => '',
553 'custom_url' => '',
554 'enable_query_params' => false,
555 'query_params' => [],
556 ];
557 }
558
559 /**
560 * Save Email Notification Settings
561 *
562 * Handles saving of global email notification settings that serve as defaults
563 * for newly created forms.
564 *
565 * @param array<mixed> $setting_options Setting options.
566 * @return bool
567 * @since 2.9.0
568 */
569 public static function srfm_save_email_notification_settings( $setting_options ) {
570 $settings = [
571 'email_to' => isset( $setting_options['email_to'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['email_to'] ) ) : '',
572 'subject' => isset( $setting_options['subject'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['subject'] ) ) : '',
573 'email_body' => isset( $setting_options['email_body'] ) ? wp_kses_post( Helper::get_string_value( $setting_options['email_body'] ) ) : '',
574 'from_name' => isset( $setting_options['from_name'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['from_name'] ) ) : '{site_title}',
575 'from_email' => isset( $setting_options['from_email'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['from_email'] ) ) : '{admin_email}',
576 'email_cc' => isset( $setting_options['email_cc'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['email_cc'] ) ) : '',
577 'email_bcc' => isset( $setting_options['email_bcc'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['email_bcc'] ) ) : '',
578 'email_reply_to' => isset( $setting_options['email_reply_to'] ) ? sanitize_text_field( Helper::get_string_value( $setting_options['email_reply_to'] ) ) : '',
579 ];
580
581 return update_option( 'srfm_email_notification_settings_options', $settings );
582 }
583
584 /**
585 * Get default email notification settings.
586 *
587 * @return array<string, mixed>
588 * @since 2.9.0
589 */
590 public static function get_default_email_notification_settings() {
591 return [
592 'email_to' => '{admin_email}',
593 'subject' => sprintf(
594 /* translators: %s: {form_title} smart tag placeholder. */
595 __( 'New Form Submission - %s', 'sureforms' ),
596 '{form_title}'
597 ),
598 'email_body' => '{all_data}',
599 'from_name' => '{site_title}',
600 'from_email' => '{admin_email}',
601 'email_cc' => '{admin_email}',
602 'email_bcc' => '{admin_email}',
603 'email_reply_to' => '{admin_email}',
604 ];
605 }
606
607 /**
608 * Get default form restriction settings.
609 *
610 * Free only ships defaults for the Maximum Entries subsection. Pro-only
611 * subsections (IP, Country, Keyword) ship their own defaults from the
612 * Pro plugin.
613 *
614 * @return array<string, array<string, mixed>>
615 * @since 2.9.0
616 */
617 public static function get_default_form_restriction_settings() {
618 return [
619 'max_entries' => [
620 'status' => false,
621 'maxEntries' => 0,
622 'message' => __( "This form is now closed as we've received all the entries.", 'sureforms' ),
623 ],
624 ];
625 }
626
627 /**
628 * Get Settings Form Data
629 *
630 * @param \WP_REST_Request $request Request object or array containing form data.
631 * @return WP_REST_Response|WP_Error
632 * @since 0.0.1
633 */
634 public static function srfm_get_general_settings( $request ) {
635
636 $nonce = Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) );
637
638 if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
639 return new WP_Error( 'rest_nonce_invalid', __( 'Nonce verification failed.', 'sureforms' ), [ 'status' => 403 ] );
640 }
641
642 $options_to_get = $request->get_param( 'options_to_fetch' );
643
644 $options_to_get = Helper::get_string_value( $options_to_get );
645
646 $options_to_get = explode( ',', $options_to_get );
647
648 // Restrict fetched keys to known plugin options to prevent reading
649 // arbitrary wp_options values (even though manage_options is required).
650 $allowed_options = [
651 'srfm_general_settings_options',
652 'srfm_email_summary_settings_options',
653 'srfm_security_settings_options',
654 'srfm_default_dynamic_block_option',
655 'srfm_mcp_settings_options',
656 'srfm_form_restriction_settings_options',
657 'srfm_compliance_settings_options',
658 'srfm_form_confirmation_settings_options',
659 'srfm_email_notification_settings_options',
660 ];
661 $options_to_get = array_values( array_intersect( array_map( 'sanitize_text_field', $options_to_get ), $allowed_options ) );
662
663 $global_setting_options = [];
664 foreach ( $options_to_get as $option_name ) {
665 $global_setting_options[ $option_name ] = get_option( $option_name, [] );
666 }
667
668 if ( empty( $global_setting_options['srfm_general_settings_options'] ) || ! is_array( $global_setting_options['srfm_general_settings_options'] ) ) {
669 $global_setting_options['srfm_general_settings_options'] = [
670 'srfm_ip_log' => false,
671 'srfm_form_analytics' => false,
672 'srfm_admin_notification' => true,
673 'srfm_form_views_tracking' => false,
674 'srfm_enable_logs' => true,
675 ];
676 }
677
678 if ( ! isset( $global_setting_options['srfm_general_settings_options']['srfm_admin_notification'] ) ) {
679 $global_setting_options['srfm_general_settings_options']['srfm_admin_notification'] = true;
680 }
681
682 if ( ! isset( $global_setting_options['srfm_general_settings_options']['srfm_form_views_tracking'] ) ) {
683 $global_setting_options['srfm_general_settings_options']['srfm_form_views_tracking'] = false;
684 }
685
686 // Back-fill for installs whose option predates the setting. Logging is on by
687 // default, so an absent key means on, not off.
688 if ( ! isset( $global_setting_options['srfm_general_settings_options']['srfm_enable_logs'] ) ) {
689 $global_setting_options['srfm_general_settings_options']['srfm_enable_logs'] = true;
690 }
691
692 $global_setting_options['srfm_log_file_size'] = Client_Logger::get_file_size();
693
694 /**
695 * We have introduced toggle for analytics optin in the general settings.
696 * Hence retrieving the option sureforms_analytics_optin to get current status.
697 *
698 * @since 1.7.0
699 *
700 * @since 2.5.1 - Renamed sureforms_analytics_optin to sureforms_usage_optin.
701 */
702 $srfm_bsf_analytics = get_option( 'sureforms_usage_optin', false ) === 'yes' ? true : false;
703 $global_setting_options['srfm_general_settings_options']['srfm_bsf_analytics'] = $srfm_bsf_analytics;
704
705 if ( empty( $global_setting_options['srfm_default_dynamic_block_option'] ) ) {
706 $global_setting_options['srfm_default_dynamic_block_option'] = Helper::default_dynamic_block_option();
707 }
708 if ( empty( $global_setting_options['srfm_email_summary_settings_options'] ) ) {
709 $global_setting_options['srfm_email_summary_settings_options'] = [
710 'srfm_email_summary' => false,
711 'srfm_email_sent_to' => get_option( 'admin_email' ),
712 'srfm_schedule_report' => __( 'Monday', 'sureforms' ),
713 ];
714 }
715 if ( empty( $global_setting_options['srfm_security_settings_options'] ) ) {
716 $global_setting_options['srfm_security_settings_options'] = [
717 'srfm_v2_checkbox_site_key' => '',
718 'srfm_v2_checkbox_secret_key' => '',
719 'srfm_v2_invisible_site_key' => '',
720 'srfm_v2_invisible_secret_key' => '',
721 'srfm_v3_site_key' => '',
722 'srfm_v3_secret_key' => '',
723 'srfm_cf_appearance_mode' => 'auto',
724 'srfm_cf_turnstile_site_key' => '',
725 'srfm_cf_turnstile_secret_key' => '',
726 'srfm_hcaptcha_site_key' => '',
727 'srfm_hcaptcha_secret_key' => '',
728 'srfm_honeypot' => false,
729 ];
730 }
731
732 if ( empty( $global_setting_options['srfm_mcp_settings_options'] ) ) {
733 $global_setting_options['srfm_mcp_settings_options'] = [
734 'srfm_abilities_api' => (bool) get_option( 'srfm_abilities_api', false ),
735 'srfm_abilities_api_edit' => (bool) get_option( 'srfm_abilities_api_edit', false ),
736 'srfm_abilities_api_delete' => (bool) get_option( 'srfm_abilities_api_delete', false ),
737 'srfm_mcp_server' => (bool) get_option( 'srfm_mcp_server', false ),
738 ];
739 }
740
741 // Get form restriction settings with defaults.
742 $form_restriction_settings = get_option( 'srfm_form_restriction_settings_options', [] );
743 if ( empty( $form_restriction_settings ) || ! is_array( $form_restriction_settings ) ) {
744 $form_restriction_settings = self::get_default_form_restriction_settings();
745 } else {
746 // Merge with defaults to ensure all keys exist.
747 $form_restriction_settings = array_replace_recursive(
748 self::get_default_form_restriction_settings(),
749 $form_restriction_settings
750 );
751 }
752 $global_setting_options['srfm_form_restriction_settings_options'] = $form_restriction_settings;
753
754 // Get compliance settings with defaults.
755 $compliance_settings = get_option( 'srfm_compliance_settings_options', [] );
756 if ( empty( $compliance_settings ) || ! is_array( $compliance_settings ) ) {
757 $compliance_settings = self::get_default_compliance_settings();
758 } else {
759 // Merge with defaults to ensure all keys exist.
760 $compliance_settings = array_merge(
761 self::get_default_compliance_settings(),
762 $compliance_settings
763 );
764 }
765 $global_setting_options['srfm_compliance_settings_options'] = $compliance_settings;
766
767 // Get form confirmation settings with defaults.
768 $form_confirmation_settings = get_option( 'srfm_form_confirmation_settings_options', [] );
769 if ( empty( $form_confirmation_settings ) || ! is_array( $form_confirmation_settings ) ) {
770 $form_confirmation_settings = self::get_default_form_confirmation_settings();
771 } else {
772 // Merge with defaults to ensure all keys exist.
773 $form_confirmation_settings = array_merge(
774 self::get_default_form_confirmation_settings(),
775 $form_confirmation_settings
776 );
777 }
778 // Restore "data:" prefix stripped by wp_kses_post() in previous saves.
779 if ( isset( $form_confirmation_settings['message'] ) && is_string( $form_confirmation_settings['message'] ) && false !== strpos( $form_confirmation_settings['message'], 'src="image/svg+xml;base64' ) ) {
780 $normalized = preg_replace( '/src="image\/svg\+xml;base64/', 'src="data:image/svg+xml;base64', $form_confirmation_settings['message'] );
781 if ( is_string( $normalized ) ) {
782 $form_confirmation_settings['message'] = $normalized;
783 }
784 }
785 $global_setting_options['srfm_form_confirmation_settings_options'] = $form_confirmation_settings;
786
787 // Get email notification settings with defaults.
788 $email_notification_settings = get_option( 'srfm_email_notification_settings_options', [] );
789 if ( empty( $email_notification_settings ) || ! is_array( $email_notification_settings ) ) {
790 $email_notification_settings = self::get_default_email_notification_settings();
791 } else {
792 // Merge with defaults to ensure all keys exist.
793 $email_notification_settings = array_merge(
794 self::get_default_email_notification_settings(),
795 $email_notification_settings
796 );
797 }
798 $global_setting_options['srfm_email_notification_settings_options'] = $email_notification_settings;
799
800 // Apply filter to allow other modules to add their settings.
801 $global_setting_options = apply_filters( 'srfm_global_settings_data', $global_setting_options );
802
803 return new WP_REST_Response( $global_setting_options );
804 }
805
806 }
807