<?php

/*
    Created by Ben Huddleston.  http://www.minc.info, http://www.redwingstudio.com
    Based on work by:
    
    Simon Willison - http://simonwillison.net/2003/Jun/17/theHolyGrail/
    Stephen Poley - http://www.xs4all.nl/%7Esbpoley/webmatters/formval.html
    Andrew Walsh - http://awalsh.net/ 

*/

/*
safe_mail()
Fix all of the bloody exploits for MIME and whatever else, such as injection.

Strip all of the LF and CR, and then make sure there's no MIME or boundary information:
version 1.0.0 (28 Oct 2005)
*/    

function safe_mail($p_to,$p_subject,$p_message,$p_headers=null,$p_paramaters=null)
{
    
$format_good 1;
    
    if (
eregi("\r",$p_to) || eregi("\n",$p_to)){
        
$format_good 0;
    }
    if (
eregi("\r",$p_subject) || eregi("\n",$p_subject)){
        
$format_good 0;
    }
    if (
eregi("\r",$p_headers) || eregi("\n",$p_headers)){
        
$format_good 0;
    }
    
    
//now check for MIME encoding in the $message field
    
$mimecount substr_count(strtolower($p_message), strtolower("Content-Type"));    
    if(
$mimecount!=0)
    {
        
$format_good 0;
    }
    
$mimecount substr_count(strtolower($p_message), strtolower("boundary="));    
    if(
$mimecount!=0)
    {
        
$format_good 0;
    }
    
//afew more checks just incase we miss the to and from, etc:
    
$mimecount substr_count(strtolower($p_to), strtolower("Content-Type"));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_to), strtolower("boundary="));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_subject), strtolower("Content-Type"));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_subject), strtolower("boundary="));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_message), strtolower("Content-Type"));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_message), strtolower("boundary="));    
    if(
$mimecount!=0){$format_good 0;}    
    
$mimecount substr_count(strtolower($p_headers), strtolower("Content-Type"));    
    if(
$mimecount!=0){$format_good 0;}
    
$mimecount substr_count(strtolower($p_headers), strtolower("boundary="));    
    if(
$mimecount!=0){$format_good 0;}    
    
    
    
//now if $format_good is 1, we are safe, if not, we log it.
    
if($format_good==1)
    {
        
$result mail($p_to,$p_subject,$p_message,$p_headers);
        return(
$result);
    
    }else
    {
        echo 
"Bad Data.  Your submission included invalid information!";
        return(
FALSE);
    }
    
    
    
    return(
FALSE);
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Ajax Contact Form with PHP fallback</title>

<!-- test for javascript -->
<script type="text/javascript">document.cookie = "jscript=Yes; path=/";</script>
<!-- end test for javascript -->
<script type="text/javascript" src="formval.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>
<body>

