Skip to content

Instantly share code, notes, and snippets.

@stevenpray
Last active August 29, 2015 13:58
Show Gist options
  • Save stevenpray/10078771 to your computer and use it in GitHub Desktop.
Save stevenpray/10078771 to your computer and use it in GitHub Desktop.
PHP Message Form
<?php
/**
* Message Form
*
* @author Steven Pray <steven@stevenpray.com>
* @copyright Copyright (c) 2014 Steven Pray
* @license http://www.opensource.org/licenses/mit-license.php MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* in the Software without restriction, including without limitation the rights
* deal to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
define('MAIL_TO', 'hello@example.com');
define('FORM_ID', 'message_form');
$form_field_names = array('name', 'email', 'phone', 'message');
session_start();
$form_processed =& $_SESSION['form_processed_' . FORM_ID];
$form_submitted = ($_SERVER['REQUEST_METHOD'] === 'POST');
$form_values = array();
$form_errors = array('form' => false);
foreach ($form_field_names as $field_name) {
$form_values[$field_name] = isset($_REQUEST[$field_name]) ? trim($_REQUEST[$field_name]) : '';
$form_errors[$field_name] = false;
}
if ($form_submitted) {
$form_processed = handle_form_submission($form_field_names, $form_values, $form_errors);
}
if ($form_submitted && $form_processed) {
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ' . $_SERVER['REQUEST_URI']);
} elseif ($form_processed) {
$form_processed = false;
print_html(done_html($form_values));
} else {
print_html(form_html($form_values, $form_errors));
}
exit();
/**
* Output Functions
***************************************************************************/
/**
* @param string $body_html
*/
function print_html($body_html)
{
print <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Form</title>
</head>
<body>
{$body_html}
</body>
</html>
HTML;
}
/**
* @param array $values
* @return string
*/
function done_html(array $values)
{
return <<<HTML
<h1>Thanks!</h2>
HTML;
}
/**
* @param array $values
* @param array $errors
* @return string
*/
function form_html(array $values, array $errors)
{
$classes = array();
foreach ($errors as $name => $value) {
$classes[$name] = is_null($errors[$name]) ? null : 'error';
}
foreach ($values as $name => $value) {
$values[$name] = htmlspecialchars($value);
}
$html = <<<HTML
<form id="%s" method="post">
<div class="{$classes['form']} notice">{$errors['form']}</div>
<fieldset>
<div class="field {$classes['name']}">
<label for="name">Name</label>
<input id="name" name="name" type="text" value="{$values['name']}" required>
<div class="notice">{$errors['name']}</div>
</div>
<div class="field {$classes['email']}">
<label for="email">Email</label>
<input id="email" name="email" type="email" value="{$values['email']}" required/>
<div class="notice">{$errors['email']}</div>
</div>
<div class="field {$classes['phone']}">
<label for="phone">Phone</label>
<input id="phone" name="phone" type="tel" value="{$values['phone']}" required/>
<div class="notice">{$errors['phone']}</div>
</div>
<div class="field {$classes['message']}">
<label for="message">Message</label>
<textarea id="message" name="message" required>{$values['message']}</textarea>
<div class="notice">{$errors['message']}</div>
</div>
</fieldset>
<div class="buttonset">
<button type="submit">Send Message</button>
</div>
</form>
HTML;
return sprintf($html, FORM_ID);
}
/**
* Process Functions
***************************************************************************/
/**
* @param array $names
* @param array $values
* @param array $errors
* @return bool
*/
function handle_form_submission(array &$names, array &$values, array &$errors)
{
$success = false;
$filtered_values = array_fill_keys($names, null);
foreach ($names as $name) {
$function_name = 'validate_' . $name;
if (function_exists($function_name)) {
$filtered_values[$name] = call_user_func_array($function_name, array(&$values[$name], &$errors[$name]));
} else {
trigger_error(sprintf('corresponding validate function not found for field named `%s`', $name));
}
}
$error_count = 0;
foreach ($errors as $error) {
if ($error !== false) {
$error_count++;
}
}
if ($error_count == 0) {
$success = process_form_filtered_values($filtered_values, $errors['form']);
}
return $success;
}
/**
* @param array $values
* @param $error
* @return bool
*/
function process_form_filtered_values(array $values, &$error)
{
$mail_subject = 'Form Message';
$mail_message = $values['message'];
$mail_headers = array(
'X-Mailer: PHP Message Form',
sprintf('From: %s <%s>', $values['name'], $values['email']),
);
$mail_accepted = mail(MAIL_TO, $mail_subject, $mail_message, implode(PHP_EOL, $mail_headers));
if ($mail_accepted === false) {
$error = error_get_last();
}
return $mail_accepted;
}
/**
* Validation Functions
***************************************************************************/
/**
* @param $value
* @param $error
* @return string|false
*/
function validate_name(&$value, &$error)
{
$filtered_value = false;
if (empty($value)) {
$error = 'required';
} else {
$filtered_value = filter_var($value, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
if ($filtered_value !== $value) {
$error = 'invalid';
}
}
return $filtered_value;
}
/**
* @param $value
* @param $error
* @return string|false
*/
function validate_email(&$value, &$error)
{
$filtered_value = false;
if (empty($value)) {
$error = 'required';
} else {
$filtered_value = filter_var($value, FILTER_VALIDATE_EMAIL);
if ($filtered_value === false) {
$error = 'invalid';
}
}
return $filtered_value;
}
/**
* @param $value
* @param $error
* @return string|false
*/
function validate_phone(&$value, &$error)
{
$filtered_value = false;
if (empty($value) === false) {
define('PHONE_REGEX', '/^(?:(?:\+?(1)\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/');
if (preg_match(PHONE_REGEX, $value, $matches)) {
$phone_area_code = ($matches[2]) ? $matches[2] : $matches[3];
$phone_exchange_code = $matches[4];
$phone_local_number = $matches[5];
$filtered_value = sprintf("%s-%s-%s", $phone_area_code, $phone_exchange_code, $phone_local_number);
$value = $filtered_value;
} else {
$error = 'invalid';
}
}
return $filtered_value;
}
/**
* @param $value
* @param $error
* @return string|false
*/
function validate_message(&$value, &$error)
{
$filtered_value = false;
if (empty($value)) {
$error = 'required';
} else {
$filtered_value = $value;
}
return $filtered_value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment