Location: PHPKode > scripts > Mrasnika's configuration system > mrasnikas-configuration-system/config.inc.php
<?
// --------------------------------------------------------
//
//		XML Configuration Class
//
// --------------------------------------------------------
//
//	Author:	Kaloyan Kirilov Tzvetkov
//
//	Email:	hide@address.com
//		hide@address.com
//		hide@address.com
//
//	Description:
//		This class uses an XML file to build
//		a data structure for keeping
//		different kind of settings. The XML
//		file has different element for
//		various data types, which are
//		validated when read or set.
//
// --------------------------------------------------------





 class mrsnk_Basic {
 // basic class for the application
 //

  var $error;
  // text string contining the last error, occured
  // with the config object

 // function error()
 //	saves the last error in this->error,
 //	and formats it to be passed to trigger_error()
 //
 function error($error) {
	$this->error = $error;
	return "<B><I>CONFIG</I> Class Error</B>: $error";
  	}
 }

 // ----------------------------------------------
 //
 //	ELEMENT DECLARATION
 //
 // ----------------------------------------------
 
 class mrsnk_Settings extends mrsnk_Basic {
 // basic class for all settings
 // used for storing data from:
 //	<alias>,
 //	<password>,
 //	<email>,
 //	<value>,
 //	<string>,
 //	<url>,
 //	<int>,
 //	<boolean>,
 //	<float>,
 //	<date>
 //

 var $description;
 //description of the setting, corresponding
 //to the <description> tag

 var $type;
 //type of the tag

 var $name;
 //original name of the setting 
 
 var $Name;
 //capitalized name of the setting
 
 var $value;
 //value of the setting

 var $default;
 // default value for the setting


 // constructor mrsnk_Setting()
 // parametetrs:
 //	TYPE of the tag - int, string, etc.
 //	ATTRIBUTES of the element
 //	PARENT of the element
 //
// function mrsnk_Settings($_type, $_ATTR) {
 function mrsnk_Settings($_type, $_ATTR) {

 	$ATTR = array();
 	while(list($k, $v) = each($_ATTR)) {
 		$_k = strToUpper($k);

 		switch ($_k) {
 			case 'NAME' :
 				$_name = $v;
 				$ATTR[] = $_k;
 				break;

 			case 'SELECTED' :
 			case 'VALUE' :
 				$_value = $v;
 				$ATTR[] = $_k;
 				break;

 			case 'DEFAULT' :
 				$_default = $v;
 				$ATTR[] = $_k;
 				break;
 			
 			default :
 			// Error - Unrecognized attributes
			trigger_error($this->error(sprintf("Unrecognized attribute [%s] for [%s=%s]",
				$_type, $k, $v)));
				
				break;
 			}
 		}
	
  
 	// type contraints
	$_type = strToUpper($_type);
 	switch ($_type) {
 		case '~' :	//unregonized attributes - there are no
 			//checks made for this type of elements
 			break;


		case 'ALIAS' :
			//username, variables
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name)));
				}

			//check format
			if (!eregi('^[a-z]+[a-z0-9_]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			if (!eregi('^[a-z_]+[a-z0-9_]+$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				}
			
			break;


		case 'PASSWORD' :
			//md5 hash
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!eregi('^[a-f0-9]{32}$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			if (!eregi('^[a-f0-9]{32}$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				}
			break;


		case 'EMAIL' :
			//email address
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'. '@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'. '@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				}
			break;


		case 'VALUE' :
			//options values
			$CHECK = array(
				'NAME',
				'SELECTED',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!eregi('^true|false|on|off|0+|0*1$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-SELECTED [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_value = (eregi('^true|on|0*1$', $_value))?'ON':'OFF';
				}
			if (!eregi('^true|false|on|off|0+|0*1$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				} else {
				$_default = (eregi('^true|on|0*1$', $_default))?'ON':'OFF';
				}
			break;


		case 'STRING' :
			//string attributes
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}
			break;

			
		case 'URL' :
			//URLs
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!preg_match('`^((http|https|ftp)://)(([a-z0-9_]+):([a-z0-9-_]*)@)?(([a-z0-9_-]+\.)*)([a-z0-9-]{3,})\.(com|net|org|edu|gov|mil|int|arpa|aero|biz|coop|info|museum|name|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cf|cd|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|fj|fk|fm|fo|fr|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw)(:(\d+))?((/[a-z0-9-_.%~]*)*)?(\?[^? ]*)?$`iU', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			if (!preg_match('`^((http|https|ftp)://)(([a-z0-9_]+):([a-z0-9-_]*)@)?(([a-z0-9_-]+\.)*)([a-z0-9-]{3,})\.(com|net|org|edu|gov|mil|int|arpa|aero|biz|coop|info|museum|name|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cf|cd|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|fj|fk|fm|fo|fr|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw)(:(\d+))?((/[a-z0-9-_.%~]*)*)?(\?[^? ]*)?$`iU', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				}

			break;


		case 'INT' :
			//inteeger values
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!ereg('^[0-9]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_value = intval($_value);
				}
			if (!ereg('^[0-9]+$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				} else {
				$_default = intval($_default);
				}
			break;


		case 'BOOLEAN' :
			//boolean settings
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!eregi('^true|false|on|off|0+|0*1$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_value = (eregi('^true|on|0*1$', $_value))?'ON':'OFF';
				}
			if (!eregi('^true|false|on|off|0+|0*1$', $_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				} else {
				$_default = (eregi('^true|on|0*1$', $_default))?'ON':'OFF';
				}
			break;


		case 'FLOAT' :
			//float values
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if (!is_float($_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			if (!is_float($_default)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				}
			break;


		case 'DATE' :
			//dates
			$CHECK = array(
				'NAME',
				'VALUE',
				'DEFAULT'
				);
			
			//unrecognized attribute
			if ($CHK = array_diff($ATTR, $CHECK)) {
				trigger_error($this->error(
					sprintf("Unrecognized attributes [%s] for [%s - %s]",
						join(", ", $CHK), $_type, $_name))); 
				}

			//check format
			if ($_value && (strToTime($_value) == -1)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_value = ($_value)?date('Y-M-d H:i:s', strToTime($_value)):NULL;
				}
			if ($_default && (strToTime($_default) == -1)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-DEFAULT [%s]=[%s]",
						$_type, $_name, $_default))); 
				} else {
				$_default = ($_default)?date('Y-M-d H:i:s', strToTime($_default)):NULL;
				}
			break;


 		default :	//some error
			trigger_error($this->error(sprintf("Unrecognized SETTING type [%s]", $_type)));
			return;
			break;
 		}
 	
 	$this->type = $_type;
 	$this->name = $_name;
 	$this->Name = strToUpper($_name);
 	$this->value = $_value;
 	$this->default = $_default;
 	}
 }




 class mrsnk_Root extends mrsnk_Basic {
 // This is the root element of the XML
 // configuration file - "<config>"
 
 var $saveDate;
 // "saveDate" is the date on which the config
 // was was altered for the last time.
 
 var $authorAdmin;
 // "authorAdmin" is the administrator account,
 // that was the last to alter the configuration
 // file. This is either the master-administrator
 // account from <administrationSettings>, or
 // any of the application administrators.
 
 var $authorIP;
 // "authorIP" is the IP address, from which
 // the configuration file was altered for the
 // last time.
 
 var $GROUPS;
 // Repository for the stored groups of settings
 
 // constructor mrsnk_Root()
 // parameters:
 //	ATTRIBUTES - an array with the
 //	attributes of the <config> element
 //
 function mrsnk_Root($_ATTR) {
	$this->GROUPS = array();
 	while(list($k, $v) = each($_ATTR)) {
 		$_k = strToUpper($k);

 		switch ($_k) {
 			case 'SAVEDATE' :
 				$this->saveDate = $v;
 				break;
 			case 'AUTHORADMIN' :
 				$this->authorAdmin = $v;
 				break;
 			case 'AUTHORIP' :
 				$this->authorIP = $v;
 				break;
 			default :
 			// Unrecognized attributes will be added
 			// to GROUPS as settings;
 				$this->GROUPS[] = new mrsnk_Settings(
 					'~',	//type - unregocnized
 					array(
 					'name'=>$k,
 					'value'=>$v,
 					'default'=>NULL
 					));
 				break;
 			}
 		}
  	}
 }





 class mrsnk_Group extends mrsnk_Basic {
 // This is for the groups tags in the configuration
 // file, which are <*Settings> (
 //	<administrationSettings>,
 //	<debugSettings>,
 //	<fileSettings>,
 //	<sessionSettings>,
 //	<phpSettings>,
 //	<applicationSettings>,
 //	<miscellaneousSettings>,
 //	<customSettings>
 //	<databaseSettings>) and
 //	<group>,
 //	<options>,
 //	<session>

 var $type;
 //type of the group - name of the tag

 var $name;
 //name of the group
 
 var $description;
 //description of the group

 var $SETTINGS;
 // Repository for the stored settings
 
 // constructor mrsnk_Group()
 // parametetrs:
 //	TYPE of the tag - int, string, etc.
 //	ATTRIBUTES for the tag
 //
 function mrsnk_Group($_type, $_ATTR) {
	$_Type = strToUpper($_type);
	
	//check type constraints
	switch ($_Type) {
		case 'DEBUGSETTINGS' :
		case 'FILESETTINGS' :
		case 'SESSIONSETTINGS' :
		case 'PHPSETTINGS' :
		case 'APPLICATIONSETTINGS' :
		case 'MISCELLANEOUSSETTINGS' :
		case 'CUSTOMSETTINGS' :
		case 'DATABASESETTINGS' :
		case 'ADMINISTRATIONSETTINGS' :
		// setting groups
			$_name = $_type;
			break;
			

		case 'GROUP' :
		case 'OPTIONS' :
		case 'SESSION' :
		//group elements
 			$ATTR = array();
 			while(list($k, $v) = each($_ATTR)) {
 				$_k = strToUpper($k);
				switch ($_k) {
					case 'NAME' :
						$_name = $v;
						break;
					
					default:	$ATTR[$k] = $v;
						break;
					}
				}
			$_ATTR = $ATTR;
			break;
		}

	//create properties
	$this->type = $_Type;
	$this->name = $_name;
	$this->SETTINGS = array();

	//add attribtes
 	while(list($k, $v) = each($_ATTR)) {
 		$_k = strToUpper($k);

		$this->SETTINGS[] = new mrsnk_Settings(
			'~',	//type - unregocnized
			array(
			'name' => $k,
			'value' => $v,
			'default' => NULL));
 		}
 	}
 }





 class mrsnk_Administrator extends mrsnk_Basic {
 // class for master-administor(s), stored as
 // <administrator> tags in the configuration

 var $name;
 var $Name;
 //configuration name for the super-adminstrator

 var $description;
 //description of the group
 
 var $lastLoginDate;
 //"lastLoginDate" is the date, on which this
 //master-administrator logged in for the last time.
 
 var $lastLoginIP;
 // "lastLoginIP" is the IP address, from which this
 // master-administrator logged in for the last time.

 var $ATTRIBUTES;
 // repository for the attributes of this
 // master-admin. This also can be used to add your
 // custom data to the master-administrator
 // accounts

 // constructor mrsnk_Administrator()
 // parametetrs:
 //	ATTRIBUTES for the administrator
 //
 function mrsnk_Administrator($_ATTR) {

 	while(list($k, $v) = each($_ATTR)) {
 		$_k = strToUpper($k);

 		switch ($_k) {
 			case 'NAME':
 				$this->name = $v;
 				$this->Name = strToUpper($v);
 				break;
 			case 'LASTLOGINDATE' :
 				$this->lastLoginDate = $v;
 				break;
 			case 'LASTLOGINIP' :
 				$this->lastLoginIP = $v;
 				break;
 			default :
 			// Unrecognized attributes will be added
 			// to GROUPS as settings;
 				$this->ATTRIBUTES[] = new mrsnk_Settings(
 					'~',	//type - unregocnized
 					$k,	//name
 					$v,	//value
 					NULL,	//default
 					NULL	//description
 					);
 				break;
 			}
 		}
 	}
 }





 class mrsnk_Directory extends mrsnk_Settings {
 // this class is for the <directory> tags

 var $type = 'DIRECTORY';

 var $permissions;
 // this is the file premissions of that directory (or file,
 // because mrsnk_File class extends this one). This
 // attribute is used when the application is installed,
 // and all the neceseary directories and files are
 // created. 

 // constructor mrsnk_Directory()
 // parametetrs:
 //	ATTRIBUTES for the tag
 //
 function mrsnk_Directory($_ATTR) {

	while(list($k, $v) = each($_ATTR)) {
		$_k = strToUpper($k);

		switch ($_k) {
			case 'NAME' :
				$_name = $v;
				break;

 			case 'VALUE' :
 				$_value = $v;
 				break;

 			case 'DEFAULT' :
 				$_default = $v;
 				break;
 			
 			case 'PERMISSIONS' :
 				$_permissions = $v;
 				break;

 			default :
 			// Error - Unrecognized attributes
				trigger_error($this->error(
					sprintf("Unrecognized attribute for DIRECTORY [%s=%s]",
						$k, $v))); 
				
				break;
			}
		}

	//check format
	if (!eregi("^[^ ?*]+$", $_value)) {
		trigger_error($this->error(sprintf("Wrong format for DIRECTORY-VALUE [%s]",
			$_value))); 
		}
	if (!eregi("^[^ ?*]+$", $_default)) {
		trigger_error($this->error(sprintf("Wrong format for DIRECTORY-DEFAULT [%s]",
			$_default))); 
		}
	
	//check permissions
	if (!ereg('^0?[0-7]{3}$', $_permissions)) {
		trigger_error($this->error(sprintf("Wrong format for DIRECTORY-PERMISSIONS [%s]",
			$_permissions))); 
		}

	//fix directory w/o trailing slash
	$_value .= (!ereg('/$', $_value))?'/':'';
	$_default .= (!ereg('/$', $_default))?'/':'';

	//initialize
 	$this->name = $_name;
 	$this->Name = strToUpper($_name);
 	$this->value = $_value;
 	$this->default = $_default;
 	$this->permissions = $_permissions;
	}
 }





 class mrsnk_File extends mrsnk_Directory {
 // class, coressponding to the <file> tag
 
 var $type = 'FILE';

 // constructor mrsnk_File()
 // parametetrs:
  //	ATTRIBUTES for the tag
 //
 function mrsnk_File($_ATTR) {

	while(list($k, $v) = each($_ATTR)) {
		$_k = strToUpper($k);

		switch ($_k) {
			case 'NAME' :
				$_name = $v;
				break;

 			case 'VALUE' :
 				$_value = $v;
 				break;

 			case 'DEFAULT' :
 				$_default = $v;
 				break;
 			
 			case 'PERMISSIONS' :
 				$_permissions = $v;
 				break;
 			
 			default :
 			// Error - Unrecognized attributes
				trigger_error($this->error(
					sprintf("Unrecognized attribute for FILE [%s=%s]",
						$k, $v))); 
				
				break;
			}
		}

	//check format
	if (!eregi("^[^ ?*]+$", $_value)) {
		trigger_error($this->error(sprintf("Wrong format for FILE-VALUE [%s]",
			$_value))); 
		}
	if (!eregi("^[^ ?*]+$", $_default)) {
		trigger_error($this->error(sprintf("Wrong format for FILE-DEFAULT [%s]",
			$_default))); 
		}
	
	//check permissions
	if (!ereg('^0?[0-7]{3}$', $_permissions)) {
		trigger_error($this->error(sprintf("Wrong format for FILE-PERMISSIONS [%s]",
			$_permissions))); 
		}

	//initialize
 	$this->name = $_name;
 	$this->Name = strToUpper($_name);
 	$this->value = $_value;
 	$this->default = $_default;
 	$this->permissions = $_permissions;
	}
 }




 // ----------------------------------------------
 //
 //	CONFIG CLASS DECLARATION
 //
 // ----------------------------------------------

class Config extends mrsnk_Basic{

 var $path;
 // this is the path to the config.xml

 var $default_path = 'config.xml';
 //default path to the config file

 var $CONFIG;
 // repository for the settings, extracted
 // from config.xml

 var $data;
 // contents of the XML file

 var $STACK;
 // stack for parsing XML file



 // constructor Config()
 // paremeters:
 //	path - where the config.xml is stored. If none,
 //	current folder is searched for 'config.xml' file
 //
 function Config() {

	//check for path
	if ($this->path = @func_get_arg(0)) {
		
		if (!file_exists($this->path)) {
			trigger_error($this->error(sprintf("XML Configuration file [%s] not found",
				$this->path)));
 			return;
 			}
		
		} else {

	//path not present, use default_path	
		unset($this->path);

		if (!file_exists($this->default_path)) {
			trigger_error($this->error(sprintf("XML Configuration file [%s] not found",
				$this->default_path)));
 			return;
 			}

		$this->path = $this->default_path;
		}
	
	//load the config.xml
	$this->load();
 	}





  // function load()
  //	loads the contents of the config.xml
  //
  function load() {

 	if (!file_exists($this->path)) {
 		trigger_error($this->error(sprintf("XML Configuration file [%s] not found ",$this->path)));
 		return;
 		}
 		
	if (!$file = @file($this->path)) {
		trigger_error($this->error(sprintf("XML Configuration file [%s] is empty or can not be read ",
			$this->path)));
		return;
		}
 	
 	$file = join('' , $file);
 	$this->data = $file;
  	
  	$this->parse();
  	}





  // function lastStack()
  //	returns reference to
  //	the last element in STACK
  //
  function &lastStack() {
  	return @$this->STACK[@count($this->STACK)-1];
  	}





  //start-element function
  function _start($_xml, $_name, $_attr) {
	
	$_Name = strToUpper($_name);
	
	switch ($_Name) {
		case 'CONFIG' :
		// The root element for the configuration file.
			$this->CONFIG = new mrsnk_Root($_attr);
			$this->STACK[] = &$this->CONFIG;
			break;
		
		case 'ADMINISTRATIONSETTINGS' :
		case 'DEBUGSETTINGS' :
		case 'FILESETTINGS' :
		case 'SESSIONSETTINGS' :
		case 'PHPSETTINGS' :
		case 'APPLICATIONSETTINGS' :
		case 'MISCELLANEOUSSETTINGS' :
		case 'CUSTOMSETTINGS' :
		case 'DATABASESETTINGS' :
		//settings groups
			
			// find where to add it
			$_last = &$this->lastStack();
			if (get_class($_last) != 'mrsnk_root') {

				//parent element has to be the root element
				trigger_error($this->error(
					sprintf("Parent element is not <config> for element [%s] ",
						$_name)));
				} else {
				$parent = &$_last->GROUPS;
				}
			
			// there can be only element of this type
			if (in_array($_Name, $parent)) {
				
				//duplicate settings-group element
				trigger_error($this->error(
					sprintf("There can be only element of type [%s] ",
						$_name)));
				}

			//add it
			$parent[] = new mrsnk_Group($_name, $_attr);
			$this->STACK[] = &$parent[count($parent)-1];
			
			break;

		case 'GROUP' :
		case 'OPTIONS' :
		case 'SESSION' :
		//special group elements

			// find where to add it
			$_last = &$this->lastStack();

			if (!in_array(get_class($_last), array(
				'mrsnk_administrator',
				'mrsnk_group'
				))) {

				//parent element has to be group element
				trigger_error($this->error(sprintf("Parent element is not a group-type for element [%s] ",
					$_name)));
				} else {
				switch (get_class($_last)) {
					case 'mrsnk_administrator':
						$parent = &$_last->ATTRIBUTES;
						break;
					case 'mrsnk_group':
						$parent = &$_last->SETTINGS;
						break;
					}
				}
			
			//add it
			$parent[] = new mrsnk_Group($_name, $_attr);
			$this->STACK[] = &$parent[count($parent)-1];

			break;

		case 'ADMINISTRATOR' :
		//master-administrator

			// find where to add it
			$_last = &$this->lastStack();
			if ((get_class($_last) != 'mrsnk_group')
				|| ($_last->type != 'ADMINISTRATIONSETTINGS')) {

				//parent element has to be the admin-settings element
				trigger_error($this->error(sprintf("Parent element is not <adminSettings> for element [%s] ",
					$_name)));
				} else {
				$parent = &$_last->SETTINGS;
				}

			//add it
			$parent[] = new mrsnk_Administrator($_attr);
			$this->STACK[] = &$parent[count($parent)-1];


			break;
		
		case 'DESCRIPTION' :
		//element description
			$_last = &$this->lastStack();
			$VARS  = array_keys(get_class_vars(get_class($_last)));

			if (in_array('description', $VARS)) {
				$this->STACK[] = &$_last->description;
				} else {
				trigger_error($this->error(sprintf("Description not allowed in tag [%s] ",
					get_class($_last))));
				}
			break;


		case 'VALUE': 
		//option values

			// find where to add it
			$_last = &$this->lastStack();
				
			if ((get_class($_last) != 'mrsnk_group') ||
				($_last->type != 'OPTIONS')) {

				//parent element has to be OPTIONS element
				trigger_error($this->error(sprintf("Parent element is not OPTIONS  for element [%s] [%s]",
					$_name,
					get_class($_last))));
				} else {
				$parent = &$_last->SETTINGS;
				}

			//add it
			$parent[] = new mrsnk_Settings($_name, $_attr);
			$this->STACK[] = &$parent[count($parent)-1];
			//$this->STACK[] = &$parent[count($parent)-1]->name;
		
			break;

		case 'ALIAS': 
		case 'PASSWORD': 
		case 'EMAIL': 
		case 'STRING': 
		case 'URL': 
		case 'INT': 
		case 'BOOLEAN': 
		case 'FLOAT': 
		case 'DATE' :
		//settings elements
			
			// find where to add it
			$_last = &$this->lastStack();
				
			if (!in_array(get_class($_last), array(
				'mrsnk_administrator',
				'mrsnk_group'
				))) {

				//parent element has to be the group element
				trigger_error($this->error(sprintf("Parent element is not a group-type for element [%s] [%s]",
					$_name,
					get_class($_last))));
				} else {
				switch (get_class($_last)) {
					case 'mrsnk_administrator':
						$parent = &$_last->ATTRIBUTES;
						break;
					case 'mrsnk_group':
						$parent = &$_last->SETTINGS;
						break;
					}
				}

			//add it
			$parent[] = new mrsnk_Settings($_name, $_attr);
			$this->STACK[] = &$parent[count($parent)-1];

			break;

		case 'DIRECTORY' :
		//settings for directories
			
			// find where to add it
			$_last = &$this->lastStack();
				
			if (get_class($_last) != 'mrsnk_group') {

				//parent element has to be the group element
				trigger_error($this->error(sprintf("Parent element is not a group-type for element [%s] [%s]",
					$_name,
					get_class($_last))));
				} else {
				$parent = &$_last->SETTINGS;
				}
			//add it
			$parent[] = new mrsnk_Directory($_attr);
			$this->STACK[] = &$parent[count($parent)-1];
			break;


		case 'FILE' :
		//settings for files
			
			// find where to add it
			$_last = &$this->lastStack();
				
			if (get_class($_last) != 'mrsnk_group') {

				//parent element has to be the group element
				trigger_error($this->error(sprintf("Parent element is not a group-type for element [%s] [%s]",
					$_name,
					get_class($_last))));
				} else {
				$parent = &$_last->SETTINGS;
				}

			//add it
			$parent[] = new mrsnk_File($_attr);
			$this->STACK[] = &$parent[count($parent)-1];
			break;

		
		default :	//there isn't such a tag
			trigger_error($this->error(sprintf("Unrecognized tag [%s] ", $_name)));
			break;
		}
  	}






  //end-element function
  function _end($_xml, $_name) {
  	$this->STACK = array_slice($this->STACK, 0, count($this->STACK)-1);
  	
  	if (empty($this->STACK)) {
  		$this->STACK = NULL;
  		}
  	}





  //CDTATA function
  function _CData($_xml, $cdata) {
  	$_last = &$this->lastStack();

	if ($_class = get_class($_last)) {
		
		switch ($_class) {
			case 'mrsnk_settings' :
				if ($_last->type == 'VALUE'){
					$_last->name .= $cdata;
					$_last->Name = strToUpper($_last->name);
					} else {
					if (trim($cdata)) {
						trigger_error($this->error(sprintf("Data between tags is not supported for [%s]",
						$_class)));
						}
					}
				break;
			
			default :	//error
				if (trim($cdata)) {
					trigger_error($this->error(sprintf("Data between tags is not supported for [%s]",
					$_class)));
					}
				break;
			}
	

		} else {
		$_last .= $cdata;
		}
	}





  // parses the contents of the config.xml
  function parse() {
	
	//create parser
	$_xml = xml_parser_create();
	
                // parser settings
	xml_set_object($_xml, $this);
	xml_parser_set_option($_xml, XML_OPTION_CASE_FOLDING, 0);
	xml_set_element_handler($_xml, "_start", "_end");
	xml_set_character_data_handler($_xml, "_CData");

	if (!xml_parse($_xml, $this->data, TRUE)) {
		trigger_error($this->error(sprintf("XML parse error [%s] at line [%d] ",
			xml_error_string(xml_get_error_code($_xml)),
			xml_get_current_line_number($_xml))));
		}

	//release parser
	xml_parser_free($_xml);
	}

  
  
  

 // returns object from configuration
 // parameters:
 //	PATH is where the setting is located
 //	in the Configuration, visualized using
 //	array with all the elements.
 //
 function &Find($_path){

  	//translate the path
  	$SECTIONS = array();
  	while (list(,$v)=each($_path)) {
  		$SECTIONS[] = array(
  			name=>$v,
  			Name=>trim(strToUpper($v))
  			);
  		}

	// load default data for explore cell
	$explore = &$this->CONFIG->GROUPS;
	reset($explore);
	$level = 0;

	//explore all the elements
	while(list($k, $v) = each($explore)) {
		$start = $level;

		//getelement by class_name
		switch (get_class($v)) {

			case 'mrsnk_administrator' :
				if (@in_array($v->name, $SECTIONS[$start])
					|| @in_array($v->Name, $SECTIONS[$start])) {
						$explore = &$explore[$k]->ATTRIBUTES;
						$level++;
						reset($explore);
						}
				break;

			case 'mrsnk_group' :
				if (($v->type == 'OPTIONS')
					&& (@in_array($v->name, $SECTIONS[$start])
						||@in_array($v->Name, $SECTIONS[$start])
					)) {

					//there are no more elements left.
					//this means that the element we
					//searched for is found, and it is
					//an OPTIONS element
					if (++$start == count($SECTIONS)) {
						return $explore[$k]->SETTINGS;
						} else {
						
						//this is not the last element,
						//which means that the path
						//is invalid, or there's a reference
						//to an exact element of the options
						$explore = &$explore[$k]->SETTINGS;
						$level++;
						reset($explore);
						}
				
					} else {
					
					//other than OPTIONS
					if (@in_array($v->name, $SECTIONS[$start])
						|| @in_array($v->type, $SECTIONS[$start])) {
							$explore = &$explore[$k]->SETTINGS;
							$level++;
							reset($explore);
							}
					}
				break;

			case 'mrsnk_directory' :
			case 'mrsnk_file' :
			case 'mrsnk_settings' :

				if (@in_array(trim($v->name), $SECTIONS[$start])
					|| @in_array(trim($v->Name), $SECTIONS[$start])) {

						//there are no more elements left.
						//this means that the element we
						//searched for is found
						if (++$start == count($SECTIONS)) {
							return $explore[$k];
							
							} else {
							
							//this is not the last element,
							//which means that the path
							//is invalid
							trigger_error($this->error(sprintf("Configuration element
								path [%s] is invalid",
								join(".", $_path))));
							}
						}
				break;

			default :	//error
				trigger_error($this->error(sprintf("Unknown class [%s]", get_class($v))));
				return;
				break;
			}

		//make another loop
		if ($level > $start) {
			continue;
			}
		}

	//element isn't found
	trigger_error($this->error(sprintf("Configuration element [%s] not found", join(".", $_path))));
  	}

 // returns object from configuration
 // parameters:
 //	PATH is where the setting is located
 //	in the Configuration, visualized using
 //	array with all the elements.
 //
 function Get(){

	$_path = array();
	for ($i=0; $i<func_num_args(); $i++) {
 		$_path[] = func_get_arg($i);
 		}
	$_rslt = $this->Find($_path);

	switch (gettype($_rslt)) {
		case 'array' :
			$_RSLT = array();
			reset($_rslt);
			while(list($k, $v) = each($_rslt)) {
				$_RSLT[trim($v->name)]=$v->value;
				}
			return $_RSLT;
			break;
		default :
			return $_rslt->value;
			break;
		}
	}





 // sets value for an object from configuration
 // parameters:
 //	VALUE is the value to be set
 //	PATH is where the setting is located
 //	in the Configuration, visualized using
 //	array with all the elements.
 //
 function Set(){

	// first parameter is the value
	$_value = func_get_arg(0);
	
	//the rest are for the path
	$_path = array();
	for ($i=1; $i<func_num_args(); $i++) {
 		$_path[] = func_get_arg($i);
 		}
	
	// element isn't found
	if (!$_rslt = &$this->Find($_path)) {
		return FALSE;
		}
	$_type = $_rslt->type;
	$_name = join("." , $_path);

	switch ($_type) {
		case 'ALIAS':
			if (!eregi('^[a-z]+[a-z0-9_]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			$_rslt->value = $_value;
			break;

		case 'PASSWORD':
			if (!eregi('^[a-f0-9]{32}$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			$_rslt->value = $_value;
			break;

		case 'EMAIL' :
			if ($_value && !ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'. '@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			$_rslt->value = $_value;
			break;
		
		case 'VALUE' :
			if (!eregi('^true|false|on|off|0+|0*1$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-SELECTED [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_rslt->value = (eregi('^true|on|0*1$', $_value))?'ON':'OFF';
				}
			break;

		case 'URL' :
			if ($_value && !preg_match('`^((http|https|ftp)://)(([a-z0-9_]+):([a-z0-9-_]*)@)?(([a-z0-9_-]+\.)*)([a-z0-9-]{3,})\.(com|net|org|edu|gov|mil|int|arpa|aero|biz|coop|info|museum|name|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cf|cd|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|fj|fk|fm|fo|fr|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw)(:(\d+))?((/[a-z0-9-_.%~]*)*)?(\?[^? ]*)?$`iU', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			$_rslt->value = $_value;
			break;


		case 'INT' :
			if (!ereg('^[0-9]+$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_rslt->value = intval($_value);
				}
			break;

		case 'BOOLEAN' :
			if (!eregi('^true|false|on|off|0+|0*1$', $_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_rslt->value = (eregi('^true|on|0*1$', $_value))?'ON':'OFF';
				}
			break;

		case 'FLOAT' :
			if (!is_float($_value)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				}
			$_rslt->value = $_value;
			break;

		case 'DATE' :
			if ($_value && (strToTime($_value) == -1)) {
				trigger_error($this->error(
					sprintf("Invalid data format for attribute %s-VALUE [%s]=[%s]",
						$_type, $_name, $_value))); 
				} else {
				$_rslt->value = ($_value)?date('Y-M-d H:i:s', strToTime($_value)):NULL;
				}
			break;

		case 'STRING' :
		default :
			if (ereg('["<>]', $_value)) {
				$_rslt->value = htmlSpecialChars($_value);
				} else {
				$_rslt->value = $_value;
				}

			break;
		}
	
	return TRUE;
	}

 // returns object with all its details
 //	and attributes from
 //	configuration
 //
 // parameters:
 //	PATH is where the setting is located
 //	in the Configuration, visualized using
 //	array with all the elements.
 //
 function Details(){

	$_path = array();
	for ($i=0; $i<func_num_args(); $i++) {
 		$_path[] = func_get_arg($i);
 		}
	return $this->Find($_path);
	}

 //saves the configration structure to the
 //	configuration XML file, appling
 //	the differences.
 //
 // parameters:
 //	ACCOUNT is the alias for the
 //	user, or administration account,
 //	that saves the new configuration
 //
 function Save($_account){
	
	// save the author
	$this->CONFIG->authorAdmin = $_account;
	
	// check for the original XML file and
	// then create a backup copy with
	// the old configurtions
	
	$_original = $this->path."~ORIGINAL";
	$_backup = $this->path."~BACKUP".date("-Ymd_His");
	
	if (file_exists($_original)) {
		
		// make a backup copy
		if ($fp = fopen($_backup, 'w')) {
			fwrite($fp, $this->data);
			fclose($fp);
			}
		} else {

		// create the original
		if ($fp = fopen($_original, 'w')) {
			fwrite($fp, $this->data);
			fclose($fp);
			}
		}

	// write the new settings 
	$_write = "<?xml version=\"1.0\"?>\n";
	
	// recursively searches through the
	// object, and returns its contents
	//
	function _write(&$__p, $__t=0) {
	
		// indent
		$__i = str_repeat("\t", $__t++);
		
		//description
		if ($__p->description) {
			$__p->description = wordwrap(
				ereg_replace("[[:space:]]+", ' ', $__p->description),
				30 + (4 - $__t)*3,
				"\n$__i\t\t");
			}

		switch (get_class($__p)) {
			case 'mrsnk_root' :
				for ($i=0; $i<count($__p->GROUPS); $i++) {
					$__r .= _write(&$__p->GROUPS[$i], $__t);
					}
				
				//get the remote IP
				if (!$_ip = $_SERVER[REMOTE_ADDR]) {
					global $HTTP_SERVER_VARS;
					$_ip = $HTTP_SERVER_VARS[REMOTE_ADDR];
					}
				
				return "<config"
					.sprintf(" saveDate=\"%s\"",
						date("Y-m-d H:i:s"))
					.sprintf("\n\t authorAdmin=\"%s\"",
						htmlSpecialChars($__p->authorAdmin))
					.sprintf("\n\t authorIP=\"%s\"",
						$_ip)
					.">"
					.$__r
					."</config>";
				break;
			
			case 'mrsnk_group':
				for ($i=0; $i<count($__p->SETTINGS); $i++) {
					$__r .= _write(&$__p->SETTINGS[$i], $__t);
					}

				switch ($__p->type) {
					case 'SESSION' :
						return "\n$__i<session"
							.sprintf(" name=\"%s\"",
								$__p->name)
							.">"
							.((!$__p->description)?"\n" :
								"\n$__i\t<description>"
								.sprintf("%s</description>\n\t",
									htmlSpecialChars(
									$__p->description)))
							.$__r
							."\n$__i</session>\n";
						break;
					
					case 'OPTIONS' :
						return "\n$__i<options"
							.sprintf(" name=\"%s\"",
								$__p->name)
							.">"
							.((!$__p->description)?"\n" :
								"\n$__i\t<description>"
								.sprintf("%s</description>\n",
									htmlSpecialChars(
									$__p->description)))
							.$__r
							."\n$__i</options>\n";
						break;

					case 'GROUP' :
						return "\n$__i<group"
							.sprintf(" name=\"%s\"",
								$__p->name)
							.">"
							.((!$__p->description)?"\n" :
								"\n$__i\t<description>"
								.sprintf("%s</description>\n",
									htmlSpecialChars(
									$__p->description)))
							.$__r
							."\n$__i</group>";
						break;

					case 'ADMINISTRATIONSETTINGS':
					case 'APPLICATIONSETTINGS':
					case 'PHPSETTINGS':
					case 'SESSIONSETTINGS':
					case 'FILESETTINGS':
					case 'DEBUGSETTINGS':
					case 'MISCELLANEOUSSETTINGS':
					case 'CUSTOMSETTINGS':
					case 'DATABASESETTINGS':
						return "\n$__i<$__p->name>"
							.((!$__p->description)?"\n" :
								"\n$__i\t<description>"
								.sprintf("%s</description>\n\t",
									htmlSpecialChars(
									$__p->description)))
							.$__r
							."\n$__i</$__p->name>\n";
						break;
					}
				break;
			
			case 'mrsnk_administrator':
				for ($i=0; $i<count($__p->ATTRIBUTES); $i++) {
					$__r .= _write(&$__p->ATTRIBUTES[$i], $__t);
					}
				
				return "\n$__i<administrator"
					.sprintf("\n$__i\tname=\"%s\"",
						$__p->name)
					.sprintf("\n$__i\tlastLoginDate=\"%s\"",
						$__p->lastLoginDate)
					.sprintf("\n$__i\tlastLoginIP=\"%s\"",
						$__p->lastLoginIP)
					.">"
					.((!$__p->description)?'' :
						"\n$__i\t<description>"
						.sprintf("%s</description>\n",
							htmlSpecialChars(
							$__p->description)))
					.$__r
					."\n$__i</administrator>\n";
				;
				break;
			
			case 'mrsnk_settings' :
				switch ($__p->type) {
					case 'ALIAS' :
					case 'PASSWORD':
					case 'EMAIL':
					case 'STRING':
					case 'URL':
					case 'BOOLEAN':
					case 'INT':
					case 'FLOAT':
					case 'DATE':
						return "\n$__i<"
							.strToLower($__p->type)
							.sprintf(" name=\"%s\"",
								$__p->name)
							.sprintf("\n$__i\tvalue=\"%s\"",
								$__p->value)
							.sprintf("\n$__i\tdefault=\"%s\"",
								$__p->default)
							.">"
							.((!$__p->description)?'' :
								"\n$__i\t<description>"
								.sprintf("%s</description>",
									htmlSpecialChars(
									$__p->description)))
							."\n$__i</"
							.strToLower($__p->type)
							.">\n";
						break;

					case 'VALUE':
						return "\n$__i<value"
							.sprintf(" selected=\"%s\"",
								$__p->value)
							.sprintf(" default=\"%s\"",
								$__p->default)
							.">"
							.((!$__p->description)?'' :
								"\n$__i\t<description>"
								.sprintf("%s</description>",
									htmlSpecialChars(
									$__p->description)))
							."\n$__i\t"
							.trim($__p->name)
							."</value>\n";
						break;
					}
				break;

			case 'mrsnk_file' :
			case 'mrsnk_directory' :
				return "\n$__i<"
					.strToLower($__p->type)
					.sprintf(" name=\"%s\"",
						$__p->name)
					.sprintf("\n$__i\tvalue=\"%s\"",
						$__p->value)
					.sprintf("\n$__i\tdefault=\"%s\"",
						$__p->default)
					.sprintf("\n$__i\tpermissions=\"%s\"",
						$__p->permissions)
					.">"
					.((!$__p->description)?'' :
						"\n$__i\t<description>"
						.sprintf("%s</description>",
							htmlSpecialChars(
							$__p->description)))
					."\n$__i</"
					.strToLower($__p->type)
					.">\n";

				break;
			}
		}
	
	$_write .= _write(&$this->CONFIG);
	$_write = str_replace("\n", "\r\n", $_write);
	
	if ($fp = fopen($this->path, 'w')) {
		fwrite($fp, $_write);
		fclose($fp);
		}
	}
 }
?>
Return current item: Mrasnika's configuration system