<?php
########################################################
#
# Kontaktformular
#
# Dieses Script erzeugt ein einfaches Mail-Formular für den Anwender und sendet eine E-Mail an die vordefinierte Adresse.
#
# Copyright 2007 MatchWare A/S
# http://www.matchware.com/mediator/
#
# The script requires a PHP-compatible server.
# Most hosting service providers support PHP.
#
# This script presents a simple mail form to the user and sends an e-mail
# to a predefined address. Various options, along with language settings,
# can be customized fully. This script does not use anti-spam measures to
# avoid robots from using it, but most common methods of "form hijacking"
# have been addresed.
#
########################################################
########################################################
#
# The following is the script configuration.
# Edit it as you see fit.
#
########################################################
# This defines the address this mail will be sent to. This MUST be a valid address, or
# the script will abort.
$recipient = "[email protected]";
# If you set this variable to 'false', the user won't be allowed to write
# a subject for the mail (the default subject will be used). If you set it
# to 'true', an input field containing the subject will be shown to the user.
$allowSubject = false;
# This defines the default subject. If the user is allowed to edit it, this will be
# used as the default value of the subject field when the mail form is presented.
# If not, the subject of the mail will always be the content of this variable.
$defaultSubject = "E-Mail von kinski-forever.net";
# Define whether the user has to provide a real e-mail address (true) or not (false).
$requireMail = true;
# Define whether the user has to enter a message. I recommend you keep this turned on.
$requireMessage = true;
# This is where you can define any extra fields you might like to present
# to the user. You can add as many as you want, but keep in mind that none
# of these will be required to send the mail.
# If you don't need any extra fields at all, you can empty the array like so:
# $extraFields = array();
#
$extraFields = array(
#"Telefon",
#"Fax",
#"Wo haben Sie von uns erfahren?",
#"Wo wohnen Sie?",
);
# This string will be used to pad the extra fields when presented in the final mail.
$padString = ".";
# We'll need to define some labels to use in the mail form itself. You can
# change these to fit your needs.
# If you have any experience with HTML you'll know that special characters
# can be represented with tags, like & for "&" - this will be done
# automatically.
$labelName = "Ihr Name";
$labelMail = "Ihre E-Mail Adresse";
$labelSubject = "Betreff dieser Mail";
$labelMessage = "Ihre Nachricht";
$labelRequired = "notwendig";
$labelSendMail = "Mail senden!";
# We should also define some messages to display in case of success or errors.
# Mail:
$msgSendSuccess = "Ihre Mail wurde erfolgreich versandt";
$msgSendFailure = "Während des Mailversands ist ein unbekannter Fehler aufgetreten.";
$msgMailHeader = "Folgendes wurde von Ihrer Website aus gesendet:";
# Errors:
$msgErrorsWereEncountered = "Es sind Fehler aufgetreten";
$msgValidEmailRequired = "Sie müssen eine gültige E-Mail-Adresse eingeben";
$msgValidNameRequired = "Sie müssen einen Namen eingeben";
$msgNeedMessage = "Sie müssen eine Nachricht eingeben";
$msgNoValidNameChars = "Ungültige Zeichen im eingegebenen Namen. Bitte erneut eingeben.";
# To help the layout along a bit we'll define a simple stylesheet. You
# can change this all you want, or remove it completely if you wish.
?>
<style type='text/css'>
/* Errors */
.md9MailerErrors h3
{
margin: 0px 0px 10px 0px;
font-size: 20px;
}
/* The mail form itself */
.md9MailerForm input, .md9MailerForm textarea
{
width: 95%;
border: 2px solid #444;
background-color: #fafafa;
font-size: 13px;
color: #000;
padding: 2px;
}
.md9MailerForm input:focus, .md9MailerForm textarea:focus
{
background-color: #fff;
border-color: #000;
}
</style>
<?php
########################################################
#
# You shouldn't edit below this line
# unless you know what you are doing :o)
#
########################################################
# Any extra fields defined in the $extraFields array will be prepended with an
# identifier when the input fields are displayed. This is that identifier.
$extraFieldPrepend = "exfield_";
$lineBreak = "\r\n";
# This line tells PHP to display all errors, except notices which are basically
# useless anyway. Most servers should be configured to ignore notices by default,
# but it's better to be safe than sorry.
error_reporting(E_ALL ^ E_NOTICE);
#######################################################################################
# #
# We'll need some functions to handle generic data mangling. Let's define them here. #
# #
#######################################################################################
# This function takes a string as input and returns
# only the alphanumerical parts in lowercase. This is
# used to prepare extra fieldnames for use in the form.
function makeSafeField($input)
{
$input = preg_replace("/[^(a-z0-9)]/i","",$input);
$input = strtolower($input);
return $input;
}
# This function takes a string as input and strips it
# of anything that might be considered bad characters
# ... only the most basic chars are allowed to remain.
function makeSafeName($input)
{
$input = preg_replace("/[^([:alnum:][:space:],\.)]/i","",$input);
return trim($input);
}
# This function uses a preg-pattern to determine whether
# any given e-mail address validates according to the
# standards. This pattern was taken from www.php.net,
# courtesy of a mister Elier Delgado.
function isValidEmail($input)
{
$pattern = "/^[a-z]+[a-z0-9]*[\.|\-|_]?[a-z0-9]+@([a-z]+[a-z0-9]*(?(?=[\.|\-])([\.|\-][a-z]+[a-z0-9]*[a-z0-9]+)|[a-z0-9]+)){1,4}\.[a-z]{2,4}$/i";
return preg_match($pattern,$input);
}
# This function will remove any line breaks from whatever is sent
# its way. Many spammers have a nasty habit of using linebreaks to
# inject new headers into an e-mail, effectively redirecting it
# somewhere else. This can be used to send lots of spammail using
# your website as the source - and trust me, you don't want that.
function stripBadStuff($input)
{
$input = str_replace(array("\n","\r"), "", $input);
$input = stripslashes($input);
return $input;
}
#######################################################################################
# #
# Okay - now's the time for the real script to run. #
# #
#######################################################################################
# First, we should check if the e-mail address you filled in actually validates. If not,
# the script will abort at once.
if (!isValidEmail($recipient))
die("<h1>Error!</h1>The variable <b>\$recipient</b> is set to '<i>".$recipient."</i>', which is not a valid e-mail address. You cannot use this
script until you've configured it properly.<br/><br/>The script has aborted execution on line <b>".__LINE__."</b>.");
# Set up an array for any errors we might encounter.
$errors = array();
# If the script was called with a POST-request, we should parse
# the incoming data and do stuff with it.
if ($_SERVER['REQUEST_METHOD'] == "POST")
{
# We'll start by setting a success-variable to true. If any errors are
# encountered while processing the data, the variable will be set to
# false, meaning something has gone wrong.
$OkayToSend = true;
# Remove any nasty hackerstuff from name and e-mail
$sender_name = stripBadStuff($_POST['sendername']);
$sender_mail = stripBadStuff($_POST['sendermail']);
# We should do the same for the subject - provided the user ever had
# a chance to change it.
$subject = ($allowSubject) ? stripBadStuff($_POST['subject']) : $defaultSubject;
# Now we'll check to see if the e-mail address actually validates. If not,
# we need to figure out if we should take action.
if (!isValidEmail($sender_mail))
{
if ($requireMail)
{
# The address was not valid, and that's a bad thing. We'll report the
# error and make sure the mail isn't sent.
$OkayToSend = false;
$errors[] = $msgValidEmailRequired;
}
else
# The address was not valid, but it's not a problem. We'll delete the address
# for now, then fill it in later if the mail is to be sent.
unset($sender_mail);
}
# Let's make sure the user has entered a name at all.
if (!strlen($sender_name))
{
# That's a negative. We'll need to abort here.
$errors[] = $msgValidNameRequired;
$OkayToSend = false;
}
else
{
# There is a name. Let's clean it up some more...
$sender_name = makeSafeName($sender_name);
# ... and make sure there's anything left after that last butchering.
if (!strlen($sender_name))
{
$errors[] = $msgNoValidNameChars;
$OkayToSend = false;
}
}
# The subject should be cleaned up as well.
$subject = makeSafeName($subject);
if (!strlen($subject))
$subject = $defaultSubject;
# Now we should run through the extra fields (if any), making sure the data
# is free of nasty surprises.
#
# First, we set up an array to contain the output we're expecting.
$exFieldOutput = array();
# Then we'll make an integer variable which will contain the lenghts of the
# field 'titles'. This will later be used to pad the output and make it look
# good. We'll set it to the length of the "name" label, then check to see if
# the e-mail label is longer.
$maxFieldLength = strlen($labelName);
if (strlen($labelMail) > $maxFieldLength) $maxFieldLength = strlen($labelMail);
# Then we find out whether there's actually any fields to process.
if (is_array($extraFields) && @count($extraFields))
# Start a loop through the fields you've defined earlier
foreach($extraFields as $key)
{
# Find out what the current field would be called in the POST-array.
$fieldname = makeSafeField($key);
# If the field has content, let's do stuff to it.
if (strlen(trim($_POST[$extraFieldPrepend . $fieldname])))
{
# Remove line breaks - in this case not because they'd compromise security,
# since the extra fields will be inserted as part of the body of the mail,
# but rather because we want the mail to look neat and tidy.
$value = str_replace(array("\n","\r"), " ", $_POST[$extraFieldPrepend . $fieldname]);
$value = trim($value);
$value = stripslashes($value);
# Put the resulting value into our output array.
$exFieldOutput[$key] = $value;
# If this field has a longer name than previously recorded, update
# $maxFieldLength to compensate.
if (strlen($key) > $maxFieldLength)
$maxFieldLength = strlen($key);
}
}
# Prepare the body of the mail
$body = stripslashes(trim($_POST['body']));
# If the message is empty but required to exist, throw a hissy fit.
if (!strlen($body) && $requireMessage)
{
$OkayToSend = false;
$errors[] = $msgNeedMessage;
}
# Now we're done processing - let's see if we're allowed to continue.
if ($OkayToSend)
{
# Seems we're good to go.
# If no e-mail has been set, we'll insert a generic string which will make the
# mail look more proper.
if (!$sender_mail)
{
$removeMailOnComplete = true;
$sender_mail = "no-valid-email-provided";
}
# Set up an "extra body" variable and put a simple divider into it. We're using a secondary
# variable instead of appending to the body text, since the latter will be shown in the
# editor if something goes wrong during post of the mail.
$exbody = "\n\n".str_repeat("-",$maxFieldLength+3)."\n";
# Add mail and name variables, to make sure the data is easily accessible to the reader
$exbody .= str_pad($labelName ." ", $maxFieldLength+2, $padString, STR_PAD_RIGHT) . ": ".$sender_name . "\n";
$exbody .= str_pad($labelMail ." ", $maxFieldLength+2, $padString, STR_PAD_RIGHT) . ": ".$sender_mail . "\n";
# Add the processed extra fields if they exist
if (count($exFieldOutput))
foreach($exFieldOutput as $k=>$v)
$exbody .= str_pad($k ." ", $maxFieldLength+2, $padString, STR_PAD_RIGHT) . ": ".$v . $lineBreak;
# Create another "extra body" variable - this one will be prepended to the content.
# Consider it a header to the content provided by the user.
$prebody = $msgMailHeader."\n".str_repeat("-", strlen($msgMailHeader))."\n\n";
# Set up the basic headers of the e-mail
$headers = "From: \"".$sender_name."\" <".$sender_mail.">\n";
$headers .= "Subject: ".$subject."\n";
$headers .= "X-Mailer: Mail script generated by Matchware Mediator 9\n";
$headers .= "X-Mail-source: http" . ($_SERVER['HTTPS']=="on"?"s":"") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n";
# That's all the processing we need. Yay!
# Send the mail and report status.
print "<div class='md9MailerErrors'>";
if (mail($recipient, $subject, $prebody.$body.$exbody, $headers))
{
# The mail was sent without problems, so we'll report
# a success and reset body + extra fields.
print "<h3>".htmlentities($msgSendSuccess)."</h3>\n";
unset($body);
unset($exFieldOutput);
}
else
# Something bad happened. The most likely cause is that the server has not been
# configured with mail-sending capabilities. More information should be available
# in the server logs.
print "<h3>".htmlentities($msgSendFailure)."</h3>\n";
print "</div>\n\n";
# Unset the sender's mail if he didn't provide a proper one. This is
# to stop "no-valid-email-provided" from showing up in the mail form.
if ($removeMailOnComplete) unset($sender_mail);
}
}
#######################################################################################
# #
# All events below this line are executed every time the script is run - if errors #
# are encountered during POST, they will be displayed along with the mail form. #
# #
#######################################################################################
# Display errors, if any were found.
if (@count($errors))
{
print "<div class='md9MailerErrors'>";
print "<h3>".htmlentities($msgErrorsWereEncountered).":</h3><ul>\n";
foreach($errors as $v)
print "<li>".htmlentities($v)."</li>\n";
print "</ul></div><br/>\n\n\n";
}
# Print the form tag
print "<form class='md9MailerForm' action='".$_SERVER['PHP_SELF']."' method='post'>";
# Print name
print "<label><b>".htmlentities($labelName)." (".htmlentities($labelRequired).")</b><br/><input maxlength='100' type='text' name='sendername'
value=\"{$sender_name}\"/></label>";
print "<br/>\n\n";
# Print mail
print "<label><b>".htmlentities($labelMail).
($requireMail ? " (".htmlentities($labelRequired).")" : ""). # only print "required" if $requireMail is 'true'
":</b><br/><input type='text' name='sendermail' value=\"{$sender_mail}\"/></label>";
print "<br/>\n\n";
# Print subject, if needed
if ($allowSubject)
{
if (!$subject) $subject = $defaultSubject;
print "<label><b>".htmlentities($labelSubject).":</b><br/><input type='text' maxlength='100' name='subject' value=\"{$subject}\"/></label>";
print "<br/>\n\n";
}
# Print extra fields, if available
if (is_array($extraFields) && @count($extraFields))
foreach($extraFields as $f)
{
print "<label><b>".htmlentities($f).":</b><br/>";
$fName = makeSafeField($f);
$fVal = (strlen($exFieldOutput[$f])) ? $exFieldOutput[$f] : "";
print "<input type='text' name='".$extraFieldPrepend.$fName."' value=\"{$fVal}\"/></label>";
print "<br/>\n\n";
}
# Print the body field
print "<label><b>".htmlentities($labelMessage).
($requireMessage ? " (".htmlentities($labelRequired).")" : "").
"</b><br/><textarea rows='4' cols='60' name='body'>$body</textarea>";
print "<br/>\n\n";
# Print the buttons and close the form
print "<button type='submit'>".$labelSendMail."</button>";
print "</form>";
?>