<?php

#
# Form E-Mail 3.5
#
# Versenden einer E-Mail, die ueber ein Kontaktformular
# geschrieben wurde.
#
# Autor:            Patrick Canterino <patrick@patshaping.de>
# Letzte Aenderung: 09.01.2012
#
# Copyright (C) 2002-2012 Patrick Canterino
#
# Diese Datei kann unter den Bedingungen der "Artistic License 2.0"
# weitergegeben und / oder veraendert werden.
# Siehe:
# http://www.opensource.org/licenses/artistic-license-2.0
#

# ===========
#  Hauptteil
# ===========

$VERSION = '3.5-dev';

require('config.php');
require('functions.php');
require('class.Template.php');

if($_SERVER['REQUEST_METHOD'] != 'POST') show_fatal($err_only_post);

# Wenn Captchas aktiviert sind, Session starten

if($captcha_enable) {
    session_start();

    # Pruefen, ob die zulaessige Zahl der Falscheingaben bei Captchas ueberschritten wurde

    if($captcha_max && isset($_SESSION['captcha_failed']) && $_SESSION['captcha_failed'] >= $captcha_max) {
        show_fatal($err_captcha_max);
    }
}

# Bestimmte Werte in Integers umwandeln

$name_min    = intval($name_min);
$subject_min = intval($subject_min);
$text_min    = intval($text_min);
$name_max    = intval($name_max);
$subject_max = intval($subject_max);
$text_max    = intval($text_max);
$line_break  = intval($line_break);

# Formulardaten auslesen

$email     = formdata('email');
$name      = formdata('name');
$recipient = formdata('recipient');
$subject   = formdata('subject');
$text      = formdata('text');

# Pruefen, ob ueberhaupt was ausgefuellt wurde

if(!$name && !$email && !$text) show_user_error($err_nothing);

# Pruefen, ob alle wichtigen Formular-Felder ausgefuellt wurden

if(!$name)    show_user_error($err_no_name);
if(!$email)   show_user_error($err_no_email);
if(!$text)    show_user_error($err_no_text);

if(!$subject) $subject = $default_subject; # Standard-Betreff

# Pruefen, ob Name, Betreff und Text lang genug sind

if($name_min    && strlen($name)    < $name_min)    show_user_error($err_name_short);
if($subject_min && strlen($subject) < $subject_min) show_user_error($err_subject_short);
if($text_min    && strlen($text)    < $text_min)    show_user_error($err_text_short);

# Pruefen, ob Name, Betreff und Text nicht zu lang sind

if($name_max    && strlen($name)    > $name_max)    show_user_error($err_name_long);
if($subject_max && strlen($subject) > $subject_max) show_user_error($err_subject_long);
if($text_max    && strlen($text)    > $text_max)    show_user_error($err_text_long);

# Pruefen, ob eingegebene E-Mail-Adresse gueltig ist

if(!filter_var($email,FILTER_VALIDATE_EMAIL)) show_user_error($err_invalid_email);

# Individuelle Felder einlesen

$prepared_user_fields = array();

