[php]<?php
session_start();
// define security constant
define(“contact_form”, true);
// define paths to includes
define(“config_file”, “config.php”);
define(“form_file”, “form.php”);
class Contact_Form {
var $config;
var $errors;
var $data;
var $success;
var $form_file;
var $id;
function Contact_Form($config_file = NULL, $form_file = NULL) {
$this->Jane Dirr <[email protected]>Jane Dirr <[email protected]>errors = array();
$this->data = array();
// load configuration
if ( !empty($config_file) ) {
require ( $config_file );
} else {
require( config_file );
}
$this->config = $config;
if ( !empty($form_file) ) {
$this->form_file = $form_file;
} else {
$this->form_file = form_file;
}
if (!empty($this->config['identifier'])) {
$this->id = $this->config['identifier'];
} else {
$this->id = 'contact-form';
}
if (isset($_POST['submit'])) {
$this->processForm();
}
}
// These are wrapper functions for the session variable naming
// used to support multiple forms without getting session data
// mixed up between forms
function getSessionVar($name) {
if (!empty($_SESSION['acf_'.$this->id.'_'. $name])) {
return $_SESSION['acf_'.$this->id.'_'. $name];
} else {
return false;
}
}
function checkSessionVar($name) {
$val = $this->getSessionVar($name);
if (!empty($val)) {
return true;
} else {
return false;
}
}
function updateSessionVar($name, $value) {
$_SESSION['acf_'.$this->id.'_'. $name] = $value;
return true;
}
function clearSessionVar($name) {
unset($_SESSION['acf_'.$this->id.'_'. $name]);
return true;
}
// End the session wrapper functions
// Onto the form functions:
function displayForm() {
// show the form file
require( $this->form_file );
}
function displayCaptcha() {
if ( $this->checkSessionVar('temp_captcha') ) {
$hash = $this->getSessionVar('temp_captcha');
$this->clearSessionVar('temp_captcha');
// generate image
$captcha = imagecreatefrompng($this->config['captcha_base']);
// allocate colours
$black = imagecolorallocate($captcha, 0, 0, 0);
$blue = imagecolorallocate($captcha, 0, 75, 117);
$num_lines = mt_rand(2,4);
for ($i = 1; $i <= $num_lines; $i++) {
imageline($captcha,mt_rand(0,93),0,mt_rand(20,73),80,$black);
}
$hash = str_split($hash);
$num_letter = 1;
foreach ( $hash as $letter ) {
imagestring($captcha, mt_rand(5,7), 10+(12*$num_letter), 6+mt_rand(0,8), $letter, $blue);
$num_letter++;
}
header("Content-type: image/png");
imagepng($captcha);
}
return;
}
function getCaptcha() {
if ( $this->config['use_captcha'] == TRUE ) {
$hash = substr(sha1(mt_rand() * microtime()),0,5);
$this->updateSessionVar('temp_captcha', $hash);
$this->updateSessionVar('captcha', sha1($hash));
echo "<img src=\"". $this->config['captcha_path'] ."\" alt=\"Verification image\" class=\"captcha\" />";
} else if ( $this->config['use_check'] == TRUE ) {
// add two numbers
$num1 = mt_rand(1,6);
$num2 = mt_rand(1,6);
$this->updateSessionVar('check', "{$num1}+{$num2}");
echo "{$num1} + {$num2} = ";
} else {
// no verification
return false;
}
}
function generateHash() {
// generate the single-time security hash
$hash = sha1(uniqid('') * time() * mt_rand());
$hash = substr($hash, 0, 12);
// store the unencrypted hash in the session variable
$this->updateSessionVar('hash', $hash);
// now encrypt it to use in the form
$form_hash = sha1($hash);
echo "<input type='hidden' name='hash' value='".$form_hash."' />";
}
// used in forms to retrieve value
// can use second and third arguments to show $display if the value == $check
// if fourth argument is TRUE then it will treat the string as a comma separated list
// and if the value matches one of the items, it will return true
function value($field, $check = NULL, $display = NULL, $csl = FALSE) {
if ( $csl == TRUE ) {
if ( $check !== NULL && $display !== NULL ) {
if ( !empty($this->data[$field]) ) {
$this->data[$field] = str_replace(",",", ",$this->data[$field]);
$value = explode(',',$this->data[$field]);
if ( in_array($check,$value) ) {
echo $display;
} else {
return false;
}
}
}
} else {
if ( $check !== NULL && $display !== NULL ) {
if ( @strtolower($this->data[$field]) == strtolower($check) ) {
echo $display;
}
} else if ( !empty($this->data[$field]) ) {
echo $this->data[$field];
} else {
return false;
}
}
return false;
}
function success() {
if (!empty($this->success)) {
return true;
}
return false;
}
function getSuccess() {
if ($this->success()) {
echo $this->config['success_message'];
} else {
return false;
}
}
// End Form Display Functions
// Form Verification Functions
// These are used behind the scenes during form processing
function checkHash($hash) {
if ( !empty($hash) && $this->checkSessionVar('hash') ) {
if ( sha1( $this->getSessionVar('hash') ) == $hash ) {
$this->clearSessionVar('hash');
return true;
}
} else {
return false;
}
}
function checkCaptcha($captcha) {
if ( $this->config['use_captcha'] == TRUE ) {
if ( $this->getSessionVar('captcha') == sha1($captcha) ) {
return true;
} else {
return false;
}
} else if ( $this->config['use_check'] == TRUE ) {
// human verification check
$sum = $this->getSessionVar('check');
if ( empty($sum) ) {
return false;
}
$parts = explode("+", $sum);
if ( $parts[0]+$parts[1] == $captcha ) {
return true;
} else {
return false;
}
} else {
// no verification needd
return true;
}
}
function checkEmail($email) {
if ( preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i', $email) ) {
return true;
} else {
return false;
}
}
// End Form Verification Functions
// Error Handling Functions
function addError($error) {
$this->errors[] = $error;
return true;
}
function hasErrors() {
if ( count($this->errors) > 0 ) {
return true;
} else {
return false;
}
}
function getErrors() {
sort($this->errors);
return $this->errors;
}
function displayErrors($before = '', $after = '') {
if ( $this->hasErrors() ) {
$errors = $this->getErrors();
foreach ($errors as $error) {
echo $before . $error . $after;
}
} else {
return false;
}
}
// End Error Handling Functions
// Now, the big function, this processes the form data
// and validates it, and then stores it in the $this->data array
// If everything is OK, it then goes on to send the email
function processForm() {
$hash = '';
$captcha = '';
// get security hash and CAPTCHA and then check them
if (!empty($_POST['hash'])) {
$hash = $_POST['hash'];
}
if ( !empty($_POST['captcha'])) {
$captcha = $_POST['captcha'];
}
if ( $this->checkHash($hash) ) {
// check captcha
if ( $this->checkCaptcha($captcha) ) {
$secure = true;
} else {
$this->addError("The verification code was incorrect.");
}
} else {
$this->addError('Your session has expired. Please try again.');
}
// now check for the values
$fields = $this->config['fields'];
$data = array(); // this will hold our values
// loop through the fields which have been defined in the config file
foreach ( $fields as $field_name => $field_settings ) {
if (!empty($_POST[$field_name])) {
$data[$field_name] = $_POST[$field_name];
if ( isset($field_settings['type']) ) {
// if a specific type of content has been defined
if ($field_settings['type'] == "email") {
if ( !$this->checkEmail($data[$field_name]) ) {
if ( !empty($this->config['error_field_'. $field_name]) ) {
$this->addError($this->config['error_field_'. $field_name]);
} else {
$this->addError( $this->config['error_invalid_email'] );
}
}
} else if ( $field_settings['type'] == "number" ) {
if ( !is_numeric($data[$field_name]) ) {
if ( !empty($this->config['error_field_'. $field_name]) ) {
$this->addError($this->config['error_field_'. $field_name]);
} else {
$this->addError( $this->config['error_invalid_number'] );
}
}
}
}
if ( isset($field_settings['length']) ) {
if ( strlen($data[$field_name]) !== $field_settings['length']) {
if ( !empty($this->config['error_field_'. $field_name]) ) {
$this->addError($this->config['error_field_'. $field_name]);
} else {
$this->addError( $this->config['error_invalid_length'] );
}
}
}
if ( @is_array($data[$field_name]) ) {
$content = '';
foreach ( $data[$field_name] as $val ) {
$content .= $val . ', ';
}
$data[$field_name] = $val;
}
} else {
if ( isset($field_settings['required']) && $field_settings['required'] == true ) {
// support customised error messages for required fields
if ( !empty($this->config['error_field_'. $field_name]) ) {
$this->addError($this->config['error_field_'. $field_name]);
} else {
$this->addError($this->config['error_missing_field']);
}
}
}
}
// store the data as a class variable so it can be accessed by the form functions
$this->data = $data;
// save the IP address
$this->data['ip'] = $_SERVER['REMOTE_ADDR'];
// now based on whether we authenticated correctly, the script will either return the errors or will send the email
if ( !$this->hasErrors() ) {
$this->sendEmail();
// check again to see if any errors were generated
// in the sending process
if ( !$this->hasErrors() ) {
if ( !empty($this->config['success_page']) ) {
header("Location: {$this->config['success_page']}");
} else {
$this->success = true;
}
}
}
// when the form is displayed, errors will be shown
}
function sendEmail() {
$recipient = $this->config['address'];
// email field name
$email_field = $this->config['email_field'];
// now replace the double square-bracket-enclosed variables with the real thing.
$body = $this->config['body'];
$subject = $this->config['subject'];
$from = $this->data[$email_field];
$sender_body = '';
$sender_subject = '';
if ( $this->config['sender_copy'] == true ) {
$sender_body = $this->config['sender_body'];
$sender_subject = $this->config['sender_subject'];
}
foreach ( $this->data as $name => $value ) {
$body = str_replace("[[{$name}]]", $value, $body);
$subject = str_replace("[[{$name}]]", $value, $subject);
$sender_body = str_replace("[[{$name}]]", $value, $sender_body);
$sender_subject = str_replace("[[{$name}]]", $value, $sender_subject);
}
if ( $this->config['raw'] == TRUE ) {
$body .= "\n\nFields submitted:\n";
foreach( $this->data as $name => $value ) {
$body .= "{$name}: {$value}\n";
}
}
$headers = "From: {$from}\r\nReply-To: {$from}\r\n";
if (!@mail( $recipient, $subject, $body, $headers )) {
$this->addError('The email could not be sent due to a problem with the current server setup.');
}
if ( $this->config['sender_copy'] == true ) {
$sender_from = $this->config['sender_email'];
$sender_headers = "From: {$sender_from}\r\n";
mail( $from, $sender_subject, $sender_body, $sender_headers );
}
return true;
}
}
// initialise the contact form
// you could set parameters for this to handle multiple forms from the same script
// or you could use two forms on the same page by duplicating the code and changing the variable name
$form = new Contact_Form();
/*** END OF FILE ***/[/php]