Как заставить работать действительно простую капчу в простой контактной форме?

Я попытался создать простую контактную форму в соответствии с это руководство

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

С помощью следующего кода я могу использовать шорткод [contact] на любой из моих страниц, и форма отображается, НО при проверке капчи возникает проблема.

Это код плагина:

function wptuts_get_the_ip() {
    if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        return $_SERVER["HTTP_X_FORWARDED_FOR"];
    }
    elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
        return $_SERVER["HTTP_CLIENT_IP"];
    }
    else {
        return $_SERVER["REMOTE_ADDR"];
    }
}
// short code function 
function wptuts_contact_form_sc( $atts ) {     
add_shortcode( 'contact', 'contact_form_shortcode' );

   extract(shortcode_atts(array(
        "email" => get_bloginfo('admin_email'),
        "subject" => '',
        "label_name" => 'Your Name',
        "label_email" => 'Your E-mail Address',
        "label_subject" => 'Your Answer',
        "label_captcha" => 'Captcha',
        "label_submit" => 'Submit',
        "error_empty" => 'Please fill in all the required fields.',
        "error_noemail" => 'Please enter a valid e-mail address.',
        "success" => 'Thanks for your e-mail! We\'ll get back to you as soon as we can.'
    ), $atts));

    $captcha_instance = new ReallySimpleCaptcha(); //imports really simple captcha plugin
    $word = $captcha_instance->generate_random_word();
    $prefix = mt_rand();
    $image= $captcha_instance->generate_image( $prefix, $word );

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        $error = false;
        $required_fields = array("your_name", "email", "captcha", "subject");

        foreach ($_POST as $field => $value) {
            if (get_magic_quotes_gpc()) {
                $value = stripslashes($value);
            }
            $form_data[$field] = strip_tags($value);
        }

        foreach ($required_fields as $required_field) {
            $value = trim($form_data[$required_field]);
            if(empty($value)) {
                $error = true;
                $result = $error_empty;
            }
        }

        if(!is_email($form_data['email'])) {
            $error = true;
            $result = $error_noemail;
        }

        if ($error == false) {

            $captcha_text=$form_data['captcha'];                
            $correct = $captcha_instance->check( $prefix, $captcha_text );

            if($correct==TRUE){

                $email_subject = "[" . get_bloginfo('name') . "] " . $form_data['subject'];
                $email_message = $form_data['captcha'] . "\n\nIP: " . wptuts_get_the_ip();
                $headers  = "From: ".$form_data['your_name']." <".$form_data['email'].">\n";
                $headers .= "Content-Type: text/plain; charset=UTF-8\n";
                $headers .= "Content-Transfer-Encoding: 8bit\n";
                wp_mail($email, $email_subject, $email_message, $headers);
                $result = $success;
                $sent = true;
            }
        }
    }

    if($result != "") {
        $info = '<div class="info">'.$result.'</div>';        
    }

    $email_form = '<form class="contact-form" method="post" action="'.get_permalink().'">
        <div>
            <label for="cf_name">'.$label_name.':</label>
            <input type="text" name="your_name" id="cf_name" size="50" maxlength="50" value="'.$form_data['your_name'].'" />
        </div>
        <div>
            <label for="cf_email">'.$label_email.':</label>
            <input type="text" name="email" id="cf_email" size="50" maxlength="50" value="'.$form_data['email'].'" />
        </div>
        <div>
            <label for="cf_subject">'.$label_subject.':</label>
            <input type="text" name="subject" id="cf_subject" size="50" maxlength="50" value="'.$subject.$form_data['subject'].'" />
        </div>
        <div>
            <label for="cf_message">'.$label_captcha.':</label>
            <input type="text" name="captcha" id="cf_message" size="50" maxlength="50" value=""/>
        </div>
        <div id="captcha"><span id="captcha_text">Captcha:</span><img id="captcha_image" src="'.plugins_url("really-simple-captcha/tmp/" . $image) . '" alt="" /></div>
        <div>
            <input type="submit" value="'.$label_submit.'" name="send" id="cf_send" />
        </div>

    </form>';

    if($sent == true) {
        return $info;
    } else {
        return $info.$email_form;
    }
} 
add_shortcode('contact', 'wptuts_contact_form_sc');

// add plugins style to frontend
function prize_game_contact_form() {
wp_register_style('prize_game_contact_form', plugins_url('css/style.css',__FILE__));
wp_enqueue_style('prize_game_contact_form');
}
add_action('wp_enqueue_scripts', 'prize_game_contact_form');

Я пока не добавил $captcha_instance->remove( $prefix );, потому что работает не так, как должно. Кажется, что каждый раз, когда я нажимаю кнопку отправки, создается новое слово, и функция $captcha_instance->check() проверяет, совпадает ли новое слово с текстом капчи в поле ввода, но эти слова, конечно, не совпадают, потому что это уже новое слово. Я не понимаю, почему при нажатии на кнопку отправки создается новое слово. Где ошибка?


person user2718671    schedule 21.01.2014    source источник


Ответы (4)


Я считаю, что проблема в том, что вы генерируете новый $prefix при каждом запуске функции. Таким образом, нет возможности запустить check() или remove(), потому что $prefix, используемый в форме, является новым значением.

В вашей форме создайте скрытое поле ввода со значением используемого $prefix. Таким образом, это значение публикуется вместе с формой. Когда функция запускается второй раз после публикации формы, используйте опубликованное значение $prefix для выполнения check() и remove(). Это должно сработать.

Вот подробная статья о том, как интегрировать плагин Really Simple Captcha в ваш плагин или тему вместе со скрытым полем префикса, которое я только что упомянул: http://www.lost-in-code.com/platforms/wordpress/wordpress-plugins/wordpress-using-really-simple-captcha/

