1

I made myself a custom CAPTCHA SUM type and it's working , however even if I add the right sum, my customer will not be created, not sure why and how to debug this. Here is my code:

The wp-content/plugins/custom-sum-captcha/custom-sum-captcha.php content is:

<?php
/*
Plugin Name: Custom Sum CAPTCHA
Description: Custom CAPTCHA requiring users to solve the sum of two random numbers.
Version: 1.0.0
Author: XXXXXXXXXXX
*/
// Enqueue JavaScript file
// Enqueue jQuery and define ajaxurl
function custom_sum_captcha_enqueue_script() {
    wp_enqueue_script('jquery');
    wp_enqueue_script('custom-sum-captcha-script', plugins_url('js/captcha.js', __FILE__), array('jquery'), '1.0', true);

    // Define ajaxurl variable for the frontend
    wp_localize_script('custom-sum-captcha-script', 'ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_enqueue_scripts', 'custom_sum_captcha_enqueue_script');

// Validate CAPTCHA
function custom_sum_captcha_validate_answer($answer) {
    $sum = intval($_POST['real_answer']);
    $user_answer = intval($answer);
    return $user_answer === $sum;
}
// Callback function to handle AJAX request
function custom_sum_captcha_validate() {
    // Check if the request is a POST request
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // Check if the answer is provided
        if (isset($_POST['captcha_answer'])) {
            // Validate the CAPTCHA
            $is_valid = custom_sum_captcha_validate_answer($_POST['captcha_answer']);

            // Send JSON response
            echo json_encode($is_valid ? '1' : '0');
        }
    }
    // Always exit to prevent further execution
    wp_die();
}

// Hook the AJAX action
add_action('wp_ajax_custom_sum_captcha_validate', 'custom_sum_captcha_validate');
add_action('wp_ajax_nopriv_custom_sum_captcha_validate', 'custom_sum_captcha_validate');


// Generate CAPTCHA HTML
function custom_sum_captcha_generate_html() {
    $num1 = rand(1, 10);
    $num2 = rand(1, 10);
    $sum = $num1 + $num2;

    $html = '<p>Please solve the following math problem:</p>';
    $html .= '<p>' . $num1 . ' + ' . $num2 . ' = <input type="text" id="captcha-answer" name="captcha-answer" style="width:20%"/></p>';
    $html .= '<input type="hidden" id="captcha-sum" value="' . $sum . '" />';
    return $html;
}

// Shortcode handler
function custom_sum_captcha_shortcode() {
    return custom_sum_captcha_generate_html();
}
add_shortcode('custom_sum_captcha', 'custom_sum_captcha_shortcode');


function custom_sum_captcha_validate_registration($errors) {
    echo 1212; exit();
    // Validate the CAPTCHA answer
    if (empty($_POST['captcha-answer']) || !custom_sum_captcha_validate_answer($_POST['captcha-answer'])) {
        // CAPTCHA validation failed, add an error message
        $errors->add('captcha_error', __('The CAPTCHA answer is incorrect.', 'textdomain'));
    }
    return $errors;
}
add_filter('woocommerce_process_registration_errors', 'custom_sum_captcha_validate_registration', 10, 1);

the wp-content/plugins/custom-sum-captcha/js/captcha.js content is:

jQuery(document).ready(function($) {
    $('.woocommerce-form-register').on('submit', function(event) {
        // Prevent form submission
        event.preventDefault();

        // Get the email input value
        var userEmail = $('#reg_email').val();

        // Validate email format
        if (!isValidEmail(userEmail)) {
           alert('Error message 1');
            return; // Exit the function
        }

        // Get the user's answer
        var userAnswer = $('#captcha-answer').val();
        var realAnswer = $('#captcha-sum').val();

        // Check if the answer is empty
        if (userAnswer.trim() === '') {
            alert('Error message 2');
            return; // Exit the function
        }

        // Send AJAX request to validate the CAPTCHA
        $.ajax({
            type: 'POST',
            url: ajax_object.ajaxurl,
            dataType: 'json',
            data: {
                action: 'custom_sum_captcha_validate',
                captcha_answer: userAnswer,
                real_answer: realAnswer
            },
            success: function(response) {
                console.log('Response from server:', response); // Log the response from the server
                if (response && response === '1') {
                    alert('OK');
                    // If the answer is valid, submit the form
                    $('.woocommerce-form-register').off('submit').submit();
                } else {
                    // If the answer is invalid, display an error message
                    alert('Error message 3');
                }
            },
            error: function(xhr, status, error) {
                // Log any errors that occur during the AJAX request
                console.error('AJAX Error: ', xhr.responseText);
                alert('An error occurred while processing your request. Please try again later.');
            }
        });
    });
    // Function to validate email format
    function isValidEmail(email) {
        var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    }
});

