Возникли проблемы с отправкой формы через AJAX на WordPress с reCAPTCHA - PullRequest
1 голос
/ 24 мая 2019

Я потратил много часов, пытаясь найти выход из этого, и продолжаю придумывать одну или другую проблему.Я завязываю себя в узлы и надеюсь, что кто-то может мне помочь, метафорически шлепнув меня по лицу и показывая, как, черт возьми, это делать правильно.

Хорошо ... так что яу меня есть страница на моем внешнем интерфейсе, которая вставлена ​​с помощью шорткода.По сути, эта форма является своего рода формой AMA (Ask Me Anything), которую я использую для создания сообщений в моей области администратора.Посетители вводят свой вопрос, имя и адрес электронной почты, и отправляют мне форму через AJAX.Материалы сохраняются в базе данных WordPress с пользовательским типом записи ama, и электронное письмо отправляется мне через wp_mail, потому что у меня установлен плагин SMTP, который направляет туда все запросы на wp_mail.У меня установлен CMB2 на моем веб-сайте, и там хранятся ключи для reCAPTCHA.

Пока все хорошо.

У меня была рабочая форма с полями CMB2, но CMB2, похоже, неподдержка reCAPTCHA (в противном случае он работал нормально).Поэтому я решил начать с нуля и написать свою собственную форму, поскольку я хотел отправить только три поля.Что может пойти не так, не так ли?

Вот мой код Франкена.

<?php
function ccdClient_shortcode_amaForm( $atts ) {

    // Parse attributes
    $atts = ( shortcode_atts( array(
        'id'        => uniqid('ccdClient_amaForm_'),
    ), $atts, 'ama_form' ) );

    $rcKey = cmb2_get_option( 'ccdtheme_settings_apikeys', '_ccdclient_themesettings_apikeys_captcha_sitekey' );

    $form = '
    <form id="' . $atts['id'] . '" name="' . $atts['id'] . '" method="post" action="">
        <div class="amaError"></div>
        <div class="amaForm-field-question amaForm-field">
            <p><label for="question">Your Question</label></p>
            <p><textarea id="question" name="question" tabindex="1"></textarea></p>
        </div>
        <div class="amaForm-fieldGroup amaForm-groupTwo">
            <div class="amaForm-field-name amaForm-field">
                <p><label for="name">Your Name</label></p>
                <p><input type="text" id="name" name="name" tabindex="2" /></p>
            </div>
            <div class="amaForm-field-email amaForm-field">
                <p><label for="email">Your Email</label></p>
                <p><input type="email" id="email" name="email" tabindex="3" /></p>
            </div>
        </div>
        <div class="amaForm-fieldGroup amaForm-groupTwo">
            <div class="amaForm-field-recaptcha amaForm-field amaForm-recaptcha">
                <div class="g-recaptcha" data-sitekey="' . $rcKey . '"></div>
            </div>
            <div class="amaForm-field-submit amaForm-field amaForm-submit">
                <input type="submit" value="Publish" id="submit" name="submit" />
            </div>
        </div>
    </form>
    <script>
        $(document).ready(function() {

            // Get form
            var amaForm = $("#' . $atts['id'] . '");
            // Get messages div
            var amaError = $("#' . $atts['id'] . ' .amaError");
            // Set data
            var amaData = { "action" : "ama_form_process"}

            var options = { 
                url: "'. admin_url( 'admin-ajax.php' ) .'",
                type: "post",
                dataType: "json",
                data: amaData,
                success : function(responseText, statusText, xhr, $form) {
                    $(amaError).html("Your form has been submitted successfully");
                },
            };

            //Set submit function
            amaForm.on("submit", function(e) {
                //Prevent default form behavior
                e.preventDefault();
                // Serialise form data
                //Post via AJAX
                $.ajax(options)
                .done(function(response) {
                    // Make sure that the amaError div has the "success" class.
                    $(amaError).removeClass("error");
                    $(amaError).addClass("success");
                    // Set the message text.
                    $(amaError).text(response);
                })
                .fail(function(data) {
                    // Make sure that the amaError div has the "error" class.
                    $(amaError).removeClass("success");
                    $(amaError).addClass("error");

                    // Set the message text.
                    if (data.responseText !== "") {
                        $(amaError).text(data.responseText);
                    } else {
                        $(amaError).text("Oops! An error occured, and your message could not be sent.");
                    }
                });
            });
        });
    </script>';

    return $form;
}
add_shortcode('ama_form', 'ccdClient_shortcode_amaForm');

