'array', 'sanitize_callback' => array( $this, 'sanitize_general_settings' ), ) ); // Email Templates. register_setting( 'affcf_email_settings', 'affcf_email_templates', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_email_templates' ), ) ); // Default Pages. register_setting( 'affcf_pages_settings', 'affcf_default_pages', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_pages_settings' ), ) ); // Security Settings. register_setting( 'affcf_security_settings', 'affcf_security_settings', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_security_settings' ), ) ); // CAPTCHA Settings. register_setting( 'affcf_captcha_settings', 'affcf_captcha_settings', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_captcha_settings' ), ) ); // Submission Limits. register_setting( 'affcf_submission_limits', 'affcf_submission_limits', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_submission_limits' ), ) ); // Rate Limiting. register_setting( 'affcf_rate_limit_settings', 'affcf_rate_limit_settings', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_rate_limit_settings' ), ) ); // Error Messages. register_setting( 'affcf_error_messages', 'affcf_error_messages', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_error_messages' ), ) ); } /** * Sanitize general settings * * @param array $input Input data. */ public function sanitize_general_settings( $input ) { $sanitized = array(); $sanitized['auto_save_enabled'] = ! empty( $input['auto_save_enabled'] ); $sanitized['auto_save_interval'] = absint( $input['auto_save_interval'] ?? 10 ); $sanitized['enforce_unique_titles'] = ! empty( $input['enforce_unique_titles'] ); $sanitized['draft_cleanup_days'] = absint( $input['draft_cleanup_days'] ?? 30 ); $sanitized['default_post_status'] = sanitize_text_field( $input['default_post_status'] ?? 'pending' ); $sanitized['allow_guest_submissions'] = ! empty( $input['allow_guest_submissions'] ); // Sanitize allowed submission roles. $sanitized['allowed_submission_roles'] = isset( $input['allowed_submission_roles'] ) && is_array( $input['allowed_submission_roles'] ) ? array_map( 'sanitize_text_field', $input['allowed_submission_roles'] ) : array(); return $sanitized; } /** * Sanitize email templates * * @param array $input Input data. */ public function sanitize_email_templates( $input ) { $sanitized = array(); $templates = array( 'submission_received', 'post_published', 'post_rejected', 'admin_notification' ); foreach ( $templates as $template ) { if ( isset( $input[ $template ] ) ) { $sanitized[ $template ] = array( 'enabled' => ! empty( $input[ $template ]['enabled'] ), 'subject' => sanitize_text_field( $input[ $template ]['subject'] ?? '' ), 'message' => wp_kses_post( $input[ $template ]['message'] ?? '' ), ); } } return $sanitized; } /** * Sanitize pages settings * * @param array $input Input data. * @return array Sanitized settings. */ public function sanitize_pages_settings( $input ) { $sanitized = array(); $sanitized['dashboard_page_id'] = absint( $input['dashboard_page_id'] ?? 0 ); $sanitized['submit_page_id'] = absint( $input['submit_page_id'] ?? 0 ); $sanitized['edit_page_id'] = absint( $input['edit_page_id'] ?? 0 ); $sanitized['custom_dashboard_page_id'] = absint( $input['custom_dashboard_page_id'] ?? 0 ); $sanitized['custom_submit_page_id'] = absint( $input['custom_submit_page_id'] ?? 0 ); $sanitized['custom_edit_page_id'] = absint( $input['custom_edit_page_id'] ?? 0 ); return $sanitized; } /** * Sanitize security settings * * @param array $input Input data. * @return array Sanitized settings. */ public function sanitize_security_settings( $input ) { $sanitized = array(); $sanitized['direct_publish_roles'] = is_array( $input['direct_publish_roles'] ?? array() ) ? array_map( 'sanitize_text_field', $input['direct_publish_roles'] ) : array(); $sanitized['enable_honeypot'] = ! empty( $input['enable_honeypot'] ); $sanitized['enable_ip_logging'] = ! empty( $input['enable_ip_logging'] ); return $sanitized; } /** * Sanitize CAPTCHA settings * * @param array $input Input data. * @return array Sanitized CAPTCHA settings. */ public function sanitize_captcha_settings( $input ) { $sanitized = array(); $sanitized['enabled'] = ! empty( $input['enabled'] ); $sanitized['site_key'] = sanitize_text_field( $input['site_key'] ?? '' ); $sanitized['secret_key'] = sanitize_text_field( $input['secret_key'] ?? '' ); // Sanitize and validate score_threshold (must be between 0.0 and 1.0). $score = floatval( $input['score_threshold'] ?? 0.5 ); $sanitized['score_threshold'] = max( 0.0, min( 1.0, $score ) ); return $sanitized; } /** * Sanitize error messages * * @param array $input Input data. * @return array Sanitized messages. */ public function sanitize_error_messages( $input ) { if ( ! is_array( $input ) ) { return array(); } return array_map( 'sanitize_text_field', $input ); } /** * Sanitize submission limits settings * * @param array $input Input data. * @return array Sanitized submission limits. */ public function sanitize_submission_limits( $input ) { $sanitized = array(); // Global limit. $sanitized['global_limit_enabled'] = ! empty( $input['global_limit_enabled'] ); $sanitized['global_limit_count'] = absint( $input['global_limit_count'] ?? 20 ); // Time-based limit. $sanitized['time_based_enabled'] = ! empty( $input['time_based_enabled'] ); $sanitized['time_based_period'] = in_array( $input['time_based_period'] ?? 'month', array( 'day', 'week', 'month' ), true ) ? $input['time_based_period'] : 'month'; $sanitized['time_based_limit'] = absint( $input['time_based_limit'] ?? 10 ); // Per-form limits. $sanitized['per_form_limits'] = array(); if ( ! empty( $input['per_form_limits'] ) && is_array( $input['per_form_limits'] ) ) { foreach ( $input['per_form_limits'] as $form_id => $limit_data ) { $sanitized['per_form_limits'][ absint( $form_id ) ] = array( 'enabled' => ! empty( $limit_data['enabled'] ), 'limit' => absint( $limit_data['limit'] ?? 5 ), ); } } return $sanitized; } /** * Sanitize rate limit settings * * @param array $input Input data. * @return array Sanitized settings. */ public function sanitize_rate_limit_settings( $input ) { $sanitized = array(); $sanitized['enabled'] = ! empty( $input['enabled'] ); $sanitized['attempts_per_hour'] = absint( $input['attempts_per_hour'] ?? 5 ); $sanitized['attempts_per_day'] = absint( $input['attempts_per_day'] ?? 20 ); $sanitized['lockout_duration'] = absint( $input['lockout_duration'] ?? 3600 ); // Validate ranges. if ( $sanitized['attempts_per_hour'] < 1 ) { $sanitized['attempts_per_hour'] = 5; } if ( $sanitized['attempts_per_day'] < 1 ) { $sanitized['attempts_per_day'] = 20; } if ( $sanitized['lockout_duration'] < 300 ) { $sanitized['lockout_duration'] = 300; // Min 5 minutes. } if ( $sanitized['lockout_duration'] > 86400 ) { $sanitized['lockout_duration'] = 86400; // Max 24 hours. } return $sanitized; } /** * Get setting value * * @param string $key Setting key. * @param mixed $default_value Default value. */ public static function get( $key, $default_value = null ) { $settings = get_option( 'affcf_settings', array() ); return $settings[ $key ] ?? $default_value; } /** * Update setting value * * @param string $key Setting key. * @param mixed $value Setting value. */ public static function update( $key, $value ) { $settings = get_option( 'affcf_settings', array() ); $settings[ $key ] = $value; return update_option( 'affcf_settings', $settings ); } }