while(list($user_field,$user_field_data) = each($user_fields)) {
    $user_field_content = formdata($user_field);

    # Pruefung, ob es ein Pflichtfeld ist

    if(!$user_field_content) {
        if(isset($user_field_data['required']) && $user_field_data['required']) {
            if(isset($user_field_data['errors']['not_set'])) {
                show_user_error($user_field_data['errors']['not_set']);
            }
            else {
                show_fatal($err_indiv_errmsg_miss,array('ERRMSG' => 'not_set', 'INDIVIDUAL' => $user_field));
            }
        }
        else {
            # Wenn das Feld optional ist und nicht gesetzt wurde, brechen wir hier ab
            # und machen mit dem naechsten Feld weiter

            $prepared_user_fields[$user_field_data['tpl_var']] = '';
            continue;
        }
    }

    # Laengen-Pruefung

    if(isset($user_field_data['min']) && $user_field_data['min']) {
        if(strlen($user_field_content) < $user_field_data['min']) {
            if(isset($user_field_data['errors']['too_short'])) {
                show_user_error($user_field_data['errors']['too_short']);
            }
            else {
                show_fatal($err_indiv_errmsg_miss,array('ERRMSG' => 'too_short', 'INDIVIDUAL' => $user_field));
            }
        }
    }

    if(isset($user_field_data['min']) && $user_field_data['max']) {
        if(strlen($user_field_content) > $user_field_data['max']) {
            if(isset($user_field_data['errors']['too_long'])) {
                show_user_error($user_field_data['errors']['too_long']);
            }
            else {
                show_fatal($err_indiv_errmsg_miss,array('ERRMSG' => 'too_long', 'INDIVIDUAL' => $user_field));
            }
        }
    }

    # Pruefung gegen frei definierbare Pruef-Funktion

    if(isset($user_field_data['check']) && $user_field_data['check'] != '') {
        if(function_exists($user_field_data['check']) && call_user_func($user_field_data['check'],$user_field_content) === false) {
            if(isset($user_field_data['errors']['check_fail'])) {
                show_user_error($user_field_data['errors']['check_fail']);
            }
            else {
                show_fatal($err_indiv_errmsg_miss,array('ERRMSG' => 'check_fail', 'INDIVIDUAL' => $user_field));
            }
        }
    }

    # Pruefung gegen frei definierbaren regulaeren Ausdruck

    if(isset($user_field_data['regex']) && $user_field_data['regex'] != '') {
        if(!preg_match($user_field_data['regex'],$user_field_content)) {
            if(isset($user_field_data['errors']['match_fail'])) {
                show_user_error($user_field_data['errors']['match_fail']);
            }
            else {
                show_fatal($err_indiv_errmsg_miss,array('ERRMSG' => 'match_fail', 'INDIVIDUAL' => $user_field));
            }
        }
    }

    # Formularfeld durch frei definierbare Funktion bearbeiten

    if(isset($user_field_data['prepare']) && $user_field_data['prepare'] != '') {
        if(function_exists($user_field_data['check'])) {
            $user_field_content = call_user_func($user_field_data['prepare'],$user_field_content);
        }
    }

    # Name der Template-Variable ermitteln

    if(isset($user_field_data['tpl_var']) && $user_field_data['tpl_var'] != '') {
        $tpl_var = $user_field_data['tpl_var'];
    }
    else {
        $tpl_var = 'USER_'.$user_field;
    }

    # Fertige Formulardaten wegkopieren und fuer spaeter zur Verfuegung stellen

    $prepared_user_fields[$tpl_var] = $user_field_content;
}

# Captcha ueberpruefen

if($captcha_enable) {
    $captcha_input     = formdata('captcha');
    $captcha_incorrect = false;

    if(isset($_SESSION) && isset($_SESSION['captcha'])) {
        if($captcha_case) {
            if(!$captcha_input || empty($captcha_input) || $captcha_input != $_SESSION['captcha']) $captcha_incorrect = true;
        }
        else {
            if(!$captcha_input || empty($captcha_input) || strtolower($captcha_input) != strtolower($_SESSION['captcha'])) $captcha_incorrect = true;
        }

        if($captcha_incorrect) {
            if($captcha_max) {
                if(isset($_SESSION['captcha_failed']) && $_SESSION['captcha_failed']) {
                    $_SESSION['captcha_failed']++;
                }
                else {
                    $_SESSION['captcha_failed'] = 1;
                }
            }

            if($captcha_max && isset($_SESSION['captcha_failed']) && $_SESSION['captcha_failed'] >= $captcha_max) {
                show_fatal($err_captcha_max);
            }
            else {
                show_user_error($err_captcha_incorrect);
            }
        }
    }
    else {
        show_fatal($err_captcha_session_failure);
    }
}

# Referer ueberpruefen

if($check_referer) {
    $referer_ok = semicolon_split($referer_ok);

    $referer_parts = parse_url($_SERVER['HTTP_REFERER']);
    $referer_host  = $referer_parts['host'];

    if(in_array($referer_host,$referer_ok) === false) show_fatal($err_referer_not_ok);
}

# Zeilenumbrueche in Namen und Betreff durch Leerzeichen ersetzen

