Contactform with Honeypot (+ loadtime function)

Hey guys,

I’m new and have read (and tried) all posts about honeypots for my contactform.
I have also tried a combination with a loadtime function, but that also failed.
In my example below I have only the honeypot function, but it’s not working…

Which PHP-guru can help me out? I asume only the PHP part is wrong…
I also asume I only have to adjust the “sendemail.php” and not the “class.sendemail.php”.

Who can help me out? Score extra points by also putting a loadtime function in it :wink:

Thanks for all your help!


-------------------------------------

CSS (style.css):

.robotic {
    display:none;
}

-------------------------------------

HMTL (index.html):

                    <div id="contactform">    
                        <div id="response"></div>
                        <form method="POST" action="sendemail.php" class="form">
                            <div id="main">
                                              <p class="name">
                                    <input type="text" name="name" id="name" />
                                    <label for="name" class="overlabel">Name</label>
                                </p>
                                <p class="email">
                                    <input type="text" name="email" id="email" />
                                    <label for="email" class="overlabel">E-mail</label>
                                </p>
                                <p class="text">
                                    <textarea name="comments" id="comments" ></textarea>
                                    <label for="comments" class="overlabel">Comments</label>
                                </p>
                                                                                                                <!-- Honeypot -->
                                                                                                                <p class="robotic" id="pot">
                                                                                                                              <input type="text" name="robotest" id="robotest" />
                                    <label for="robotest" class="overlabel">Leave this blank</label>
                                                                                                                </p>
                                <p class="submit">
                                    <button type="submit" name="submit" id="submit" class="graybutton">Send e-mail</button>
                                </p>
                            
                            </div><!--end main-->
                        </form>
                    </div><!--end contact form-->


PHP (sendemail.php):


<?php
    
    $name = trim($_POST['name']);
    $email = $_POST['email'];
    $comments = $_POST['comments'];
    $robotest = $_POST['robotest'];
    
    $site_owners_email = 'xxx@xxx.xxx'; 
    $site_owners_name = 'Xxx Xxx'; 

    if (strlen($name) < 2) {
        $error['name'] = "Enter your name";    
    }
    
    if (!preg_match('/^[a-z0-9&\\'\\.\\-_\\+]+@[a-z0-9\\-]+\\.([a-z0-9\\-]+\\.)*+[a-z]{2}/is', $email)) {
        $error['email'] = "Enter a valid e-mail";    
    }
    
    if (strlen($comments) < 3) {
        $error['comments'] = "Leave a comment";
    }

    if (strlen($robotest) > 2) {
        $error['robotest'] = "You are a bot";
    }

    if (!$error) {

        require_once('class.sendemail.php');
        $mail = new PHPMailer();
        
        $mail->From = $email;
        $mail->FromName = $name;
        $mail->Subject = "Bericht via de website";
        $mail->AddAddress($site_owners_email, $site_owners_name);
        $mail->Body = $comments;
        
        $mail->Send();
    
        
        echo "<p class='success'> Message sent </p>";
        
    } # end if no error
    else {

        $response = (isset($error['name'])) ? "<p id='error1'>" . $error['name'] . " \
" : null;
        $response .= (isset($error['email'])) ? "<p id='error2'>" . $error['email'] . "</p> \
" : null;
        $response .= (isset($error['comments'])) ? "<p id='error3'>" . $error['comments'] . "</p>" : null;
        $response .= (isset($error['robotest'])) ? "<p id='error4'>" . $error['robotest'] . "</p>" : null;
        
        echo $response;
    } # end if there was an error sending

?>

That’s not very clear. What is not working?

Is your form submitting at all? Prove it. Add this at line one.


<?php
var_dump($_POST);

What, does it really load itself?


require_once('class.sendemail.php');

Did this object instantiate? How can you prove it?


$mail = new PHPMailer();

Turn on error_reporting at the top of the page and set it to show all errors.


<?php
// temporary code you use on a dev server if you do not run with error reporting
 error_reporting(E_ALL);
 ini_set("display_errors", 1);

// now do your var_dump
var_dump($_POST);

// now continue with your code


When developing, don’t send the email at first, assemble all the variables and just echo them onto the page so they look like an email.

Add the actual emailing in last.

Does all your error handling work? Prove it by submitting errors one by one, then all at once and look carefully at a) var_dump($_POST) and b) your own error messages in response.

PS Can you also wrap any PHP code in square bracket tags like this [ PHP ] … your code [ /PHP ] <- but WITHOUT the spaces. Cheers!

Dear Cups,

Thanks for your reply! But that’s all Chines to me :wink:

With the current PHP code the form is sent when the Honeypot is filled in and also when you leave it blank.

The contact form is just a standard form and I have customised/added:

$robotest = $_POST[‘robotest’];

if (strlen($robotest) > 2) {
$error[‘robotest’] = “You are a bot”;
}

$response .= (isset($error[‘robotest’])) ? “<p id=‘error4’>” . $error[‘robotest’] . “</p>” : null;

My best guess is that part 3 is wrong…

But my guesses don’t bring solutions, so

Your advised “var_dump($_POST);” gives the following result:

array(3) { [“name”]=> string(5) “Test” [“email”]=> string(14) “test@test.com” [“comments”]=> string(5) “Test” }
Notice: Undefined index: robotest in sendemail.php on line 19

Notice: Undefined variable: error in sendemail.php on line 40

Here I have stripped out a lot of the dependencies in an effort to just get to the point, get the logic working correctly and then prove it is working (all as one file for the moment which submits to itself).

sendemail.php


<div id="contactform"> 
<div id="response"></div>
<form method="POST" action="sendemail.php" class="form">
<div id="main">
<p class="name">
<input type="text" name="name" id="name" />
<label for="name" class="overlabel">Name</label>
</p>
<p class="email">
<input type="text" name="email" id="email" />
<label for="email" class="overlabel">E-mail</label>
</p>
<p class="text">
<textarea name="comments" id="comments" ></textarea>
<label for="comments" class="overlabel">Comments</label>
</p>
<!-- Honeypot -->
<p class="robotic" id="pot">
<input type="text" name="robotest" id="robotest" />
<label for="robotest" class="overlabel">Leave this blank</label>
</p>
<p class="submit">
<button type="submit" name="submit" id="submit" class="graybutton">Send e-mail</button>
</p>

</div><!--end main-->
</form>
</div><!--end contact form-->


<?php
// var_dump($_POST);  // remove this before going live

$name = trim($_POST['name']);
$email = $_POST['email'];
$comments = $_POST['comments'];
$robotest = $_POST['robotest'];

$site_owners_email = 'xxx@xxx.xxx'; 
$site_owners_name = 'Xxx Xxx'; 

$error = array() ; // intialise the array prior to adding new items to it

if (strlen($name) < 2) {
$error['name'] = "Enter your name";	
}

if ( filter_var( $email, FILTER_VALIDATE_EMAIL) === false )  {  // PHP5 onwards
$error['email'] = "Enter a valid e-mail";	
}

if (strlen($comments) < 3) {
$error['comments'] = "Leave a comment";
}

if (strlen($robotest) > 2) {
$error['robotest'] = "You are a bot";
}

if (empty($error) ) {  // check if the array is still empty

  echo "<p> Message to be sent below </p>";  // spoof email output for now ...
  echo 'FROM: ' .  $email ;
  echo 'NAME:  ' . $name ;
  echo 'SUBJECT : ' . "Bericht via de website";
  echo 'SITE OWNER: ' . $site_owners_name;
  echo 'BODY ' . $comments;

}else{

  $response = "Error found : " ;  // initialise the variable clearly

  foreach($error as $err){  // loop through the array of errors
    $response .= $err . PHP_EOL ;  // NOW you can concatenate to the variable
  }

echo $response;
}

Its up to you to line by line, add the things you want back in. Each time you add a line or a block of code you test it still works, then carry on.

Be warned I know nothing about PHPMailer, you are sending it naked vars that could contain just about anything (except the email address).

Does PHPMailer really sanitise variables for you? Be ready to prove it, maybe read the docs.

Otherwise if you are planning to output any of those vars onto the screen, such as “Thank you testname” make sure you Escape that var.

Read about it here. [google]PHP escape output[/google]. If you are not sure what that means then ask.

Here is how I did it. Should help http://www.visibilityinherit.com/code/simple-php-honeypot.php

Thanks Cups,

Have tried, but failed. Am I missing the line that says “send the e-mail”?
I will try later to check your code with mine and compare the differences. Then add lines to it, when neccessary.
So strange there is not one PHP line that says: If the Honeypot is filled in then don’t do anything, Otherwise just follow the existing script.

Will check your link later and learn more about PHP.

Have a nice weekend!

Thanks Eric,

Have also tried this simple honeypot, but after intergrating it into the existing scirpt also the SPAM e-mail is send to me.
I have put the if($_POST[‘honeypot’] above all the other lines with if($_POST

Is this the wrong location?

Sorry. i dont kow why. This is the only way I know to do it. http://www.visibilityinherit.com/code/how-to-html-form-with-php-js-captcha-validation.php

FYI. If you add my honeypot code to my script it will work

Using:

if (strlen($robotest) &lt; 2) {
    $error['robotest'] = "You are a bot";
}

Results into all forms being send (with and without filling in the “honeypot”).

Using:

if (strlen($robotest) &gt; 2) {
    $error['robotest'] = "You are a bot";
}

Results into all forms not being send with error “You are a bot” (with and without filling in the “honeypot”).

Conclusion:
Fail is in the part were the php should say:
IF the input in robotest is empty THEN proceed the checking the rest of the input of the form ELSE if the input in robotest is not empty THEN give error “You are a bot”.

Who gives me the last push?

Have a nice weekend!

Found the solution!

Just added the “ROBOTEST” in the javascript part and now it’s working like supposed!

    var name = $('input#name').val();
    var email = $('input#email').val();
    var comments = $('textarea#comments').val();
    var robotest = $('input#robotest').val();

    $.ajax({
        type: 'post',
        url: 'sendemail.php',
        data: 'name=' + name + '&email=' + email + '&comments=' + comments + '&robotest=' + robotest,