Не стесняйтесь сообщить мне, если вам понадобится помощь.

person tribulant    schedule 07.05.2016
comment
Спасибо, не тестировал, потому что это был старый проект, но я думаю, что это сработает. - person user2718671; 10.05.2016

Вы используете Wordpress? Не пытайтесь изобретать велосипед.

Загрузите бесплатный плагин, например Contact Form 7, который включает Ajax-версию (не требует обновить страницу) Спам-фильтр Askimet, плюс система CAPTCHA.

  • CAPTCHA работает наполовину так же хорошо, как 3-5 лет назад.

Мой вам совет:

  • Не ищите простых, а ищите то, что работает.
person Uncle Iroh    schedule 21.01.2014
comment
Спасибо за ваш совет. Я уже знаю Contact Form 7 и действительно - это хороший плагин. Но я хочу создать свой собственный плагин с некоторыми специальными функциями, и я просто думаю, что проще создать новый простой, чем изменять плагин сложной контактной формы 7. И я даже не знаю, можно ли изменять скрипт cf7, поэтому пришлось попробовать;) - person user2718671; 22.01.2014

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

person Steve    schedule 26.09.2014

Вы должны создать переменные $ word, $ prefix и $ image только после того, как проверите правильность ответа пользователя, и вы должны передать значение $ prefix через скрытое поле ввода. Я не проверял, но теперь этот код должен работать:

function wptuts_get_the_ip() {
    if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        return $_SERVER["HTTP_X_FORWARDED_FOR"];
    }
    elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
        return $_SERVER["HTTP_CLIENT_IP"];
    }
    else {
        return $_SERVER["REMOTE_ADDR"];
    }
}
// short code function 
function wptuts_contact_form_sc( $atts ) {     
add_shortcode( 'contact', 'contact_form_shortcode' );

   extract(shortcode_atts(array(
        "email" => get_bloginfo('admin_email'),
        "subject" => '',
        "label_name" => 'Your Name',
        "label_email" => 'Your E-mail Address',
        "label_subject" => 'Your Answer',
        "label_captcha" => 'Captcha',
        "label_submit" => 'Submit',
        "error_empty" => 'Please fill in all the required fields.',
        "error_noemail" => 'Please enter a valid e-mail address.',
        "success" => 'Thanks for your e-mail! We\'ll get back to you as soon as we can.'
    ), $atts));

    $captcha_instance = new ReallySimpleCaptcha(); //imports really simple captcha plugin

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        $error = false;
        $required_fields = array("your_name", "email", "captcha", "subject");

        foreach ($_POST as $field => $value) {
            if (get_magic_quotes_gpc()) {
                $value = stripslashes($value);
            }
            $form_data[$field] = strip_tags($value);
        }

        foreach ($required_fields as $required_field) {
            $value = trim($form_data[$required_field]);
            if(empty($value)) {
                $error = true;
                $result = $error_empty;
            }
        }

        if(!is_email($form_data['email'])) {
            $error = true;
            $result = $error_noemail;
        }

        if ($error == false) {

            $captcha_text=$form_data['captcha'];
            $captcha_prefix=$form_data['prefix'];
            $correct = $captcha_instance->check( $captcha_prefix, $captcha_text );

            if($correct==TRUE){

                $email_subject = "[" . get_bloginfo('name') . "] " . $form_data['subject'];
                $email_message = $form_data['captcha'] . "\n\nIP: " . wptuts_get_the_ip();
                $headers  = "From: ".$form_data['your_name']." <".$form_data['email'].">\n";
                $headers .= "Content-Type: text/plain; charset=UTF-8\n";
                $headers .= "Content-Transfer-Encoding: 8bit\n";
                wp_mail($email, $email_subject, $email_message, $headers);
                $result = $success;
                $sent = true;
            }
        }
    }

    $word = $captcha_instance->generate_random_word();        
    $prefix = mt_rand();
    $image= $captcha_instance->generate_image( $prefix, $word );

    if($result != "") {
        $info = '<div class="info">'.$result.'</div>';        
    }

    $email_form = '<form class="contact-form" method="post" action="'.get_permalink().'">
        <div>
            <label for="cf_name">'.$label_name.':</label>
            <input type="text" name="your_name" id="cf_name" size="50" maxlength="50" value="'.$form_data['your_name'].'" />
        </div>
        <div>
            <label for="cf_email">'.$label_email.':</label>
            <input type="text" name="email" id="cf_email" size="50" maxlength="50" value="'.$form_data['email'].'" />
        </div>
        <div>
            <label for="cf_subject">'.$label_subject.':</label>
            <input type="text" name="subject" id="cf_subject" size="50" maxlength="50" value="'.$subject.$form_data['subject'].'" />
        </div>
        <div>
            <label for="cf_message">'.$label_captcha.':</label>
            <input type="text" name="captcha" id="cf_message" size="50" maxlength="50" value=""/>
            <input type="hidden" name="prefix" id="prefix" value="'.$prefix.'"/>
        </div>
        <div id="captcha"><span id="captcha_text">Captcha:</span><img id="captcha_image" src="'.plugins_url("really-simple-captcha/tmp/" . $image) . '" alt="" /></div>
        <div>
            <input type="submit" value="'.$label_submit.'" name="send" id="cf_send" />
        </div>

    </form>';

    if($sent == true) {
        return $info;
    } else {
        return $info.$email_form;
    }
} 
add_shortcode('contact', 'wptuts_contact_form_sc');

// add plugins style to frontend
function prize_game_contact_form() {
wp_register_style('prize_game_contact_form', plugins_url('css/style.css',__FILE__));
wp_enqueue_style('prize_game_contact_form');
}
add_action('wp_enqueue_scripts', 'prize_game_contact_form');
person Gustavo    schedule 03.11.2014