PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.10.1
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.10.1
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.10.1, at inc/global-settings/global-settings.php

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