<?
/* (c) 2004 carsten.schaedlich@projekt-vier.de */

class field {
    var $description;
    var $name;
    var $value;
    var $match;
    var $mandatory;
    var $conditions;
    var $errormandatory;
    var $errorinvalid;
    
    function field($description)
    {
        $this->description = $description;
        $this->conditions = Array();
        return $this;
    }
    
    function addCondition()
    {
        array_push ($this->conditions, new condition());
    }
}

class form
{
    var $name;
    var $fields;
    var $error;
    var $errorfield;

    function form()
    {
        $this->fields = Array();
        return $this;
    }

    function setfielddescription($name,$description) {
        $i = 0;
        foreach($this->fields as $field) {
            if ($field->name == $name) {
                $field->description = $description;
                $this->fields[$i] = $field;
                break;
            }
            $i++;
        }
    }

    function checkForm($VARS)
    {
        foreach (array_keys($VARS) as $key) {
            $$key = $VARS[$key];
            if (get_cfg_var('magic_quotes_gpc')==1) {
                $$key = unescape($$key);
            }
        }

        $regex['text'] = '.*';
        $regex['email'] = '.+@.+\..+$';

        $fields = $this->fields;

        $i=0;
        foreach($fields as $field) {
            $fieldName = $field->name;

            // first, check mandaroty fields
            if (($$fieldName=="") && $field->mandatory)
            {
                $this->error = $field->errormandatory;
                $this->errorfield = $fieldName;
                return false;
            }

            // then check for wrong characters
            $match = $field->match;
            if ($match) {
                if (preg_match("/^\\/(.*)$/", $match, $matches))
                {
                    $match = $regex[$matches[1]];
                }
                if (! preg_match("/$match/", $$fieldName))
                {
                    $this->error = $field->errorinvalid;
                    $this->errorfield = $fieldName;
                    return false;
                }
            }
            $this->fields[$i]->value = $$fieldName;
            $i++;
        }

        /* Ersetze Platzhalter durch Feldwerte */
        foreach($this->fields as $field) {
            $myFields[$field->name] = $field->value;
            $myFielddescriptions[$field->name] = $field->description;
        }
        $object_vars = get_object_vars($this);
        foreach ($object_vars as $name => $value) {
            if (gettype($value) == 'array') {
                continue;
            } 
            if (preg_match_all ("/(\\$[^$]*?\\$)/m",$value, $matches, PREG_PATTERN_ORDER)) {
                for ($i=0; $i< sizeof($matches[1]); $i++) {
                    $fieldName = substr($matches[1][$i],1,-1);
                    # substitute $<fieldName>$ if fieldName is in fieldlist
                    if ($fieldName && in_array($fieldName, array_keys($myFields))) {
                        $this->$name = str_replace($matches[1][$i], $myFields[$fieldName], $this->$name);
                    }
                }
            }
            if (preg_match_all ("/(\\%[^$]*\\%)/m",$value, $matches, PREG_PATTERN_ORDER))
            {
                for ($i=0; $i< sizeof($matches[1]); $i++) {
                    $fieldName = substr($matches[1][$i],1,-1);
                    if ($fieldName)
                    {
                        $this->$name = str_replace($matches[1][$i], $myFielddescriptions[$fieldName], $this->$name);
                    }
                }
            }

        }
        return true;
    }


    function sendMail()
    {
$DEBUG=false;

        $headers  = "From: " . $this->mailfrom . "\n";
        if (isset($this->cc))
        {
            $headers .= "Cc: " . $this->cc . "\n";
        }
        if (isset($this->bcc))
        {
            $headers .= "Bcc: " . $this->bcc . "\n";
        }
        $headers .= "X-Mailer: PHP\n";
        $headers .= "Mime-Version: 1.0\n";
        $headers .= "Content-Type: text/plain; charset=ISO-8859-15\n";
        $headers .= "Content-Transfer-Encoding: quoted-printable\n";
        $headers .= "Content-Disposition: inline\n";

        $message = qp_enc($this->mailtext);

        if (! $result = mail($this->mailto, $this->subject, $message, $headers))
        {
            echo "Error sending mail: $result<br>";
            echo "Headers: <pre>$headers</pre><br>\n";
            echo "Message: <pre>$message</pre><br>\n";
        }
        else
        {
            if ($DEBUG)
            {
                echo "Mail sent to " . $this->mailto . "<br>\n";
            }
        }
    }

}

class condition
{
    var $fieldname;
    var $match;
    var $content;
}

class xmlparser
{
    var $parser;
    var $form;
    var $context;
    var $curTag;
    var $curVarname;
    var $field;

    /* take inifile, returns form object */
    function xmlparser()
    {
        $this->parser = xml_parser_create('ISO-8859-1');
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, "tag_open", "tag_close");
        xml_set_character_data_handler($this->parser, "cdata");
        $this->context = "start";
    }

    function parse($data)
    {
        xml_parse($this->parser, $data,1);
        return ($this->form);
    }


    function tag_open($parser, $tag, $attributes)
    {
        $this->curTag = $tag;
        switch($this->context)
        {
        case 'start':
            switch($tag)
            {
            case 'FORM':
                $this->oldcontext = $this->context;
                $this->context = "form";
                $this->form = new form();
                break;
            }
            break;
        case 'form':
            switch($tag)
            {
            case 'GENERAL':
                $this->oldcontext = $this->context;
                $this->context = "general";
                break;
            case 'FIELD':
                $this->oldcontext = $this->context;
                $this->context = "field";
                $this->field = new field($attributes['DESCRIPTION']);
                break;
            }
            break;
        case 'field':
            switch($tag)
            {
            case 'CONDITION':
                $this->oldcontext = $this->context;
                $this->context = "condition";
                $this->field->addCondition();
                break;
            case 'MATCH':
                $this->field->mandatory = $attributes['MANDATORY'];
                break;
            }
        }
    }

    function tag_close ($parser, $tag)
    {
        switch ($tag)
        {
        case 'GENERAL':
            $this->context = "form";
            break;
        case 'FIELD':
            $this->context = "form";
            array_push($this->form->fields, $this->field);
            break;
        case 'CONDITION':
            $this->context = "field";
            break;
        case 'FORM':
            $this->context = "start";
            break;
        }
    }

    function cdata ($parser, $cdata)
    {
        $tmpdata = preg_replace("/(^\s*)|(\s*$)/m", "", $cdata);
        if ($tmpdata == '')
        {
            return;
        }
        $data = preg_replace('/\\\\n/', "\n", $cdata);
        switch($this->context)
        {
        case 'general':
            switch($this->curTag)
            {
            case 'FORMNAME':
                $this->form->name = $data;
                break;
            case 'VARNAME':
                $this->curVarname = $data;
                break;
            case 'VALUE':
                $varname = $this->curVarname;
                $this->form->$varname .= $data;
                break;
            }
            break;
        case 'field':
             $varname = strtolower($this->curTag);
             if (!isset( $this->field)) {
                 $this->field = new \stdClass();
             }
             $this->field->$varname = $data;
             break;
        case 'condition':
             $varname = strtolower($this->curTag);
             $i = sizeof($this->field->conditions) -1;
             $this->field->conditions[$i]->$varname = $data;
             break;
        }
    }
}


/* erzeugt aus einer xml-Datei ein Formular */
function createForm($filename)
{
    $myParser = new xmlparser();
    $handle = fopen($filename, "r");
    $content = fread($handle, filesize($filename));
    fclose($handle);
    $myForm = $myParser->parse($content);
    if (! $myForm)
    {
        print xml_error_string(xml_get_error_code($myParser->parser)). "\n";
    }

    return $myForm;
}
