<?php
/*
xmlForm Class: Generate HTML forms from XML config file. HTML is generated using XSL transformations.
Version: 1.0
Copyright (C) 2002 Herman Veluwenkamp
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copy of GNU Lesser General Public License at: http://www.gnu.org/copyleft/lesser.txt
Contact author at: hermanV@subdimension.com
*/
class xmlForm {
/*
Constructor initialising config file location
*/
function xmlForm($conf) {
$this->conf = $conf;
}
/*
Validate $data using rules defined in $conf
*/
function validate($data) {
$this->error = '';
$this->validationError = FALSE; // flag validation error
$this->currentNode = ''; // keep track of current node
$this->newConf = ''; // growing XML output string
$this->var = ''; // keeps track of VAR name we are looking at
$this->type = ''; // keeps track of VAR type we are looking at
$this->regexp = false; // regexp belonging to current VAR
$this->inputData = $data; // input data to be validated against XML config
$xmlParser = xml_parser_create();
xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, false); // preserve case
xml_set_element_handler($xmlParser, array(&$this,"startElement"), array(&$this,"endElement"));
xml_set_character_data_handler($xmlParser, array(&$this,"characterData"));
if (xml_parse($xmlParser, $this->conf)) $this->conf = $this->newConf; // if ok replace with new
else $this->error = sprintf("XML Error: %s at line %d",
xml_error_string(xml_get_error_code($xmlParser)),
xml_get_current_line_number($xmlParser));
xml_parser_free($xmlParser);
return !$this->validationError;
}
/*
Handler when start of element is encountered
*/
function startElement($parser, $name, $attributes) {
$this->currentNode = $name; // keep track of current node
switch($name) {
case 'value': return; break; // ignore VALUE nodes
case 'var': // save var 'NAME' and 'TYPE' attributes
$this->var = $attributes['name'];
$this->type = $attributes['type'];
break;
}
$attributeString = ''; // concatenate attributes;
foreach ($attributes as $key => $value) $attributeString .= $key."=\"".$value."\" ";
$this->newConf .= "<$name $attributeString>";
}
/*
Handler when end of element is encountered
*/
function endElement($parser, $name) {
$this->currentNode = ''; // reset current node
switch($name) {
case 'value': return; break; // ignore VALUE nodes
case 'var': // end of VAR element
if (!$this->isVarValid()) {
$this->newConf .= "<validation-error/>\n";
$this->validationError = TRUE; // flag validation error
}
$data = $this->inputData[$this->var];
if (is_array($data)) $data = '<value>'.@implode("</value>/n<value>", $data).'</value>';
else $data = "<value>$data</value>";
$this->newConf .= $data."\n";
break;
}
$this->newConf .= "</$name>\n";
}
/*
Handler for when character data is encounered
*/
function characterData($parser, $data) {
if ($this->currentNode == '') return; // ignore whitespace
if ($this->currentNode == 'value') return; // ignore VALUE nodes
if ($this->currentNode == 'validation-regexp') $this->regexp = $data; // regular expression for validation
$this->newConf .= $data;
}
/*
Validate current $var
*/
function isVarValid() {
$type = $this->type;
$var = $this->var;
$regexp = $this->regexp;
$data = $this->inputData[$var];
switch ($type) {
case 'text':
$test_value = $data;
break;
case 'textarea':
$test_value = $data;
break;
case 'select':
$test_value = sizeof($data);
break;
case 'multiselect':
$test_value = sizeof($data);
$value = @implode(',', $data);
break;
case 'radio':
$test_value = sizeof($data);
break;
case 'checkbox':
$test_value = sizeof($data);
$value = @implode(',', $data);
break;
default:
$test_value = $data;
}
if (preg_match($regexp, $test_value)) return TRUE;
else return FAlSE;
}
/*
Perform XSL transformation on $conf passing in $parameters
*/
function xslTransform($xsl, $parameters) {
$result = '';
$hasError = FALSE;
$this->error = '';
$this->output = '';
$xh = xslt_create();
$args = array('/_xml' => $this->conf, '/_xsl' => $xsl);
$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $args, $parameters);
if ($result) $this->output = $result;
else {
$this->error = "XML Error: ".xslt_error($xh).". Code is ".xslt_errno($xh);
$hasError = TRUE;
}
xslt_free($xh);
return !$hasError;
}
}
?> |