function ama_form_process() {
    // If the form was submitted
    if ($_SERVER["REQUEST_METHOD"] == "POST") {

        // Include WordPress files
        include_once '../../../../../wp-includes/wp-load.php';

        // Set reCaptcha private key
        $recaptchaKey = cmb2_get_option( 'ccdtheme_settings_apikeys', '_ccdclient_themesettings_apikeys_captcha_secretkey' );

        // If the Google Recaptcha box was clicked
        if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
            $captcha = $_POST['g-recaptcha-response'];
            $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptchaKey . "&response=" . $captcha);
            $obj = json_decode($response);

            // If the Google Recaptcha check was successful
            if($obj->success == true) {
                $question = strip_tags( trim( $_POST['question'] ) );
                $name = strip_tags( trim( $_POST["name"] ) );
                $name = str_replace( array("\r","\n"), array(" "," "), $name);
                $email = filter_var( trim( $_POST["email"] ), FILTER_SANITIZE_EMAIL );
                if ( !$name || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                    echo "Oops! There was a problem with your submission. Please complete the form and try again.";
                    exit;
                }

                // Add the content of the form to $post as an array
                $post = array(
                    'post_title'    => $question,
                    'post_status'   => 'pending',   // Could be: publish
                    'post_type'     => 'ama', // Could be: `page` or your CPT
                    'meta_input'    => array(
                        '_ccdclient_ama_name'   => $name,
                        '_ccdclient_ama_email'  => $email,
                    ),
                );
                wp_insert_post($post);
                echo 'Saved your post successfully! :)';

                $recipient = get_option('admin_email');
                $subject = "New question from $name";
                $email_content = "Name: $name\n";
                $email_content .= "Email: $email\n\n";
                $email_content .= "Message:\n$question\n";
                $email_headers = "From: $name <$email>";
                wp_mail( $recipient, $subject, $email_content, $email_headers );
            }
            // If the Google Recaptcha check was not successful
            else {
                echo "Robot verification failed. Please try again. Success:" . $response;
            }
        }
        // If the Google Recaptcha box was not clicked
        else {
            echo "Please click the reCAPTCHA box.";
        }
    }
    // If the form was not submitted
    // Not a POST request, set a 403 (forbidden) response code.
    else {
        echo "There was a problem with your submission, please try again.";
    }
}
add_action("wp_ajax_ama_form_process", "ama_form_process");

//use this version for if you want the callback to work for users who are not logged in
add_action("wp_ajax_nopriv_ama_form_process", "ama_form_process");

Как вы можете догадаться, я просмотрел около десятка страниц или около того и объединил усилия каждого из них.из них, таким образом, перезаписывая части, которые, возможно, сработали бы и смутили бы меня без конца, и поэтому я прибегаю к здесь, чтобы сохранить то, что осталось от моего здравомыслия.

РЕДАКТИРОВАТЬ: Извинения.Пока я копировал код, я не знал, с какими проблемами столкнулся.Идет, чтобы показать степень моего разочарования.

У меня был ряд проблем с этим кодом.В настоящее время, когда я отправляю форму, она сохраняет тот же URL, но возвращает страницу с ошибкой 404.Однако ранее он говорил мне, что не может распознавать функции - и, следовательно, не может запускаться - например, cmb2_get_option (который является модификацией get_option, который специально работает со страницами параметров CMB2) и wp_insert_post.Последняя ошибка (например, wp_insert_post) возникла, когда секретный ключ был жестко запрограммирован в скрипте и не вызывался из функции get_option.

...