'', 'cache_duration' => 24, 'allowed_statuses' => [ 'valid', 'risky', 'unknown', 'unavailable' ], 'service_enabled'=> false, 'license_accepted' => false, 'license_accepted_at' => 0, 'license_accepted_by' => 0, 'cf7_forms' => [], // Contact Form 7 IDs 'wc_enable' => true, // WooCommerce checkout 'reg_enable' => true, // WP registration 'gf_forms' => [], // Gravity Forms IDs 'wpf_forms' => [], // WPForms IDs 'nf_forms' => [], // Ninja Forms IDs ]; public static function init() { add_action( 'admin_init', [ __CLASS__, 'register_settings' ] ); } public static function register_settings() { register_setting( 'zbounce_eval_settings', self::OPTION_KEY, [ 'sanitize_callback' => [ __CLASS__, 'sanitize_settings' ] ] ); // --- API Section --- add_settings_section( 'api_settings', __( 'API Configuration', 'zbounce-email-validator' ), null, 'zbounce-email-validator' ); add_settings_field( 'api_key', __( 'Purchased ZBounce API key', 'zbounce-email-validator' ), [ __CLASS__, 'render_api_key_field' ], 'zbounce-email-validator', 'api_settings' ); add_settings_field( 'cache_duration', __( 'Cache Duration', 'zbounce-email-validator' ), [ __CLASS__, 'render_cache_duration_field' ], 'zbounce-email-validator', 'api_settings' ); add_settings_field( 'service_enabled', __( 'Automatic form verification', 'zbounce-email-validator' ), [ __CLASS__, 'render_service_enabled_field' ], 'zbounce-email-validator', 'api_settings' ); add_settings_field( 'allowed_statuses', __( 'Accepted verification results', 'zbounce-email-validator' ), [ __CLASS__, 'render_allowed_statuses_field' ], 'zbounce-email-validator', 'api_settings' ); add_settings_field( 'license_accepted', __( 'License agreement', 'zbounce-email-validator' ), [ __CLASS__, 'render_license_field' ], 'zbounce-email-validator', 'api_settings' ); // --- Advanced Integrations --- add_settings_section( 'advanced_settings', __( 'Advanced Integrations', 'zbounce-email-validator' ), null, 'zbounce-email-validator' ); // CF7 add_settings_field( 'cf7_forms', __( 'Contact Form 7 to Validate', 'zbounce-email-validator' ), [ __CLASS__, 'render_cf7_forms_field' ], 'zbounce-email-validator', 'advanced_settings' ); // WooCommerce add_settings_field( 'wc_enable', __( 'Enable WooCommerce Checkout', 'zbounce-email-validator' ), [ __CLASS__, 'render_wc_enable_field' ], 'zbounce-email-validator', 'advanced_settings' ); // WP Registration add_settings_field( 'reg_enable', __( 'Enable WP Registration', 'zbounce-email-validator' ), [ __CLASS__, 'render_reg_enable_field' ], 'zbounce-email-validator', 'advanced_settings' ); // Gravity Forms, WPForms, Ninja Forms add_settings_field( 'gf_forms', __( 'Gravity Forms to Validate', 'zbounce-email-validator' ), [ __CLASS__, 'render_gf_forms_field' ], 'zbounce-email-validator', 'advanced_settings' ); add_settings_field( 'wpf_forms', __( 'WPForms to Validate', 'zbounce-email-validator' ), [ __CLASS__, 'render_wpf_forms_field' ], 'zbounce-email-validator', 'advanced_settings' ); add_settings_field( 'nf_forms', __( 'Ninja Forms to Validate', 'zbounce-email-validator' ), [ __CLASS__, 'render_nf_forms_field' ], 'zbounce-email-validator', 'advanced_settings' ); } public static function render_api_key_field() { $s = self::get_settings(); ?>
'publish' ] ); if ( empty( $sel ) ) { foreach ( $forms as $f ) { $sel[] = intval( $f->id() ); } } foreach ( $forms as $f ) { printf( '
' . esc_html__( 'Contact Form 7 not detected.', 'zbounce-email-validator' ) . '
'; } echo '' . esc_html__( 'Select the forms to validate. An empty selection validates all Contact Form 7 forms; disable external verification to stop all checks.', 'zbounce-email-validator' ) . '
'; } public static function render_wc_enable_field() { $s = self::get_settings(); $on = ! empty( $s['wc_enable'] ); ?> %4$s (ID:%2$d)' . esc_html__( 'Gravity Forms not detected.', 'zbounce-email-validator' ) . '
'; } echo '' . esc_html__( 'Select Gravity Forms by ID', 'zbounce-email-validator' ) . '
'; } public static function render_wpf_forms_field() { $s = self::get_settings(); $sel = (array) $s['wpf_forms']; $posts = get_posts( [ 'post_type' => 'wpforms', 'posts_per_page' => -1, ] ); if ( $posts ) { foreach ( $posts as $p ) { printf( '' . esc_html__( 'WPForms not detected.', 'zbounce-email-validator' ) . '
'; } echo '' . esc_html__( 'Select WPForms by ID', 'zbounce-email-validator' ) . '
'; } public static function is_api_configured(): bool { $settings = self::get_settings(); return ! empty( $settings['license_accepted'] ) && '' !== trim( $settings['api_key'] ); } public static function is_verification_enabled(): bool { return self::is_api_configured() && ! empty( self::get_settings()['service_enabled'] ); } // Preserve the previous strict behavior for callers using the old method. public static function is_connected(): bool { return self::is_verification_enabled(); } public static function can_request_api( bool $manual = false ): bool { return $manual ? self::is_api_configured() && current_user_can( 'manage_options' ) : self::is_verification_enabled(); } public static function sanitize_settings( $input ): array { $input = is_array( $input ) ? $input : []; $clean = self::DEFAULT_SETTINGS; $clean['api_key'] = isset( $input['api_key'] ) && is_string( $input['api_key'] ) ? sanitize_text_field( $input['api_key'] ) : ''; $clean['cache_duration'] = max( 1, min( 168, absint( $input['cache_duration'] ?? 24 ) ) ); foreach ( [ 'service_enabled', 'wc_enable', 'reg_enable' ] as $field ) { $clean[ $field ] = ! empty( $input[ $field ] ); } foreach ( [ 'cf7_forms', 'gf_forms', 'wpf_forms', 'nf_forms' ] as $field ) { $clean[ $field ] = array_values( array_unique( array_filter( array_map( 'absint', (array) ( $input[ $field ] ?? [] ) ) ) ) ); } if ( array_key_exists( 'allowed_statuses', $input ) ) { $values = is_array( $input['allowed_statuses'] ) ? $input['allowed_statuses'] : []; $clean['allowed_statuses'] = array_values( array_intersect( array_keys( self::status_labels() ), array_filter( $values, 'is_string' ) ) ); } $previous = self::get_settings(); $clean['license_accepted'] = isset( $input['license_accepted'] ) && in_array( $input['license_accepted'], [ '1', 1, true ], true ); if ( $clean['license_accepted'] ) { $clean['license_accepted_at'] = ! empty( $previous['license_accepted_at'] ) && ! empty( $previous['license_accepted'] ) ? absint( $previous['license_accepted_at'] ) : time(); $clean['license_accepted_by'] = ! empty( $previous['license_accepted_at'] ) && ! empty( $previous['license_accepted'] ) ? absint( $previous['license_accepted_by'] ) : get_current_user_id(); } elseif ( $clean['service_enabled'] ) { $clean['service_enabled'] = false; add_settings_error( self::OPTION_KEY, 'zbounce_eval_license_required', __( 'Accept the ZBounce service license agreement before enabling verification.', 'zbounce-email-validator' ) ); } if ( $clean['service_enabled'] && '' === $clean['api_key'] ) { $clean['service_enabled'] = false; add_settings_error( self::OPTION_KEY, 'zbounce_eval_missing_key', __( 'Enter your purchased API key before enabling external verification.', 'zbounce-email-validator' ) ); } return $clean; } public static function status_labels(): array { return [ 'valid' => __( 'Valid — mailbox confirmed', 'zbounce-email-validator' ), 'risky' => __( 'Risky — accept-all domain', 'zbounce-email-validator' ), 'disposable' => __( 'Disposable email', 'zbounce-email-validator' ), 'invalid' => __( 'Invalid email format', 'zbounce-email-validator' ), 'no_mx' => __( 'Domain does not accept mail', 'zbounce-email-validator' ), 'mailbox_not_found' => __( 'Mailbox does not exist', 'zbounce-email-validator' ), 'unknown' => __( 'Unknown — mailbox could not be confirmed', 'zbounce-email-validator' ), 'unavailable' => __( 'API unavailable — connection, key or balance problem', 'zbounce-email-validator' ), ]; } public static function render_allowed_statuses_field() { $settings = self::get_settings(); // The hidden marker permits saving an intentionally empty selection. printf( '', esc_attr( self::OPTION_KEY ) ); foreach ( self::status_labels() as $status => $label ) { printf( '' . esc_html__( 'Checked results pass; unchecked results reject the submission. Rules apply to every enabled integration, including cached results. Native form email-format validation still applies. API availability is separate from an unknown mailbox result.', 'zbounce-email-validator' ) . '
'; } public static function render_license_field() { $settings = self::get_settings(); printf( ' ', esc_attr( self::OPTION_KEY ), checked( ! empty( $settings['license_accepted'] ), true, false ), esc_html__( 'I accept the ZBounce service license agreement.', 'zbounce-email-validator' ) ); printf( '%s', esc_url( 'https://zbounce.net/license.html' ), esc_html__( 'Read the license agreement', 'zbounce-email-validator' ) ); echo '' . esc_html__( 'Acceptance is required before using ZBounce verification. Removing acceptance stops all API requests.', 'zbounce-email-validator' ) . '
'; } public static function render_balance_field() { if ( ! self::is_api_configured() ) { /* translators: %s: number of remaining verification credits. */ echo '' . esc_html( sprintf( __( 'Remaining credits: %s', 'zbounce-email-validator' ), '—' ) ) . '' . esc_html__( 'Accept the agreement and save your API key to see the balance.', 'zbounce-email-validator' ) . '
'; return; } $balance = ApiClient::get_balance(); if ( isset( $balance['remaining'] ) ) { /* translators: %s: number of remaining verification credits. */ echo '' . esc_html( sprintf( __( 'Remaining credits: %s', 'zbounce-email-validator' ), number_format_i18n( $balance['remaining'] ) ) ) . ''; } else { echo '' . esc_html__( 'Balance unavailable. Check your key and connection.', 'zbounce-email-validator' ) . ''; } } public static function render_service_enabled_field() { $s = self::get_settings(); ?> form()->get_forms() as $form ) { $id = absint( $form->get_id() ); printf( '' . esc_html__( 'Ninja Forms not detected.', 'zbounce-email-validator' ) . '
'; } echo '' . esc_html__( 'Select Ninja Forms by ID', 'zbounce-email-validator' ) . '
'; } }