Location: PHPKode > scripts > XML Forms > xml-forms/class_XMLForms.php
<?php
/*****************************************************************************************
 * XMLForms
 * rev 2010-03-30 by Mark Kintigh
 *
 * CLASS FUNCTIONS
 * ===============
 * clear()
 *    - Resets the class, clearing the loaded file's data.
 *
 * setfilename($xmlname)
 *    - Sets the file name that the class will use for the XML data.
 *
 * getfilename()
 *    - Returns the name of the XML file being used by this class.
 *
 * readdata(<$xmlname>)
 *    - Reads the data from the XML file.  Optionally, you can pass the name of the
 *      XML file through here.  It will return either true or false according to the
 *      success or failure of the read attempt.
 *
 * getformfields($formname <, $split>)
 *    - Returns an array of all of the elements in a given form in the proper format
 *      to print into the HTML document.
 *
 *    - If the optional "split" parameter is TRUE the returned array is an array of
 *      arrays.  The main array contains all of the fields, the subarray contains two
 *      fields, "text" and "field".  The "text" cell contains text that is displayed
 *      for the input field.  The "field" cell contains the actual field's code to
 *      be displayed in the HTML document.
 *
 * XML FILE OPTIONS
 * ================
 *    <?xml version="1.0" encoding="UTF-8"?>
 *    <forms>
 *       <form>
 *          <name>form_name</name>
 *          <field>
 *            <name>field_name</name>
 *            <id>element_id</id>
 *            <text>Displayed text</text>
 *            <value>Default value</value>
 *            <align>left/right/top/middle/bottom</align>
 *            <alt>alternate text for image input</alt>
 *            <checked>1/0</checked>
 *            <disabled>1/0</disabled>
 *            <maxlength>999</maxlength>
 *            <readonly>0/1</readonly>
 *            <size>999</size>
 *            <src>/images/picture.png</src>
 *            <type>button/checkbox/file/hidden/image/password/radio/reset/submit/text/
 *               textarea</type>
 *            <rows>999</rows>
 *            <cols>999</cols>
 *            <accesskey>K</accesskey>
 *            <class>css_name</class>
 *            <dir>rtl/ltr</dir>
 *            <lang>language_code</lang>
 *            <style>style_definitions</style>
 *            <tabindex>999</tabindex>
 *            <title>extra information</title>
 *            <xmllang>language_code</xmllang>
 *            <onblur>script</onblur>
 *            <onchange>script</onchange>
 *            <onclick>script</onclick>
 *            <ondblclick>script</ondblclick>
 *            <onfocus>script</onfocus>
 *            <onmousedown>script</onmousedown>
 *            <onmousemove>script</onmousemove>
 *            <onmouseout>script</onmouseout>
 *            <onmouseover>script</onmouseover>
 *            <onmouseup>script</onmouseup>
 *            <onkeydown>script</onkeydown>
 *            <onkeypress>script</onkeypress>
 *            <onkeyup>script</onkeyup>
 *            <onselect>script</onselect>
 *          </field>
 *       </form>
 *    </forms>
 *
 * <forms>
 * -------
 * Section containing all of the forms within this XML file
 *
 * <form>
 * ------
 * Section containing form data.
 *
 * <name>
 * -------
 * Name of the form.  This is what getfields() uses as the form's identifier for this
 * form.
 *
 * <field>
 * -------
 * As you can see, all of the <INPUT> options are there.  The only required element is
 * "name".  If you do not want it you can omit it or add a blank XML entry, such as
 * "<type/>".
 *
 * *** PLEASE NOTE ***
 * If HTML code is desired as part of a value, you need to replace "<" with "&lt;" and
 * ">" with "&gt;".  The class will put the actual "<" or ">" properly in the returned
 * values.  Using "<" and ">" in the actual XML file will cause issues.
 *
 *****************************************************************************************/
class XMLForms {
	var $filename = "";
	var $forms = array();
	
	function clear() {
		//
		// Clears all of the local variables and data
		//
		$this->filename = "";
		unset($forms);
		$forms = array();
	}

	function setfilename($xmlname) {
		//
		// Set the local variable with the XML file's name
		//
		$this->filename = trim($xmlname . "");
	}
	
	function getfilename() {
		//
		// Returns the file name stored within the class
		//
		return($this->filename);
	}
	
