page_slug, // Menu Slug [ $this, 'render_settings_page' ] // Callback function to render the page ); } /** * Registers settings, sections, and fields using the Settings API. */ public function register_settings() { register_setting( $this->option_group, // Option group $this->option_name, // Option name [ $this, 'sanitize_settings' ] // Sanitization callback ); // Stripe Section add_settings_section( 'quiztech_stripe_section', // Section ID __( 'Stripe API Keys', 'quiztech' ), // Section Title '__return_false', // Section callback (optional description) $this->page_slug // Page slug where section appears ); // Stripe Public Key Field add_settings_field( 'quiztech_stripe_public_key', // Field ID __( 'Stripe Public Key', 'quiztech' ), // Field Title [ $this, 'render_text_field' ], // Field render callback $this->page_slug, // Page slug 'quiztech_stripe_section', // Section ID [ // Arguments for callback 'id' => 'quiztech_stripe_public_key', 'option_name' => $this->option_name, 'key' => 'stripe_public_key', 'description' => __( 'Enter your Stripe publishable API key.', 'quiztech' ) ] ); // Stripe Secret Key Field add_settings_field( 'quiztech_stripe_secret_key', // Field ID __( 'Stripe Secret Key', 'quiztech' ), // Field Title [ $this, 'render_text_field' ], // Field render callback $this->page_slug, // Page slug 'quiztech_stripe_section', // Section ID [ // Arguments for callback 'id' => 'quiztech_stripe_secret_key', 'option_name' => $this->option_name, 'key' => 'stripe_secret_key', 'type' => 'password', // Mask the input 'description' => __( 'Enter your Stripe secret API key. This is kept confidential.', 'quiztech' ) ] ); // --- SMTP Section --- add_settings_section( 'quiztech_smtp_section', // Section ID __( 'SMTP Settings', 'quiztech' ), // Section Title [ $this, 'render_smtp_section_description' ], // Section callback for description $this->page_slug // Page slug where section appears ); // SMTP Enabled Field (Checkbox) add_settings_field( 'quiztech_smtp_enabled', __( 'Enable SMTP', 'quiztech' ), [ $this, 'render_checkbox_field' ], // New callback needed $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_enabled', 'option_name' => $this->option_name, 'key' => 'smtp_enabled', 'description' => __( 'Enable sending emails via a custom SMTP server instead of the default WordPress mail function.', 'quiztech' ) ] ); // SMTP Host Field add_settings_field( 'quiztech_smtp_host', __( 'SMTP Host', 'quiztech' ), [ $this, 'render_text_field' ], $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_host', 'option_name' => $this->option_name, 'key' => 'smtp_host', 'description' => __( 'e.g., smtp.example.com', 'quiztech' ) ] ); // SMTP Port Field add_settings_field( 'quiztech_smtp_port', __( 'SMTP Port', 'quiztech' ), [ $this, 'render_text_field' ], // Use text field, sanitize as number later $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_port', 'option_name' => $this->option_name, 'key' => 'smtp_port', 'type' => 'number', 'description' => __( 'e.g., 587 (TLS) or 465 (SSL)', 'quiztech' ) ] ); // SMTP Encryption Field (Select) add_settings_field( 'quiztech_smtp_encryption', __( 'Encryption', 'quiztech' ), [ $this, 'render_select_field' ], // New callback needed $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_encryption', 'option_name' => $this->option_name, 'key' => 'smtp_encryption', 'options' => [ '' => __( 'None', 'quiztech' ), 'ssl' => __( 'SSL', 'quiztech' ), 'tls' => __( 'TLS', 'quiztech' ), ], 'description' => __( 'Select the encryption method.', 'quiztech' ) ] ); // SMTP Auth Field (Checkbox) add_settings_field( 'quiztech_smtp_auth', __( 'Use Authentication', 'quiztech' ), [ $this, 'render_checkbox_field' ], // Reuse callback $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_auth', 'option_name' => $this->option_name, 'key' => 'smtp_auth', 'description' => __( 'Enable if your SMTP server requires a username and password.', 'quiztech' ) ] ); // SMTP Username Field add_settings_field( 'quiztech_smtp_username', __( 'SMTP Username', 'quiztech' ), [ $this, 'render_text_field' ], $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_username', 'option_name' => $this->option_name, 'key' => 'smtp_username', 'description' => __( 'The username for SMTP authentication.', 'quiztech' ) ] ); // SMTP Password Field add_settings_field( 'quiztech_smtp_password', __( 'SMTP Password', 'quiztech' ), [ $this, 'render_text_field' ], $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_password', 'option_name' => $this->option_name, 'key' => 'smtp_password', 'type' => 'password', 'description' => __( 'The password for SMTP authentication. Stored as plain text in the database.', 'quiztech' ) ] ); // SMTP From Address Field add_settings_field( 'quiztech_smtp_from_address', __( 'From Email Address', 'quiztech' ), [ $this, 'render_text_field' ], $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_from_address', 'option_name' => $this->option_name, 'key' => 'smtp_from_address', 'type' => 'email', 'description' => __( 'The email address emails will be sent from.', 'quiztech' ) ] ); // SMTP From Name Field add_settings_field( 'quiztech_smtp_from_name', __( 'From Name', 'quiztech' ), [ $this, 'render_text_field' ], $this->page_slug, 'quiztech_smtp_section', [ 'id' => 'quiztech_smtp_from_name', 'option_name' => $this->option_name, 'key' => 'smtp_from_name', 'description' => __( 'The name emails will be sent from.', 'quiztech' ) ] ); // Future settings sections/fields (e.g., email, defaults) should be registered here. } // End register_settings() /** * Renders the main settings page container and form. */ public function render_settings_page() { ?>