This is the child-theme file: wp-content/themes/flatsome-child/woocommerce/myaccount/form-login.php content:

<form class="woocommerce-form woocommerce-form-login login" method="post">

                    <?php do_action( 'woocommerce_login_form_start' ); ?>

                    <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
                        <label for="username"><?php esc_html_e( 'Username or email address', 'woocommerce' ); ?>&nbsp;<span class="required">*</span></label>
                        <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="username" id="username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" /><?php // @codingStandardsIgnoreLine ?>
                    </p>
                    <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
                        <label for="password"><?php esc_html_e( 'Password', 'woocommerce' ); ?>&nbsp;<span class="required">*</span></label>
                        <input class="woocommerce-Input woocommerce-Input--text input-text" type="password" name="password" id="password" autocomplete="current-password" />
                    </p>

                    <?php do_action( 'woocommerce_login_form' ); ?>

                    <p class="form-row">
                        <label class="woocommerce-form__label woocommerce-form__label-for-checkbox woocommerce-form-login__rememberme">
                            <input class="woocommerce-form__input woocommerce-form__input-checkbox" name="rememberme" type="checkbox" id="rememberme" value="forever" /> <span><?php esc_html_e( 'Remember me', 'woocommerce' ); ?></span>
                        </label>
                        <?php wp_nonce_field( 'woocommerce-login', 'woocommerce-login-nonce' ); ?>
                        <button type="submit" class="woocommerce-button button woocommerce-form-login__submit<?php if ( fl_woocommerce_version_check( '7.0.1' ) ) { echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); } ?>" name="login" value="<?php esc_attr_e( 'Log in', 'woocommerce' ); ?>"><?php esc_html_e( 'Log in', 'woocommerce' ); ?></button>
                    </p>
                    <p class="woocommerce-LostPassword lost_password">
                        <a href="<?php echo esc_url( wp_lostpassword_url() ); ?>"><?php esc_html_e( 'Lost your password?', 'woocommerce' ); ?></a>
                    </p>

                    <?php do_action( 'woocommerce_login_form_end' ); ?>

                </form>

My form is submitted when I add the right sum of my captcha and i receive an alert if not. So far so good. But after the form submit , after I add my email address, my user is not created. Can anyone tell me why ? how to debug this more ?

Thank you

1 Answer 1

0

I think i over complicated a bit :)

using this hook woocommerce_register_post would simply things.

This is my content of the custom-sum-captcha.php file:

function custom_sum_captcha_generate_html() {
    $num1 = rand(1, 10);
    $num2 = rand(1, 10);
    $sum = $num1 + $num2;

    $html = '<p>Please solve the following math problem:</p>';
    $html .= '<p>' . $num1 . ' + ' . $num2 . ' = <input type="text" id="captcha-answer" name="captcha-answer" style="width:20%"/></p>';
    $html .= '<input type="hidden" id="captcha-sum" name="captcha-sum" value="' . $sum . '" />';
    return $html;
}

// Shortcode handler
function custom_sum_captcha_shortcode() {
    return custom_sum_captcha_generate_html();
}
add_shortcode('custom_sum_captcha', 'custom_sum_captcha_shortcode');

// Validate CAPTCHA on registration form submission

function custom_sum_captcha_validate_registration_form($username, $email, $validation_errors) {
    // Check if the CAPTCHA answer is provided
    if (empty($_POST['captcha-answer'])) {
        $validation_errors->add('captcha_error', __('Please enter the CAPTCHA answer.', 'textdomain'));
    } else {
        // Validate the CAPTCHA answer
        $captcha_answer = intval($_POST['captcha-answer']);
        $real_answer = intval($_POST['captcha-sum']);
        if ($captcha_answer !== $real_answer) {
            $validation_errors->add('captcha_error', __('The CAPTCHA answer is incorrect.'.$captcha_answer.'---'.$real_answer, 'textdomain'));
        }
    }
}
add_action('woocommerce_register_post', 'custom_sum_captcha_validate_registration_form', 10, 3);

And i have added <?php echo custom_sum_captcha_generate_html(); ?> in the form-login.php file

and that's it ! no more js , no more ajax

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.