$name    = preg_replace("/\015\012|\012|\015/",' ',$name);
$subject = preg_replace("/\015\012|\012|\015/",' ',$subject);

# Uhrzeit formatieren

$timestamp = time();

date_default_timezone_set($timezone);
$time = strftime($timeformat,$timestamp);

# Header der Mail

$header = '';

if($friendly_sender) {
    if($friendly_sender == 2) {
        if(preg_match("/[\200-\377]/",$name)) {
            # Absendernamen mit Base64 codieren

            $encoded_name = base64_encode($name);
            $encoded_name = wordwrap($encoded_name,56,"\015\012",1);
            $encoded_name = "=?$charset?B?$encoded_name?=";
            $encoded_name = str_replace("\015\012","?=\015\012      =?$charset?B?",$encoded_name);
        }
        else {
            # Bestimmte Zeichen im Absendernamen codieren

            $encoded_name = str_replace('"','\"',$name);
            $encoded_name = str_replace('(','\\(',$encoded_name);
            $encoded_name = str_replace(')','\\)',$encoded_name);
            $encoded_name = '"'.$encoded_name.'"';
        }

        $header = "From: $encoded_name <$email>\n";
    }
    else $header = "From: $email\n";
}

if($add_header) {
    if(!$friendly_sender) $header .= "Reply-To: $email\n";
    $header .= 'Content-Type: text/plain; charset="'.$charset.'"'."\n";
    $header .= 'Content-Transfer-Encoding: 8bit'."\n";
    $header .= 'MIME-Version: 1.0'."\n";
    $header .= 'X-Mailer: Form E-Mail '.$VERSION."\n";
    $header .= 'X-Sender-IP: ['.$_SERVER['REMOTE_ADDR'].']';
}
else $header .= "Reply-To: $email";

$header = preg_replace("/\015\012|\012|\015/","\n",$header);

# Betreff mit Base64 codieren, wenn er Zeichen enthaelt,
# die nicht aus dem ASCII-Zeichensatz stammen

if(preg_match("/[\200-\377]/",$subject)) {
    $encoded_subject = base64_encode($subject);
    $encoded_subject = wordwrap($encoded_subject,56,"\015\012",1);
    $encoded_subject = "=?$charset?B?$encoded_subject?=";
    $encoded_subject = str_replace("\015\012","?=\015\012         =?$charset?B?",$encoded_subject);
}
else $encoded_subject = $subject;

# Mailtext formatieren...

$mtpl = new Template;
$mtpl->read_file($tpl_mail);

$mtpl->set_var('EMAIL',  $email);
$mtpl->set_var('NAME',   $name);
$mtpl->set_var('SUBJECT',$subject);
$mtpl->set_var('TIME',   $time);

# ... Umgebungsvariablen einfuegen...

if(isset($allowed_envs) && is_array($allowed_envs)) {
    foreach($allowed_envs as $allowed_env) {
        if(isset($_SERVER[$allowed_env])) {
            $mtpl->set_var('ENV_'.$allowed_env,$_SERVER[$allowed_env]);
        }
        else {
            $mtpl->set_var('ENV_'.$allowed_env,'');
        }
    }
}

# ... eigene Felder einfuegen

while(list($tpl_var,$user_field_content) = each($prepared_user_fields)) {
    $mtpl->set_var($tpl_var,$user_field_content);
}

$mtpl->set_var('TEXT',$text);

$mtpl->parse();

$mailtext = $mtpl->get_template();

if($line_break) $mailtext = wordwrap($mailtext,$line_break);

$mailtext = preg_replace("/\015\012|\012|\015/","\n",$mailtext);

# ... und die Mail abschicken (bei einem Fehler erscheint eine Meldung)

if($recipient && is_array($aliases) && $aliases[$recipient]) {
    # Empfaenger mit Alias-Namen

    $mailto = $aliases[$recipient];
}

$mailto = semicolon_split($mailto);

for($x=0;$x<count($mailto);$x++) {
    mail($mailto[$x],$encoded_subject,$mailtext,$header) or die($err_send_error);
}

# Mails auf Festplatte speichern