	function readdata($xmlname = "") {
		//
		// Opens the XML file, reads it into memory, and return success/failure
		// ----------
		// Check the optional parameter of a file name
		//
		if(strlen(trim($xmlname))>0) {
			$this->setfilename($xmlname);
		}
		//
		// Make sure the file exists before trying to read it
		//
		if(!file_exists($this->filename)) return false;
		//
		// Try to parse the details into memory
		//
		if($data = simplexml_load_file($this->filename)) {
			foreach($data->form as $form) {
				//
				// Grab the form's name
				//
				$curform = strtolower(trim($form->name));
				//
				// Add the form to the internal array of forms
				//
				if(!isset($this->forms[$curform])) {
					$this->forms[strtolower(trim($curform))] =
						new XMLForm_Form_Details();
				}
				//
				// For each field in the form...
				//
				foreach($form->field as $field) {
					//
					// Add the field to the form's details
					//
					$this->forms[strtolower(trim($curform))]->addField($field);
				}
			}
			//
			// XML was read, so return true
			//
			return true;
		} else {
			//
			// Failed to read the XML, return false
			//
			return false;
		}
	}
	
	function getformfields($formname, $split=0) {
		$ret = array();
		//
		// For each form defined....
		//
		foreach($this->forms as $form=>$cell) {
			//
			// Does this form's name match the form being looked for>
			//
			if(strtolower(trim($formname))==$form) {
				//
				// Yes, process the fields
				//
				foreach($this->forms[$form]->fields as $fieldname=>$details) {
					$field = "";
					if(isset($details['type'])) {
						if(strtolower($details['type'])=="textarea") {
							//
							// If this is <textarea> ...
							//
							$field = $this->makeTEXTAREA($details, $split);
						} else {
							//
							// It is a standard <input> ...
							//
							$field = $this->makeINPUT($details, $split);
						}
					} else {
						//
						// Not set, so assime a standard <input>
						//
						$field = $this->makeINPUT($details, $split);
					}
					//
					// Add the field to the return array IF it is not blank
					//
					if(is_array($field)) {
						$ret[] = $field;
					} elseif(strlen(trim($field))>0) {
						$ret[] = trim($field);
					}
				}
				break;
			}
		}
		return $ret;
	}

	function addCommon($k, $v) {
		//
		// I hate repeating code, so all of the common fields between <input> and
		// <textarea> were added here.
		//
		$ret = "";
		switch($k) {
				case "name":
					if(strlen($v)>0) $ret .= " NAME=\"$v\"";
					break;
				case "id":
					if(strlen($v)>0) $ret .= " ID=\"$v\"";
					break;
				case "disabled":
					if(intaval($v)!=0) $ret .= " DIABLED=\"true\"";
					break;
				case "readonly":
					if(intval($v)!=0) $ret .= " READONLY=\"true\"";
					break;
				case "accesskey":
					if(strlen($v)>0) $ret .= " ACCESSKEY=\"$v\"";
					break;
				case "dir":
					//
					// Verify that the direction is valid before adding it
					// to the options
					//
					$v = strtolower($v);
					if($v == "rtl" || $v = "ltr") {
						$ret .= " DIR=\"$v\"";
					}
					break;
				case "lang":
					if(strlen($v)>0) $ret .= " LANG=\"$v\"";
					break;
				case "style":
					if(strlen($v)>0) $ret .= " STYLE=\"$v \"";
					break;
				case "tabindex":
					if(intval($v)>0) $ret .= " TABINDEX=\"$v\"";
					break;
				case "title":
					if(strlen($v)>0) $ret .= " TITLE=\"$v\"";
					break;
				case "xmllang":
					if(strlen($v)>0) $ret .= " XML:LANG=\"$v\"";
					break;
				case "onblur":
					if(strlen($v)>0) $ret .= " onblur=\"$v\"";
					break;
				case "onchange":
					if(strlen($v)>0) $ret .= " onchange=\"$v\"";
					break;
				case "onclick":
					if(strlen($v)>0) $ret .= " onclick=\"$v\"";
					break;
				case "ondblclick":
					if(strlen($v)>0) $ret .= " ondblclick=\"$v\"";
					break;
				case "onfocus":
					if(strlen($v)>0) $ret .= " onfocus=\"$v\"";
					break;
				case "onmousedown":
					if(strlen($v)>0) $ret .= " onmousedown=\"$v\"";
					break;
				case "onmousemove":
					if(strlen($v)>0) $ret .= " onmousemove=\"$v\"";
					break;
				case "onmouseout":
					if(strlen($v)>0) $ret .= " onmouseout=\"$v\"";
					break;
				case "onmouseover":
					if(strlen($v)>0) $ret .= " onmouseover=\"$v\"";
					break;
				case "onmouseup":
					if(strlen($v)>0) $ret .= " onmouseup=\"$v\"";
					break;
				case "onkeydown":
					if(strlen($v)>0) $ret .= " onkeydown=\"$v\"";
					break;
				case "onkeypress":
					if(strlen($v)>0) $ret .= " onkeypress=\"$v\"";
					break;
				case "onkeyup":
					if(strlen($v)>0) $ret .= " onkeyup=\"$v\"";
					break;
				case "onselect":
					if(strlen($v)>0) $ret .= " onselect=\"$v\"";
					break;
		}
		return $ret;
	}
	
