HEX
Server: nginx/1.24.0
System: Linux 0c1023d6c65e 6.8.0-137-generic #137-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 17 20:28:23 UTC 2026 x86_64
User: root (0)
PHP: 8.3.33
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/mu-plugins/ethnic-recaptcha.php
<?php
/**
 * Shared Google reCAPTCHA v2 checkbox support for public forms.
 *
 * @package EthnicInfotech
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! function_exists( 'ethnic_recaptcha_option_name' ) ) {
	function ethnic_recaptcha_option_name() {
		return 'ethnic_recaptcha_settings';
	}
}

if ( ! function_exists( 'ethnic_recaptcha_default_settings' ) ) {
	function ethnic_recaptcha_default_settings() {
		return array(
			'enabled'                   => 1,
			'site_key'                  => '',
			'secret_key'                => '',
			'contact_form_7_enabled'    => 1,
			'proposal_request_enabled'  => 1,
			'resource_download_enabled' => 1,
			'wordpress_comments_enabled'=> 1,
		);
	}
}

if ( ! function_exists( 'ethnic_recaptcha_settings' ) ) {
	function ethnic_recaptcha_settings() {
		$defaults = ethnic_recaptcha_default_settings();
		$stored   = get_option( ethnic_recaptcha_option_name(), array() );
		$stored   = is_array( $stored ) ? $stored : array();
		$settings = wp_parse_args( $stored, $defaults );

		$settings['enabled']                   = ! empty( $settings['enabled'] ) ? 1 : 0;
		$settings['contact_form_7_enabled']    = ! empty( $settings['contact_form_7_enabled'] ) ? 1 : 0;
		$settings['proposal_request_enabled']  = ! empty( $settings['proposal_request_enabled'] ) ? 1 : 0;
		$settings['resource_download_enabled'] = ! empty( $settings['resource_download_enabled'] ) ? 1 : 0;
		$settings['wordpress_comments_enabled']= ! empty( $settings['wordpress_comments_enabled'] ) ? 1 : 0;
		$settings['site_key']                  = trim( sanitize_text_field( (string) $settings['site_key'] ) );
		$settings['secret_key']                = trim( sanitize_text_field( (string) $settings['secret_key'] ) );

		return $settings;
	}
}

if ( ! function_exists( 'ethnic_recaptcha_context_map' ) ) {
	function ethnic_recaptcha_context_map() {
		return array(
			'contact_form_7'    => 'contact_form_7_enabled',
			'proposal_request'  => 'proposal_request_enabled',
			'resource_download' => 'resource_download_enabled',
			'wordpress_comments'=> 'wordpress_comments_enabled',
		);
	}
}

if ( ! function_exists( 'ethnic_recaptcha_source_labels' ) ) {
	function ethnic_recaptcha_source_labels() {
		return array(
			'admin'            => 'Admin settings',
			'ethnic_constants' => 'ETHNIC constants',
		);
	}
}

if ( ! function_exists( 'ethnic_recaptcha_configuration_source_label' ) ) {
	function ethnic_recaptcha_configuration_source_label( $source ) {
		$labels = ethnic_recaptcha_source_labels();

		return isset( $labels[ $source ] ) ? $labels[ $source ] : 'Not configured';
	}
}

if ( ! function_exists( 'ethnic_recaptcha_page_url' ) ) {
	function ethnic_recaptcha_page_url( $args = array() ) {
		$url = admin_url( 'options-general.php?page=ethnic-shared-recaptcha' );

		if ( empty( $args ) ) {
			return $url;
		}

		return add_query_arg( $args, $url );
	}
}

if ( ! function_exists( 'ethnic_recaptcha_configuration' ) ) {
	function ethnic_recaptcha_configuration() {
		static $configuration = null;

		if ( null !== $configuration ) {
			return $configuration;
		}

		$settings      = ethnic_recaptcha_settings();
		$configuration = array(
			'site_key'   => '',
			'secret_key' => '',
			'source'     => '',
		);

		$candidates = array(
			array(
				'site_key'   => $settings['site_key'],
				'secret_key' => $settings['secret_key'],
				'source'     => 'admin',
			),
			array(
				'site_key'   => defined( 'ETHNIC_RECAPTCHA_SITE_KEY' ) ? (string) ETHNIC_RECAPTCHA_SITE_KEY : '',
				'secret_key' => defined( 'ETHNIC_RECAPTCHA_SECRET_KEY' ) ? (string) ETHNIC_RECAPTCHA_SECRET_KEY : '',
				'source'     => 'ethnic_constants',
			),
		);

		foreach ( $candidates as $candidate ) {
			$site_key   = trim( sanitize_text_field( (string) $candidate['site_key'] ) );
			$secret_key = trim( sanitize_text_field( (string) $candidate['secret_key'] ) );

			if ( '' === $site_key || '' === $secret_key ) {
				continue;
			}

			$configuration = array(
				'site_key'   => $site_key,
				'secret_key' => $secret_key,
				'source'     => (string) $candidate['source'],
			);
			break;
		}

		return $configuration;
	}
}

if ( ! function_exists( 'ethnic_recaptcha_is_context_enabled' ) ) {
	function ethnic_recaptcha_is_context_enabled( $context = '' ) {
		$settings = ethnic_recaptcha_settings();

		if ( empty( $settings['enabled'] ) ) {
			return false;
		}

		if ( '' === $context ) {
			return true;
		}

		$map = ethnic_recaptcha_context_map();

		if ( ! isset( $map[ $context ] ) ) {
			return true;
		}

		return ! empty( $settings[ $map[ $context ] ] );
	}
}

if ( ! function_exists( 'ethnic_recaptcha_is_enabled' ) ) {
	function ethnic_recaptcha_is_enabled( $context = '' ) {
		$configuration = ethnic_recaptcha_configuration();

		return ethnic_recaptcha_is_context_enabled( $context )
			&& '' !== $configuration['site_key']
			&& '' !== $configuration['secret_key'];
	}
}

if ( ! function_exists( 'ethnic_recaptcha_site_key' ) ) {
	function ethnic_recaptcha_site_key() {
		$configuration = ethnic_recaptcha_configuration();

		return $configuration['site_key'];
	}
}

if ( ! function_exists( 'ethnic_recaptcha_secret_key' ) ) {
	function ethnic_recaptcha_secret_key() {
		$configuration = ethnic_recaptcha_configuration();

		return $configuration['secret_key'];
	}
}

if ( ! function_exists( 'ethnic_recaptcha_has_enabled_forms' ) ) {
	function ethnic_recaptcha_has_enabled_forms() {
		return ethnic_recaptcha_is_enabled( 'contact_form_7' )
			|| ethnic_recaptcha_is_enabled( 'proposal_request' )
			|| ethnic_recaptcha_is_enabled( 'resource_download' )
			|| ethnic_recaptcha_is_enabled( 'wordpress_comments' );
	}
}

if ( ! function_exists( 'ethnic_recaptcha_mask_value' ) ) {
	function ethnic_recaptcha_mask_value( $value, $visible_chars = 6 ) {
		$value = trim( (string) $value );

		if ( '' === $value ) {
			return 'Not set';
		}

		$length = strlen( $value );

		if ( $length <= $visible_chars ) {
			return $value;
		}

		return str_repeat( '•', max( 0, $length - $visible_chars ) ) . substr( $value, -1 * $visible_chars );
	}
}

if ( ! function_exists( 'ethnic_recaptcha_widget_markup' ) ) {
	function ethnic_recaptcha_widget_markup( $context, $args = array() ) {
		$context = sanitize_key( $context );

		if ( ! ethnic_recaptcha_is_enabled( $context ) ) {
			return '';
		}

		$args = wp_parse_args(
			$args,
			array(
				'wrapper_class'  => '',
				'widget_class'   => '',
				'message_class'  => 'ethnic-recaptcha-message',
				'include_message' => false,
				'theme'          => 'light',
				'size'           => 'normal',
			)
		);

		$wrapper_classes = trim( 'ethnic-recaptcha-field ' . $args['wrapper_class'] );
		$widget_classes  = trim( 'ethnic-recaptcha-widget ' . $args['widget_class'] );
		$theme           = in_array( $args['theme'], array( 'light', 'dark' ), true ) ? $args['theme'] : 'light';
		$size            = in_array( $args['size'], array( 'normal', 'compact' ), true ) ? $args['size'] : 'normal';

		ob_start();
		?>
		<div class="<?php echo esc_attr( $wrapper_classes ); ?>">
			<div
				class="<?php echo esc_attr( $widget_classes ); ?>"
				data-ethnic-recaptcha-widget="true"
				data-sitekey="<?php echo esc_attr( ethnic_recaptcha_site_key() ); ?>"
				data-theme="<?php echo esc_attr( $theme ); ?>"
				data-size="<?php echo esc_attr( $size ); ?>"
			></div>
			<?php if ( ! empty( $args['include_message'] ) ) : ?>
				<div class="<?php echo esc_attr( $args['message_class'] ); ?>" data-ethnic-recaptcha-message hidden></div>
			<?php endif; ?>
		</div>
		<?php

		return trim( (string) ob_get_clean() );
	}
}

if ( ! function_exists( 'ethnic_recaptcha_render_widget' ) ) {
	function ethnic_recaptcha_render_widget( $context, $args = array() ) {
		echo ethnic_recaptcha_widget_markup( $context, $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}
}

if ( ! function_exists( 'ethnic_recaptcha_verify_submission' ) ) {
	function ethnic_recaptcha_verify_submission( $expected_action = '' ) {
		$expected_action = sanitize_key( $expected_action );

		if ( ! ethnic_recaptcha_is_enabled( $expected_action ) ) {
			return true;
		}

		$token = isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : '';

		if ( '' === $token ) {
			return new WP_Error( 'ethnic_recaptcha_missing_token', 'The reCAPTCHA token is missing.' );
		}

		$response = wp_remote_post(
			'https://www.google.com/recaptcha/api/siteverify',
			array(
				'timeout' => 15,
				'body'    => array(
					'secret'   => ethnic_recaptcha_secret_key(),
					'response' => $token,
					'remoteip' => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return new WP_Error( 'ethnic_recaptcha_request_failed', 'The reCAPTCHA request failed.', $response );
		}

		if ( 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
			return new WP_Error( 'ethnic_recaptcha_bad_response', 'The reCAPTCHA verification response was invalid.', $response );
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );

		if ( ! is_array( $body ) || empty( $body['success'] ) ) {
			return new WP_Error( 'ethnic_recaptcha_failed', 'The reCAPTCHA verification did not succeed.', $body );
		}

		return $body;
	}
}

if ( ! function_exists( 'ethnic_recaptcha_disable_cf7_builtin_recaptcha' ) ) {
	function ethnic_recaptcha_disable_cf7_builtin_recaptcha() {
		if ( ! ethnic_recaptcha_is_context_enabled( 'contact_form_7' ) ) {
			return;
		}

		if ( function_exists( 'wpcf7_recaptcha_enqueue_scripts' ) ) {
			remove_action( 'wp_enqueue_scripts', 'wpcf7_recaptcha_enqueue_scripts', 20 );
		}

		if ( function_exists( 'wpcf7_recaptcha_add_hidden_fields' ) ) {
			remove_filter( 'wpcf7_form_hidden_fields', 'wpcf7_recaptcha_add_hidden_fields', 100 );
		}

		if ( function_exists( 'wpcf7_recaptcha_verify_response' ) ) {
			remove_filter( 'wpcf7_spam', 'wpcf7_recaptcha_verify_response', 9 );
		}
	}

	add_action( 'plugins_loaded', 'ethnic_recaptcha_disable_cf7_builtin_recaptcha', 50 );
}

if ( ! function_exists( 'ethnic_recaptcha_append_cf7_widget' ) ) {
	function ethnic_recaptcha_append_cf7_widget( $content ) {
		if ( ! ethnic_recaptcha_is_enabled( 'contact_form_7' ) ) {
			return $content;
		}

		if ( false !== strpos( $content, 'data-ethnic-recaptcha-widget="true"' ) || false !== strpos( $content, 'g-recaptcha' ) ) {
			return $content;
		}

		$widget = ethnic_recaptcha_widget_markup(
			'contact_form_7',
			array(
				'wrapper_class'   => 'ethnic-shared-contact-form__recaptcha',
				'message_class'   => 'wpcf7-not-valid-tip ethnic-recaptcha-inline-message',
				'include_message' => true,
			)
		);

		if ( '' === $widget ) {
			return $content;
		}

		return $content . "\n\n" . $widget;
	}

	add_filter( 'wpcf7_form_elements', 'ethnic_recaptcha_append_cf7_widget', 20 );
}

if ( ! function_exists( 'ethnic_recaptcha_verify_cf7_submission' ) ) {
	function ethnic_recaptcha_verify_cf7_submission( $spam, $submission ) {
		if ( $spam || ! ethnic_recaptcha_is_enabled( 'contact_form_7' ) ) {
			return $spam;
		}

		$result = ethnic_recaptcha_verify_submission( 'contact_form_7' );

		if ( is_wp_error( $result ) ) {
			$submission->add_spam_log(
				array(
					'agent'  => 'ethnic_recaptcha',
					'reason' => 'Google reCAPTCHA v2 checkbox validation failed.',
				)
			);

			return true;
		}

		return false;
	}

	add_filter( 'wpcf7_spam', 'ethnic_recaptcha_verify_cf7_submission', 8, 2 );
}

if ( ! function_exists( 'ethnic_recaptcha_append_comment_widget' ) ) {
	function ethnic_recaptcha_append_comment_widget( $submit_field, $args = array() ) {
		if ( is_user_logged_in() || ! ethnic_recaptcha_is_enabled( 'wordpress_comments' ) ) {
			return $submit_field;
		}

		$widget = ethnic_recaptcha_widget_markup(
			'wordpress_comments',
			array(
				'wrapper_class'   => 'ethnic-comments-recaptcha',
				'message_class'   => 'ethnic-comments-recaptcha__message ethnic-recaptcha-message',
				'include_message' => true,
			)
		);

		if ( '' === $widget ) {
			return $submit_field;
		}

		return $widget . $submit_field;
	}

	add_filter( 'comment_form_submit_field', 'ethnic_recaptcha_append_comment_widget', 20, 2 );
}

if ( ! function_exists( 'ethnic_recaptcha_verify_comment_submission' ) ) {
	function ethnic_recaptcha_verify_comment_submission( $comment_data ) {
		if ( is_user_logged_in() || ! ethnic_recaptcha_is_enabled( 'wordpress_comments' ) ) {
			return $comment_data;
		}

		$result = ethnic_recaptcha_verify_submission( 'wordpress_comments' );

		if ( is_wp_error( $result ) ) {
			wp_die(
				esc_html__( 'Please complete the reCAPTCHA checkbox before submitting your comment.', 'thegem' ),
				esc_html__( 'Comment security check failed', 'thegem' ),
				array(
					'back_link' => true,
					'response'  => 403,
				)
			);
		}

		return $comment_data;
	}

	add_filter( 'preprocess_comment', 'ethnic_recaptcha_verify_comment_submission', 9 );
}

if ( ! function_exists( 'ethnic_recaptcha_enqueue_assets' ) ) {
	function ethnic_recaptcha_enqueue_assets() {
		if ( is_admin() || ! ethnic_recaptcha_has_enabled_forms() ) {
			return;
		}

		wp_register_style( 'ethnic-recaptcha', false, array(), null );
		wp_enqueue_style( 'ethnic-recaptcha' );
		wp_add_inline_style(
			'ethnic-recaptcha',
			<<<'CSS'
.ethnic-recaptcha-field {
	margin-top: 18px;
}

.ethnic-recaptcha-inline-message,
.ethnic-recaptcha-message {
	margin-top: 10px;
}

.ethnic-proposal-submit__recaptcha,
.ethnic-resources-capture__recaptcha,
.ethnic-comments-recaptcha {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
}

.ethnic-proposal-submit__recaptcha {
	margin-top: 18px;
}

.ethnic-resources-capture__recaptcha {
	margin-top: 18px;
}

.ethnic-comments-recaptcha {
	margin: 16px 0 8px;
}

.ethnic-comments-recaptcha__message {
	width: 100%;
	max-width: 620px;
	padding: 12px 14px;
	border: 1px solid rgba(185, 28, 28, 0.18);
	border-radius: 10px;
	background: #fff1f2;
	color: #b42318;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.45;
}

.ethnic-comments-recaptcha__message p {
	margin: 0;
	color: inherit;
}

.ethnic-shared-contact-form__recaptcha .g-recaptcha,
.ethnic-proposal-submit__recaptcha .g-recaptcha,
.ethnic-resources-capture__recaptcha .g-recaptcha,
.ethnic-comments-recaptcha .g-recaptcha {
	transform-origin: left top;
}

@media (max-width: 480px) {
	.ethnic-shared-contact-form__recaptcha .g-recaptcha,
	.ethnic-proposal-submit__recaptcha .g-recaptcha,
	.ethnic-resources-capture__recaptcha .g-recaptcha,
	.ethnic-comments-recaptcha .g-recaptcha {
		transform: scale(0.92);
	}
}
CSS
		);

		wp_register_script( 'ethnic-recaptcha-core', false, array(), null, true );
		wp_enqueue_script( 'ethnic-recaptcha-core' );
		wp_add_inline_script(
			'ethnic-recaptcha-core',
			sprintf(
				'window.ethnicRecaptchaConfig = %s;',
				wp_json_encode(
					array(
						'enabled'               => true,
						'siteKey'               => ethnic_recaptcha_site_key(),
						'emptyMessage'          => 'Please complete the reCAPTCHA checkbox before submitting this form.',
						'verificationErrorMessage' => 'We could not verify the security check. Please try again.',
					),
					JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
				)
			),
			'before'
		);

		wp_add_inline_script(
			'ethnic-recaptcha-core',
			<<<'JS'
(function (window, document) {
	var config = window.ethnicRecaptchaConfig || {};

	function messageNode(form) {
		return form.querySelector('[data-ethnic-recaptcha-message]');
	}

	function clearMessage(form) {
		var node = messageNode(form);

		if (!node) {
			return;
		}

		node.hidden = true;
		node.innerHTML = '';
	}

	function showMessage(form, message) {
		var node = messageNode(form);

		if (!node) {
			return;
		}

		node.innerHTML = '<p>' + message + '</p>';
		node.hidden = false;
	}

	function widgetContainer(form) {
		return form.querySelector('[data-ethnic-recaptcha-widget="true"]');
	}

	function widgetId(form) {
		var container = widgetContainer(form);

		if (!container) {
			return null;
		}

		if (!container.dataset.ethnicRecaptchaWidgetId) {
			return null;
		}

		return Number(container.dataset.ethnicRecaptchaWidgetId);
	}

	function responseForForm(form) {
		var id = widgetId(form);

		if (id === null || Number.isNaN(id) || typeof window.grecaptcha === 'undefined') {
			return '';
		}

		return String(window.grecaptcha.getResponse(id) || '').trim();
	}

	function renderWidgets(root) {
		if (typeof window.grecaptcha === 'undefined' || typeof window.grecaptcha.render !== 'function') {
			return;
		}

		(root || document).querySelectorAll('[data-ethnic-recaptcha-widget="true"]').forEach(function (container) {
			if (container.dataset.ethnicRecaptchaWidgetId) {
				return;
			}

			var siteKey = container.getAttribute('data-sitekey') || config.siteKey;
			var theme = container.getAttribute('data-theme') || 'light';
			var size = container.getAttribute('data-size') || 'normal';
			var id = window.grecaptcha.render(container, {
				sitekey: siteKey,
				theme: theme,
				size: size,
				callback: function () {
					var form = container.closest('form');
					if (form) {
						clearMessage(form);
					}
				},
				'expired-callback': function () {
					var form = container.closest('form');
					if (form) {
						showMessage(form, config.emptyMessage || 'Please complete the reCAPTCHA checkbox before submitting this form.');
					}
				}
			});

			container.dataset.ethnicRecaptchaWidgetId = String(id);
		});
	}

	function validateForm(form) {
		if (!widgetContainer(form)) {
			return true;
		}

		clearMessage(form);

		if (responseForForm(form)) {
			return true;
		}

		showMessage(form, config.emptyMessage || 'Please complete the reCAPTCHA checkbox before submitting this form.');

		return false;
	}

	function resetForm(form) {
		var id = widgetId(form);

		if (id === null || Number.isNaN(id) || typeof window.grecaptcha === 'undefined') {
			return;
		}

		window.grecaptcha.reset(id);
		clearMessage(form);
	}

	window.ethnicRecaptchaInit = function () {
		renderWidgets(document);
	};

	window.ethnicRecaptcha = {
		enabled: !!config.enabled,
		validateForm: validateForm,
		resetForm: resetForm,
		getErrorMessage: function () {
			return config.verificationErrorMessage || 'We could not verify the security check. Please try again.';
		}
	};

	document.addEventListener('DOMContentLoaded', function () {
		if (typeof window.grecaptcha !== 'undefined' && typeof window.grecaptcha.render === 'function') {
			renderWidgets(document);
		}
	});

	document.addEventListener('submit', function (event) {
		var form = event.target;

		if (!(form instanceof HTMLFormElement) || !widgetContainer(form)) {
			return;
		}

		if (!validateForm(form)) {
			event.preventDefault();
		}
	}, true);

	document.addEventListener('wpcf7submit', function (event) {
		resetForm(event.target);
	});

	document.addEventListener('wpcf7reset', function (event) {
		window.requestAnimationFrame(function () {
			resetForm(event.target);
		});
	});
})(window, document);
JS
		);

		wp_enqueue_script(
			'google-recaptcha-checkbox',
			'https://www.google.com/recaptcha/api.js?onload=ethnicRecaptchaInit&render=explicit',
			array( 'ethnic-recaptcha-core' ),
			null,
			array(
				'in_footer' => true,
				'strategy'  => 'defer',
			)
		);
	}

	add_action( 'wp_enqueue_scripts', 'ethnic_recaptcha_enqueue_assets', 30 );
}

if ( ! function_exists( 'ethnic_recaptcha_register_settings_page' ) ) {
	function ethnic_recaptcha_register_settings_page() {
		add_options_page(
			'Shared reCAPTCHA',
			'Shared reCAPTCHA',
			'manage_options',
			'ethnic-shared-recaptcha',
			'ethnic_recaptcha_render_settings_page'
		);
	}

	add_action( 'admin_menu', 'ethnic_recaptcha_register_settings_page', 40 );
}

if ( ! function_exists( 'ethnic_recaptcha_handle_settings_save' ) ) {
	function ethnic_recaptcha_handle_settings_save() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		if ( empty( $_POST['ethnic_recaptcha_settings_nonce'] ) ) {
			return;
		}

		if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ethnic_recaptcha_settings_nonce'] ) ), 'ethnic_recaptcha_settings' ) ) {
			wp_die( 'Invalid reCAPTCHA settings request.', 403 );
		}

		$current_settings = ethnic_recaptcha_settings();
		$raw_settings     = isset( $_POST['ethnic_recaptcha'] ) && is_array( $_POST['ethnic_recaptcha'] ) ? wp_unslash( $_POST['ethnic_recaptcha'] ) : array();
		$site_key         = isset( $raw_settings['site_key'] ) ? trim( sanitize_text_field( (string) $raw_settings['site_key'] ) ) : '';
		$secret_key       = $current_settings['secret_key'];

		if ( ! empty( $raw_settings['clear_secret_key'] ) ) {
			$secret_key = '';
		} elseif ( isset( $raw_settings['secret_key'] ) && '' !== trim( (string) $raw_settings['secret_key'] ) ) {
			$secret_key = trim( sanitize_text_field( (string) $raw_settings['secret_key'] ) );
		}

		update_option(
			ethnic_recaptcha_option_name(),
			array(
				'enabled'                   => ! empty( $raw_settings['enabled'] ) ? 1 : 0,
				'site_key'                  => $site_key,
				'secret_key'                => $secret_key,
				'contact_form_7_enabled'    => ! empty( $raw_settings['contact_form_7_enabled'] ) ? 1 : 0,
				'proposal_request_enabled'  => ! empty( $raw_settings['proposal_request_enabled'] ) ? 1 : 0,
				'resource_download_enabled' => ! empty( $raw_settings['resource_download_enabled'] ) ? 1 : 0,
				'wordpress_comments_enabled'=> ! empty( $raw_settings['wordpress_comments_enabled'] ) ? 1 : 0,
			),
			false
		);

		wp_safe_redirect(
			ethnic_recaptcha_page_url(
				array(
					'ethnic_recaptcha_notice' => 'saved',
				)
			)
		);
		exit;
	}

	add_action( 'admin_init', 'ethnic_recaptcha_handle_settings_save' );
}

if ( ! function_exists( 'ethnic_recaptcha_render_settings_page' ) ) {
	function ethnic_recaptcha_render_settings_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'You do not have permission to manage reCAPTCHA settings.', 403 );
		}

		$settings      = ethnic_recaptcha_settings();
		$configuration = ethnic_recaptcha_configuration();
		$notice        = isset( $_GET['ethnic_recaptcha_notice'] ) ? sanitize_key( wp_unslash( $_GET['ethnic_recaptcha_notice'] ) ) : '';
		$active_source = ! empty( $configuration['source'] ) ? ethnic_recaptcha_configuration_source_label( $configuration['source'] ) : 'No active key source';
		$status_cards  = array(
			'Shared protection'      => ! empty( $settings['enabled'] ) ? 'Enabled' : 'Disabled',
			'Contact Form 7'         => ! empty( $settings['contact_form_7_enabled'] ) ? 'Enabled' : 'Disabled',
			'Proposal request form'  => ! empty( $settings['proposal_request_enabled'] ) ? 'Enabled' : 'Disabled',
			'Resource download form' => ! empty( $settings['resource_download_enabled'] ) ? 'Enabled' : 'Disabled',
			'WordPress comments'     => ! empty( $settings['wordpress_comments_enabled'] ) ? 'Enabled' : 'Disabled',
		);
		?>
		<div class="wrap">
			<h1>Shared reCAPTCHA</h1>
			<p>Manage one shared Google reCAPTCHA v2 checkbox setup for the public proposal form, resource download forms, and Contact Form 7.</p>

			<?php if ( 'saved' === $notice ) : ?>
				<div class="notice notice-success is-dismissible">
					<p>Shared reCAPTCHA settings saved.</p>
				</div>
			<?php endif; ?>

			<div style="display:grid;gap:12px;margin-top:18px;">
				<div style="display:flex;flex-wrap:wrap;gap:18px;color:#5f6f8b;font-size:13px;">
					<span><strong>Active key source:</strong> <?php echo esc_html( $active_source ); ?></span>
					<span><strong>Resolved site key:</strong> <?php echo esc_html( ethnic_recaptcha_mask_value( $configuration['site_key'] ) ); ?></span>
				</div>
			</div>

			<form method="post" action="<?php echo esc_url( ethnic_recaptcha_page_url() ); ?>" style="margin-top:20px;">
				<?php wp_nonce_field( 'ethnic_recaptcha_settings', 'ethnic_recaptcha_settings_nonce' ); ?>

				<div style="background:#fff;border:1px solid #d9e1ef;border-radius:16px;padding:24px;margin-bottom:18px;">
					<h2 style="margin-top:0;">General</h2>
					<p style="margin-top:0;color:#5f6f8b;">Turn shared Google reCAPTCHA v2 checkbox protection on or off for supported public forms.</p>
					<label style="display:block;">
						<span style="display:block;font-weight:600;margin-bottom:6px;">Enable shared reCAPTCHA protection</span>
						<span style="display:flex;align-items:center;gap:10px;">
							<input type="checkbox" name="ethnic_recaptcha[enabled]" value="1" <?php checked( ! empty( $settings['enabled'] ) ); ?> />
							<span>Allow shared Google reCAPTCHA v2 checkbox protection on supported public forms.</span>
						</span>
					</label>
				</div>

				<div style="background:#fff;border:1px solid #d9e1ef;border-radius:16px;padding:24px;margin-bottom:18px;">
					<h2 style="margin-top:0;">Keys</h2>
					<p style="margin-top:0;color:#5f6f8b;">Use Google reCAPTCHA <strong>v2 checkbox</strong> keys here. Existing v3 keys will not render a visible checkbox widget.</p>
					<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 18px;">
						<label style="grid-column:1 / -1;">
							<span style="display:block;font-weight:600;margin-bottom:6px;">v2 checkbox site key</span>
							<input type="text" name="ethnic_recaptcha[site_key]" value="<?php echo esc_attr( $settings['site_key'] ); ?>" placeholder="Enter your Google reCAPTCHA v2 checkbox site key" style="width:100%;" />
						</label>
						<label style="grid-column:1 / -1;">
							<span style="display:block;font-weight:600;margin-bottom:6px;">v2 checkbox secret key</span>
							<input type="password" name="ethnic_recaptcha[secret_key]" value="" placeholder="<?php echo esc_attr( '' !== $settings['secret_key'] ? 'Stored already — leave blank to keep the current secret' : 'Enter your Google reCAPTCHA v2 checkbox secret key' ); ?>" style="width:100%;" />
						</label>
						<label style="grid-column:1 / -1;">
							<span style="display:flex;align-items:center;gap:10px;">
								<input type="checkbox" name="ethnic_recaptcha[clear_secret_key]" value="1" />
								<span>Clear the currently stored secret key</span>
							</span>
						</label>
					</div>
				</div>

				<div style="background:#fff;border:1px solid #d9e1ef;border-radius:16px;padding:24px;margin-bottom:18px;">
					<h2 style="margin-top:0;">Form Coverage</h2>
					<p style="margin-top:0;color:#5f6f8b;">Choose where the visible checkbox widget should appear and be enforced.</p>
					<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px;">
						<?php foreach ( $status_cards as $label => $status ) : ?>
							<div style="border:1px solid #d9e1ef;border-radius:16px;padding:18px;background:#f8fbff;">
								<h3 style="margin-top:0;margin-bottom:8px;"><?php echo esc_html( $label ); ?></h3>
								<p style="margin:0;color:#5f6f8b;"><?php echo esc_html( $status ); ?></p>
							</div>
						<?php endforeach; ?>
					</div>

					<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 18px;margin-top:18px;">
						<label style="grid-column:1 / -1;">
							<span style="display:flex;align-items:center;gap:10px;">
								<input type="checkbox" name="ethnic_recaptcha[contact_form_7_enabled]" value="1" <?php checked( ! empty( $settings['contact_form_7_enabled'] ) ); ?> />
								<span>Show and verify the Google v2 checkbox on Contact Form 7 forms.</span>
							</span>
						</label>
						<label style="grid-column:1 / -1;">
							<span style="display:flex;align-items:center;gap:10px;">
								<input type="checkbox" name="ethnic_recaptcha[proposal_request_enabled]" value="1" <?php checked( ! empty( $settings['proposal_request_enabled'] ) ); ?> />
								<span>Show and verify the Google v2 checkbox on the Request a Proposal form.</span>
							</span>
						</label>
						<label style="grid-column:1 / -1;">
							<span style="display:flex;align-items:center;gap:10px;">
								<input type="checkbox" name="ethnic_recaptcha[resource_download_enabled]" value="1" <?php checked( ! empty( $settings['resource_download_enabled'] ) ); ?> />
								<span>Show and verify the Google v2 checkbox on public resource download forms.</span>
							</span>
						</label>
						<label style="grid-column:1 / -1;">
							<span style="display:flex;align-items:center;gap:10px;">
								<input type="checkbox" name="ethnic_recaptcha[wordpress_comments_enabled]" value="1" <?php checked( ! empty( $settings['wordpress_comments_enabled'] ) ); ?> />
								<span>Show and verify the Google v2 checkbox on WordPress blog comment forms for logged-out visitors.</span>
							</span>
						</label>
					</div>
				</div>

				<div style="background:#fff;border:1px solid #d9e1ef;border-radius:16px;padding:24px;margin-bottom:18px;">
					<h2 style="margin-top:0;">Notes</h2>
					<ul style="margin:0;padding-left:18px;display:grid;gap:8px;color:#334155;">
						<li>This setup is for Google reCAPTCHA v2 checkbox only.</li>
						<li>If you previously saved v3 keys, replace them with v2 checkbox keys before expecting a visible widget.</li>
						<li>Contact Form 7 built-in v3 integration is bypassed when this shared Contact Form 7 option is enabled.</li>
					</ul>
				</div>

				<?php submit_button( 'Save reCAPTCHA Settings' ); ?>
			</form>
		</div>
		<?php
	}
}