if(isset($store_mails) && $store_mails) {
    # Standard-Werte fuer einige Variablen

    if(!isset($store_mails_dir)    || $store_mails_dir    == '') $store_mails_dir = 'stored_mails';
    if(!isset($store_mails_prefix) || $store_mails_prefix == '') $store_mails_prefix = 'feml_';

    # Verzeichnis ggf. anlegen

    if(!is_dir($store_mails_dir))   mkdir($store_mails_dir);

    # Betreff saeubern

    $clean_subject = str_replace(' ','_',$subject);
    $clean_subject = preg_replace('/[^a-z0-9\-_]/i','',$clean_subject);

    # Eindeutigen Dateinamen der Mail zusammensetzen

    $file_name = $store_mails_dir.'/'.uniqid($store_mails_prefix.$email.'_'.$clean_subject.'_'.strftime('%d%m%Y-%H%M%S',$timestamp));

    # Daten in Datei schreiben

    file_put_contents($file_name,$mailtext);

    # Alte Dateien loeschen

    if(isset($store_mails_max) && $store_mails_max > 0) {
        $dp = opendir($store_mails_dir);

        while($stored_mail_file = readdir($dp)) {
            if($stored_mail_file != '.' && $stored_mail_file != '..' && substr($stored_mail_file,0,strlen($store_mails_prefix)) == $store_mails_prefix) {
                $stored_mail_files[$store_mails_dir.'/'.$stored_mail_file] = filemtime($store_mails_dir.'/'.$stored_mail_file);
            }
        }

        closedir($dp);

        arsort($stored_mail_files);

        $x = 0;

        foreach(array_keys($stored_mail_files) as $stored_mail_filename) {
            $x++;

            if($x > $store_mails_max) {
                unlink($stored_mail_filename);
            }
        }
    }
}

if($captcha_enable) session_destroy();

# Mail wurde erfolgreich versendet, also wird die Dankesseite angezeigt

if($return_url) {
    # Per Redirect auf Seite umleiten

    if(strpos($return_url,'://') === false) {
        # URL vervollstaendigen

        $http_host = ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
        $protocol  = '';
        $port      = '';
        $path      = '';

        if(isset($_SERVER['HTTPS'])) {
            # SSL-verschluesseltes HTTP

            $protocol = 'https://';
            if($_SERVER['SERVER_PORT'] != 443) $port = ':'.$_SERVER['SERVER_PORT'];
        }
        else {
            # Normales HTTP

            $protocol = 'http://';
            if($_SERVER['SERVER_PORT'] != 80) $port = ':'.$_SERVER['SERVER_PORT'];
        }

        if(substr($return_url,0,1) == '/') {
            $return_url = $protocol.$http_host.$port.$return_url;
        }
        else {
            if(substr($_SERVER['SCRIPT_NAME'],-1,1) == '/') {
                $path = substr($_SERVER['SCRIPT_NAME'],0,-1);
            }
            else {
                $path = $_SERVER['SCRIPT_NAME'];
            }

            $path = substr($path,0,strrpos($path,'/')+1);
            if(substr($path,0,1) != '/') $path = '/'.$path;

            $return_url = $protocol.$http_host.$port.$path.$return_url;
        }
    }

    header('Status: 303 See Other');
    header('Location: '.$return_url);
}
else {
    # Mit Template formatierte Seite anzeigen

    $stpl = new Template;
    $stpl->read_file($tpl_sent);

    $stpl->set_var('EMAIL',  plain($email));
    $stpl->set_var('MAIL',   plain($mailtext));
    $stpl->set_var('NAME',   plain($name));
    $stpl->set_var('SUBJECT',plain($subject));
    $stpl->set_var('TEXT',   plain($text));
    $stpl->set_var('TIME',   plain($time));

    reset($user_fields);

    while(list($user_field,$user_field_data) = each($user_fields)) {
        if(isset($user_field_data['tpl_var']) && $user_field_data['tpl_var'] != '') {
            $tpl_var = $user_field_data['tpl_var'];
        }
        else {
            $tpl_var = 'USER_'.$user_field;
        }

        $stpl->set_var($tpl_var,htmlspecialchars(formdata($user_field)));
    }

    $stpl->parse();

    print $stpl->get_template();
}

#
### Ende ###

?>