<?php
// this is for the php form if no javascript cookie is detected
// we have to have this here so it catches it before the ajax stuff happens
// this is to keep the following situation from happening
// a user hits the page but doesn't have the cookie yet and they fill out the form
// he/she submits the form, but now the cookie is set so it shows them the AJAX form
// rather than posting the form. 
if($_POST) {
    
    
include(
'FormProcessor.class.php');

$form = <<<EOD
<form id="contactform" action="index.php" method="post">
<errorlist>
<ul class="errorlist">
<erroritem>
<li class="errormessage"><message /></li>
</erroritem>
</ul>
</errorlist>
<div id="error">&#160;</div>
<div>
 <label for="first_name">First Name: </label>
 <input type="text" name="first_name" id="first_name" compulsory="yes" validate="name" callback="uniqueName" size="20"  onchange="validateName(this, 'inf_first_name', true);" /><span id="inf_first_name">&#160;</span><error for="first_name"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="first_name" test="compulsory">You did not enter your first name</errormsg>
<errormsg field="first_name" test="alpha">Your name must consist <em>only</em> of letters</errormsg>
<div>
 <label for="last_name">Last Name: </label>
 <input type="text" name="last_name" id="last_name" compulsory="yes" validate="name" callback="uniqueName" size="20"  onchange="validateName(this, 'inf_last_name', true);"  /><span id="inf_last_name">&#160;</span><error for="last_name"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="last_name" test="compulsory">You did not enter your last name</errormsg>
<errormsg field="last_name" test="alpha">Your name must consist <em>only</em> of letters</errormsg>
<div>
 <label for="email">Email: </label>
 <input type="text" name="email" id="email" compulsory="yes" validate="email" size="20" onchange="validateEmail(this, 'inf_email', true);" /><span id="inf_email">&#160;</span><error for="email"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="email" test="compulsory">You must provide an email address</errormsg>
<errormsg field="email" test="validate">Your email contains invalid characters</errormsg>
<div>
 <label for="phone">Phone Number: </label>
 <input type="text" name="phone" id="phone" compulsory="yes" validate="phone" size="20" onchange="validateTelnr(this, 'inf_phone', true);"  /><span id="inf_phone">&#160;</span><error for="phone"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="phone" test="compulsory">You must provide a phone number</errormsg>
<errormsg field="phone" test="validate">Your phone number contains invalid characters</errormsg>
<div>
 <label for="comments">Comments: </label>
 <textarea name="comments" id="comments" compulsory="no" validate="textarea" cols="40" rows="10"></textarea><error for="comments"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="comments" test="validate">Your comments contain invalid characters</errormsg>
<div><input type="submit" value="Submit" /></div>
</form>
EOD;




function 
uniqueName($name) {
    return 
true;
}

$processor =& new FormProcessor($form);
if (
$processor->validate()) {
//echo '<p>Form data is OK.</p><pre>';
//print_r($_POST);
//echo '</pre>';

// get the posted values
$firstname $_POST["first_name"];
$lastname $_POST["last_name"];
$email $_POST["email"];
$phone $_POST["phone"];
$comments $_POST["comments"];
$contact_type "Regular Contact Form";
$name "$firstname $lastname";

$timenow date("m-d-Y");
$Subject "Contact Form";
$browser getenv('HTTP_USER_AGENT');
$ip getenv('REMOTE_ADDR');
                            
// format message
$message "
Date: $timenow
Name: $firstname $lastname
Email: $email
Phone: $phone
-----------------------------
Comments: $comments    
-----------------------------

IP: $ip
Browser: $browser


** Note all email addresses have been stripped of the 'at' sign and replaced with '_at_'. This is to protect the form from being used as a spam relay. **
"
;
    
// yank any @ symbols out to make sure no one can use this to spam anyone
// except the intended recipient                        
$message str_replace("@","_at_",$message);

// want to send an SMS message? send it via teleflip
// format the teleflip message                            
$message2 "
$firstname $lastname
($areacode) $localcode-$phonenumbers
"
;

// send the contact to the intended recipient    
$hurrah safe_mail("youremail@yourdomain.com",$Subject,$message);
// send the SMS?  uncomment line below and replace 1231231234 with the appropriate phone number
//$hurrah = safe_mail("1231231234@teleflip.com",$Subject,$message);
    
    
if($hurrah != TRUE) {
            echo 
"<b>Internal mailer error.</b><br />";
        } else {
            echo 
"<p><strong>Message sent.</strong><br />Thank you for your interest.  We will be contacting you shortly.</p>";
        }
        
} else {
    
$processor->display();
}

    
// no POST
    
} else {
    
// we have a javascript cookie so import the scripts
    
if ($_COOKIE["jscript"] =="Yes") {
    
?>        

<script type="text/javascript">

function createRequestObject() {
    var ro;
    var browser = navigator.appName;
    if(browser == "Microsoft Internet Explorer"){
        ro = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        ro = new XMLHttpRequest();
    }
    return ro;
}

var http = createRequestObject();

function sendemail() {
    var comments = document.contactform.comments.value;
    var first_name = document.contactform.first_name.value;
    var last_name = document.contactform.last_name.value;
    var email = document.contactform.email.value;
    var phone = document.contactform.phone.value;
    document.contactform.send.disabled=true; 
    document.contactform.send.value='Sending....';

        http.open('POST', 'form_processor.php','true');
        http.onreadystatechange = handleResponse;
        // force no-cache so browser always makes request and doesn't use cache'd results
        http.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
        // tell server this is a form submission
        http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        http.send('comments='+comments+'&first_name='+first_name+'&last_name='+last_name+'&phone='+phone+'&email='+email+'&action=send');
}

function handleResponse() {
    if(http.readyState == 4){
        var response = http.responseText;
        var update = new Array();

        if(response.indexOf('|' != -1)) {
            update = response.split('|');
            document.getElementById(update[0]).innerHTML = update[1];
                 document.contactform.send.disabled=false; 
                        document.contactform.send.value='Send Email';
        }
    }
}
</script>
<?php
    
} else {
    
//don't do anything
    
}
    
    
// we have a javascript cookie so show the AJAX form
    
if ($_COOKIE["jscript"] =="Yes") {
?>
<div id="contactarea">
  <form name="contactform" id="contactform" action="#">
        <div id="error">&#160;</div>
        <div>
    <label>First Name:</label>
    <input type="text" name="first_name" class="inputbox" onchange="validateName(this, 'inf_first_name', true);" />
        <span id="inf_first_name" >&#160;</span>
    </div>
        <div>        
        <label>Last Name:</label>
    <input type="text" name="last_name" class="inputbox" onchange="validateName(this, 'inf_last_name', true);" />
        <span id="inf_last_name">&#160;</span>
    </div>
        <div>
    <label>Email:</label>
    <input type="text" name="email" class="inputbox" onchange="validateEmail(this, 'inf_email', true);" />
        <span id="inf_email">&#160;</span>
    </div>
        <div>
    <label>Phone:</label>
    <input type="text" name="phone" class="inputbox" onchange="validateTelnr(this, 'inf_phone', true);" />
        <span id="inf_phone">&#160;</span>
    </div>
        <div>
    <label>Comments:</label>
    <textarea name="comments" cols="40" rows="10" id="textarea"></textarea>
    </div>
        <div>
    <input type="button" value="Send Email" name="send" onClick="sendemail();" id="submitbutton" />
        </div>
  </form>
</div>
<?php 
    
// we don't have a javascript cookie so show the PHP form
    
} else {

include(
'FormProcessor.class.php');

$form = <<<EOD
<form id="contactform" action="index.php" method="post">
<errorlist>
<ul class="errorlist">
<erroritem>
<li class="errormessage"><message /></li>
</erroritem>
</ul>
</errorlist>
<div id="error">&amp;#160;</div>
<div>
 <label for="first_name">First Name: </label>
 <input type="text" name="first_name" id="first_name" compulsory="yes" validate="name" callback="uniqueName" size="20"  onchange="validateName(this, 'inf_first_name', true);" /><span id="inf_first_name">&#160;</span><error for="first_name"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="first_name" test="compulsory">You did not enter your first name</errormsg>
<errormsg field="first_name" test="alpha">Your name must consist <em>only</em> of letters</errormsg>
<div>
 <label for="last_name">Last Name: </label>
 <input type="text" name="last_name" id="last_name" compulsory="yes" validate="name" callback="uniqueName" size="20"  onchange="validateName(this, 'inf_last_name', true);"  /><span id="inf_last_name">&#160;</span><error for="last_name"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="last_name" test="compulsory">You did not enter your last name</errormsg>
<errormsg field="last_name" test="alpha">Your name must consist <em>only</em> of letters</errormsg>
<div>
 <label for="email">Email: </label>
 <input type="text" name="email" id="email" compulsory="yes" validate="email" size="20" onchange="validateEmail(this, 'inf_email', true);" /><span id="inf_email">&#160;</span><error for="email"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="email" test="compulsory">You must provide an email address</errormsg>
<errormsg field="email" test="validate">Your email contains invalid characters</errormsg>
<div>
 <label for="phone">Phone Number: </label>
 <input type="text" name="phone" id="phone" compulsory="yes" validate="phone" size="20" onchange="validateTelnr(this, 'inf_phone', true);"  /><span id="inf_phone">&#160;</span><error for="phone"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="phone" test="compulsory">You must provide a phone number</errormsg>
<errormsg field="phone" test="validate">Your phone number contains invalid characters</errormsg>
<div>
 <label for="comments">Comments: </label>
 <textarea name="comments" id="comments" compulsory="no" validate="textarea" cols="40" rows="10"></textarea><error for="comments"> <strong class="error"><img src="alert.png" alt="alert!" /></strong></error>
</div>
<errormsg field="comments" test="validate">Your comments contain invalid characters</errormsg>
<div><input type="submit" value="Submit" /></div>
</form>
EOD;


function 
uniqueName($name) {
    return 
true;
}

$processor =& new FormProcessor($form);
if (
$processor->validate()) {
//echo '<p>Form data is OK.</p><pre>';
//print_r($_POST);
//echo '</pre>';

// get the posted values
$firstname $_POST["first_name"];
$lastname $_POST["last_name"];
$email $_POST["email"];
$phone $_POST["phone"];
$comments $_POST["comments"];
$contact_type "Regular Contact Form";
$name "$firstname $lastname";

$timenow date("m-d-Y");
$Subject "Contact Form";
$browser getenv('HTTP_USER_AGENT');
$ip getenv('REMOTE_ADDR');
                            
// format message
$message "
Date: $timenow
Name: $firstname $lastname
Email: $email
Phone: $phone
-----------------------------
Comments: $comments    
-----------------------------

IP: $ip
Browser: $browser


** Note all email addresses have been stripped of the 'at' sign and replaced with '_at_'. This is to protect the form from being used as a spam relay. **
"
;
    
// yank any @ symbols out to make sure no one can use this to spam anyone
// except the intended recipient                        
$message str_replace("@","_at_",$message);

// want to send an SMS message? send it via teleflip
// format the teleflip message                            
$message2 "
$firstname $lastname
($areacode) $localcode-$phonenumbers
"
;

// send the contact to the intended recipient    
$hurrah safe_mail("youremail@yourdomain.com",$Subject,$message);
// send the SMS?  uncomment line below and replace 1231231234 with the appropriate phone number
//$hurrah = safe_mail("1231231234@teleflip.com",$Subject,$message);
    
    
if($hurrah != TRUE) {
            echo 
"<b>Internal mailer error.</b><br />";
        } else {
            echo 
"<p><strong>Message sent.</strong><br />Thank you for your interest.  We will be contacting you shortly.</p>";
        }
        
    } else {
    
$processor->display();
    }


    } 
// end show PHP form
    
// end else no post
?>
</body>
</html>