option_group ); // Output setting sections and their fields do_settings_sections( $this->page_slug ); // Output save settings button submit_button( __( 'Save Settings', 'quiztech' ) ); ?>

()

' . esc_html__( 'Configure your SMTP server details for reliable email sending. If disabled, WordPress will use the default PHP mail function.', 'quiztech' ) . '

'; } /** * Renders a checkbox input field for a setting. * Expects args: 'id', 'option_name', 'key', 'description' (optional) * * @param array $args Arguments passed from add_settings_field. */ public function render_checkbox_field( $args ) { $options = get_option( $args['option_name'], [] ); $checked = isset( $options[ $args['key'] ] ) && $options[ $args['key'] ] ? 'checked' : ''; ?> /> label), 'description' (optional) * * @param array $args Arguments passed from add_settings_field. */ public function render_select_field( $args ) { $options = get_option( $args['option_name'], [] ); $value = isset( $options[ $args['key'] ] ) ? $options[ $args['key'] ] : ''; ?>

'sanitize_text_field', 'smtp_port' => 'absint', // Sanitize as integer 'smtp_encryption' => 'sanitize_key', // 'ssl', 'tls', or '' 'smtp_username' => 'sanitize_text_field', 'smtp_password' => 'sanitize_text_field', // Keep as text, WP handles display 'smtp_from_address' => 'sanitize_email', 'smtp_from_name' => 'sanitize_text_field', ]; foreach ( $smtp_fields as $key => $sanitize_callback ) { if ( isset( $input[ $key ] ) ) { $sanitized_input[ $key ] = call_user_func( $sanitize_callback, $input[ $key ] ); } } // Checkboxes (only save if present and value is '1') $checkbox_fields = [ 'smtp_enabled', 'smtp_auth' ]; foreach ( $checkbox_fields as $key ) { $sanitized_input[ $key ] = ( isset( $input[ $key ] ) && $input[ $key ] === '1' ) ? 1 : 0; } // Validate encryption value if ( ! in_array( $sanitized_input['smtp_encryption'], [ '', 'ssl', 'tls' ], true ) ) { $sanitized_input['smtp_encryption'] = ''; // Default to none if invalid } // Future settings added should have their sanitization logic implemented here. return $sanitized_input; } /** * Handles the AJAX request to send a test email. */ public function handle_send_test_email_ajax() { check_ajax_referer( 'quiztech_test_email_nonce', '_ajax_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Permission denied.', 'quiztech' ) ], 403 ); } $admin_email = get_option( 'admin_email' ); if ( ! is_email( $admin_email ) ) { wp_send_json_error( [ 'message' => __( 'Invalid site administrator email address.', 'quiztech' ) ] ); } $subject = __( 'Quiztech SMTP Test Email', 'quiztech' ); $message = __( 'This is a test email sent from the Quiztech plugin settings page to verify your SMTP configuration.', 'quiztech' ); $headers = []; // Can add headers if needed, e.g., Content-Type // Temporarily hook into phpmailer to capture errors $error_message = ''; add_action( 'wp_mail_failed', function ( $wp_error ) use ( &$error_message ) { if ( is_wp_error( $wp_error ) ) { $error_message = $wp_error->get_error_message(); } }, 10, 1 ); $sent = wp_mail( $admin_email, $subject, $message, $headers ); // Remove the temporary hook // Note: Removing anonymous functions requires more complex handling (e.g., storing the closure in a property). // For simplicity in this test function, we'll leave it, but be aware it persists for the request. // A better approach for production code might involve a dedicated class or named function. // remove_action( 'wp_mail_failed', $this->capture_wp_mail_error_closure ); // Example if stored if ( $sent ) { wp_send_json_success(); } else { $error_to_send = ! empty( $error_message ) ? $error_message : __( 'The email could not be sent. Check your SMTP settings and server logs.', 'quiztech' ); wp_send_json_error( [ 'message' => $error_to_send ] ); } } }