Page 1 of 1

captcha + swiftmailer

Posted: Thu May 10, 2007 4:41 am
by mrdebian
Hello all,

I got the captcha code from:
http://www.white-hat-web-design.co.u...hp-captcha.php
and tried to included in a form using the swiftmailer (http://www.swiftmailer.org/) but cannot make it work.

The form is working great and all validations are working except the captcha.
I tried a lot of combinations without success.
Below I'm pasting the action php file plus the form

Code: Select all

<?php
   session_start();

//Display an error if something went wrong
if (!empty($_GET["error"]))
{
    switch ($_GET["error"])
    {
        case "not_enough_info": ?>
            <strong style="color: red;">You need to complete all fields marked *<strong><?php
            break;
        case "invalid_email": ?>
            <strong style="color: red;">Please provide a valid email address</strong><?php
            break;
        case "upload_failed": ?>
            <strong style="color: red;">The file you uploaded failed to attach, this could be a temporary problem.
            Please try later.</strong><?php
            break;
        case "sending_failed": ?>
            <strong style="color: red;">Temporary problem, please try later.</strong><?php
            break;
    }
}

?>

<?php
   if(($_SESSION['security_code'] == $_POST['security_code']) && (!empty($_SESSION['security_code'])) ) {
      // Insert you code for processing the form here, e.g emailing the submission, entering it into a database.
      unset($_SESSION['security_code']);
   } else {
      // Insert your code for showing an error message here

?>

<form action="handle_form.php" method="post" enctype="multipart/form-data">
    <table>
        <tr>
            <td class="label">Name *</td>
            <td><input type="text" name="sender_name" value="" /></td>
        </tr>
        <tr>
            <td class="label">E-mail address *</td>
            <td><input type="text" name="sender_email" value="" /></td>
        </tr>
        <tr>
            <td class="label">Title *</td>
            <td><input type="text" name="comment_title" value="" /></td>
        </tr>
        <tr>
            <td class="label">Attachment (optional)</td>
            <td><input type="file" name="attachment" /></td>
        </tr>
        <tr>
            <td colspan="2">Comment *<br />
                <textarea name="comment_body" rows="10" cols="60"></textarea></td>
        </tr>
        <tr>
            <td>Security Code: *
            <input id="security_code" name="security_code" type="text" />
            <img src="../../includes/captcha.php?width=150&height=50&characters=5" />
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" name="submit" value="Submit" /></td>
        </tr>
    </table>
</form>
<?php
}
?>

and:

Code: Select all

<?php
session_start();

//Check if the required fields were sent
// Redirect back to the form if not


//Check if the required fields were sent
// Redirect back to the form if not
if (empty($_POST["sender_name"]) || empty($_POST["sender_email"])
    || empty($_POST["comment_title"]) || empty($_POST["comment_body"]))
{
    //redirect back to form
    header("Location: ./contactUs.php?error=not_enough_info"); //This should really be an absolute URL if you know it
    exit();
}


//Copy into global variables
$name = $_POST["sender_name"];
$email = $_POST["sender_email"];
$title = $_POST["comment_title"];
$body = $_POST["comment_body"];

//Validate the email address using a regex (I suggest you use a better one than this!!)
if (!preg_match("/[a-zA-Z0-9_\\.-]+@[a-zA-Z0-9_\\.-]+/", $email))
{
    header("Location: ./contactUs.php?error=invalid_email");
    exit();
}

//Check if an attachment was uploaded
$file_path = false;
$file_name = false;
$file_type = false;
if (!empty($_FILES["attachment"]["tmp_name"]))
{
    if ($_FILES["attachment"]["error"])
    {
        //Redirect if the upload has failed
        header("Location: ./contactUs.php?error=upload_failed");
        exit();
    }
    $file_path = $_FILES["attachment"]["tmp_name"];
    $file_name = $_FILES["attachment"]["name"];
    $file_type = $_FILES["attachment"]["type"];
}

//Everything looks ok, we can start Swift

require_once "../../includes/swift/lib/Swift.php";
require_once "../../includes/swift/lib/Swift/Connection/SMTP.php";

//Enable disk caching if we can
if (is_writable("/tmp"))
{
    Swift_CacheFactory::setClassName("Swift_Cache_Disk");
    Swift_Cache_Disk::setSavePath("/tmp");
}

//Create a Swift instance
$swift =& new Swift(new Swift_Connection_SMTP("mail.mydomain.com"));

//Create the sender from the details we've been given
$sender =& new Swift_Address($email, $name);

//Create the message to send
$message =& new Swift_Message("New comment: " . $title);
$message->attach(new Swift_Message_Part($body));

//If an attachment was sent, attach it
if ($file_path && $file_name && $file_type)
{
    $message->attach(
        new Swift_Message_Attachment(new Swift_File($file_path), $file_name, $file_type));
}

//Try sending the email
$sent = $swift->send($message, "admin@mydomain.com", $sender);
//Disconnect from SMTP, we're done
$swift->disconnect();

if ($sent)
{
    header("Location: ./success.php");
    exit();
}
else
{
    header("Location: ./contactUs.php?error=sending_failed");
    exit();
}
?>
Any help is much appreciated.

Thanks

d11wtq | Please use

Code: Select all

 [/ php] tags when posting PHP code in the forum[/color]

Posted: Thu May 10, 2007 10:41 am
by Chris Corbyn
I don't see where you check the captcha code in the form_handler.php file. You only seem to check it at the form page, which can be completely by-passed anyway ;)

Posted: Thu May 10, 2007 11:23 am
by mrdebian
Hi d11wtq,

Thanks for the reply.
Are you saying that is not necessary at the form page and needs to be checked only at the action php page?
I tried that too but also got ignored.
Would you please be more specific about how to place the check code that posted above to the form_handler.php page?

Thanks a lot

Posted: Thu May 10, 2007 1:30 pm
by Chris Corbyn
mrdebian wrote:Are you saying that is not necessary at the form page and needs to be checked only at the action php page?
Yes. You need to generate the captcha on the form page, but you need to verify the value on the action page.

As you have it now, I could easily just write my own form in HTML, point the "action" attribute to your form_handler.php and because your form_handler.php knows nothing about your captcha it will still work.

Code: Select all

<?php

session_start();

//Display an error if something went wrong
if (!empty($_GET["error"]))
{
    switch ($_GET["error"])
    {
        case "not_enough_info": ?>
            <strong style="color: red;">You need to complete all fields marked *<strong><?php
            break;
        case "invalid_email": ?>
            <strong style="color: red;">Please provide a valid email address</strong><?php
            break;
        case "upload_failed": ?>
            <strong style="color: red;">The file you uploaded failed to attach, this could be a temporary problem.
            Please try later.</strong><?php
            break;
        case "sending_failed": ?>
            <strong style="color: red;">Temporary problem, please try later.</strong><?php
            break;
        case "bad_captcha": ?>
            <strong style="color: red;">The code from the image was not correct.</strong><?php
            break;
    }
}

?>
<form action="handle_form.php" method="post" enctype="multipart/form-data">
    <table>
        <tr>
            <td class="label">Name *</td>
            <td><input type="text" name="sender_name" value="" /></td>
        </tr>
        <tr>
            <td class="label">E-mail address *</td>
            <td><input type="text" name="sender_email" value="" /></td>
        </tr>
        <tr>
            <td class="label">Title *</td>
            <td><input type="text" name="comment_title" value="" /></td>
        </tr>
        <tr>
            <td class="label">Attachment (optional)</td>
            <td><input type="file" name="attachment" /></td>
        </tr>
        <tr>
            <td colspan="2">Comment *<br />
                <textarea name="comment_body" rows="10" cols="60"></textarea></td>
        </tr>
        <tr>
            <td>Security Code: *
            <input id="security_code" name="security_code" type="text" />
            <img src="../../includes/captcha.php?width=150&height=50&characters=5" />
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" name="submit" value="Submit" /></td>
        </tr>
    </table>
</form>

Code: Select all

<?php

session_start();

/*** START MODIFICATION ***/

//Check if the required fields were sent
// Redirect back to the form if not
if (empty($_POST["sender_name"]) || empty($_POST["sender_email"])
    || empty($_POST["comment_title"]) || empty($_POST["comment_body"])
    //Added this check
    || empty($_POST["security_code"]) || empty($_SESSION["security_code"]))
{
    //redirect back to form
    header("Location: ./contactUs.php?error=not_enough_info"); //This should really be an absolute URL if you know it
    exit();
} 

//And checked here
if ($_SESSION['security_code'] != $_POST['security_code'])
{
    //redirect back to form
    header("Location: ./contactUs.php?error=bad_captcha");
    exit();
}

unset($_SESSION['security_code']);

/*** END MODIFICATION ***/

//Copy into global variables
$name = $_POST["sender_name"];
$email = $_POST["sender_email"];
$title = $_POST["comment_title"];
$body = $_POST["comment_body"];

//and the rest....

Posted: Thu May 10, 2007 2:21 pm
by mrdebian
Thanks a lot d11wtq. It works great now apart from displaying the captcha text error but that wont be difficult to fix it.

Cheers

Posted: Thu May 10, 2007 7:01 pm
by Chris Corbyn
Glad I could help.

(My eyes are all blurry, it's late and the bottle of wine was a bad idea on a week night :oops:)