	function makeINPUT($opts, $split) {
		$ret = "";
		foreach($opts as $k=>$v) {
			switch($k) {
				case "value":
					if(strlen($v)>0) $ret .= " VALUE=\"$v\"";
					break;
				case "align":
					//
					// Verify that the alignment is valid before adding it
					// to the options
					//
					if(strlen($v)>0) {
						$v = strtolower($v);
						if($v == "left" || $v == "right" || $v == "top" ||
							$v == "middle" || $v == "bottom") {
							$ret .= " ALIGN=\"$v\"";
						}
					}
					break;
				case "alt":
					if(strlen($v)>0) $ret .= " ALT=\"$v\"";
					break;
				case "checked":
					if(intval($v)!=0) $ret .= " checked=\"checked\"";
					break;
				case "maxlength":
					if(intval($v)>0) $ret .= " MAXLENGTH=\"$v\"";
					break;
				case "size":
					if(intval($v)>0) $ret .= " SIZE=\"$v\"";
					break;
				case "src":
					if(strlen($v)>0) $ret .= " SRC=\"$v\"";
					break;
				case "type":
					//
					// Verify that the type is valid before adding it to the
					// options
					//
					$v = strtolower($v);
					if($v == "button" || $v == "checkbox" || $v == "file" ||
						$v == "hidden" || $v == "image" || $v == "password" ||
						$v == "radio" || $v == "reset" || $v == "submit" ||
						$v == "text") {
						$ret .= " TYPE=\"$v\"";
					}
					break;
				default:
					$ret .= $this->addCommon($k, $v);
					break;
			}
		}
		//
		// OK, check to make sure there were options given and, if so, complete the
		// <input> field
		//
		if(strlen(trim($ret))>0) {
			$ret = "<INPUT$ret />"; 
		}
		//
		// Check to see if there is a prompt included.  If so, add it before the
		// <input> statement
		//
		if(isset($opts['text'])) {
			if($split) {
				$temp = $ret;
				$txt = (strlen(trim($opts['text']))>0) ? trim($opts['text']) : "";
				$ret = array("field"=>$temp, "text"=>$txt);
			} else {
				//
				// Make sure the text is not 0 length
				//
				if(strlen(trim($opts['text']))>0) {
					//
					// Check to see if this is a checkbox or radio box.  If so, put the
					// text to the right of the radio button or check box; otherwise,
					// place the text to the left
					//
					if(isset($opts['type'])) {
						$v = strtolower($opts['type']);
						if($v == "radio" || $v == "checkbox") {
							$ret .= $opts['text'];
						} else {
							$ret = $opts['text'] . " " . $ret;
						}
					} else {
						//
						// The type was not given, so put the text to the left
						//
						$ret = $opts['text'] . " " . $ret;
					}
				}
			}
		}
		return $ret;
	}
	
	function makeTEXTAREA($opts, $split) {
		$ret = "";
		foreach($opts as $k=>$v) {
			switch($k) {
				case "rows":
					if(intval($v)>0) $ret .= " ROWS=\"$v\"";
					break;
				case "cols":
					if(intval($v)>0) $ret .= " COLS=\"$v\"";
					break;
				default:
					$ret .= $this->addCommon($k, $v);
					break;
			}
		}
		//
		// OK, check to make sure there were options given and, if so, complete the
		// <input> field
		//
		if(strlen(trim($ret))>0) {
			$ret = "<TEXTAREA$ret>"; 
			if(isset($opts['value'])) {
				if(strlen(trim($opts['value']))>0) $ret .= trim($opts['value']);
			}
			$ret .= "</TEXTAREA>"; 
		}
		//
		// Check to see if there is a prompt included.  If so, add it before the
		// <input> statement
		//
		if(isset($opts['text'])) {
			//
			// Make sure the text is not 0 length
			//
			if(strlen(trim($opts['text']))>0) {
				$ret = $opts['text'] . " " . $ret;
			}
		}
		return $ret;
	}
}


/*****************************************************************************************
 *
 * XMLForm_Form_Details
 * Subclass for XMLForms
 *
 * This class holds the details for each of the fields of a form.  Each form has one of
 * these classes.  All of the field details are stored, by field name, within the $fields
 * array.  The $fields array is an associtive array using the available sections of the
 * XML file
 *
 ****************************************************************************************/
class XMLForm_Form_Details {

	var $fields = array();
	
	function addField($details) {
		//
		// Copy all of the details into a temporary array
		//
		foreach($details as $k=>$v) {
			$temp[strtolower(trim($k))] = trim($v);
		}
		//
		// Make sure the 'name' field exists
		//
		if(isset($temp['name'])) {
			//
			// It exists, so store the values
			//
			$this->fields[] = $temp;
			$ret = true;
		} else {
			$ret = false;
		}
		//
		// Unset the temporary array
		//
		unset($temp);
		return $ret;
	}

}

?>
Return current item: XML Forms