Location: PHPKode > projects > MJGUEST > mjguest/database/xml/driver.php
<?php
	
	/*
	+----------------------------------------------------------------
	|
	|	MJGUEST
	|	=============================================================
	|	Copyright (c) 2002-2008 Giacomo "mdsjack" Menni
	|	Terms of agreement and support at www.mdsjack.bo.it
	|
	+----------------------------------------------------------------
	|	[ DATABASE MODULE ]
	|	Database driver (PHP5 DOM) v.0.8
	+----------------------------------------------------------------
	*/
	
	class db_driver
	{
		protected	$xml;
		protected	$query 		= array();
		
		private		$EDITED		= false;
		
		public		$driver		= 'PHP DOM'; # const
		public		$path;
		public		$tot_queries;
		protected	$db_file	= '';
		
		public		$answer		= '';
		public		$error		= false;
		
		public function __construct($path = '')
		{
			$this->tables = array
			(	'[TBL=entries]'		=> 'entries'
			,	'[TBL=settings]'	=> 'settings'
			);
			
			$this->path = $path;
			$this->open();
		}
		
		public function __destruct()
		{
		#	echo $this->xml->saveXML();#dev
			$this->close();
		}
		
		public function ask($question, $sql = null, $params = array())
		{
			$this->lastquestion = $question;
			
			if ($sql !== null and !empty($params)) array_unshift($params, $sql);
			
			$this->$question($params);
		}
		
		public function get_field($num = 0)# Array mixed
		{
			$this->answer = html_entity_decode($this->query[$num], ENT_QUOTES);
			
			return $this->answer;
		}
		
		public function get_row()# Array DOMElement
		{
			$row = current($this->query);
			
			$this->answer = array();
			
			if (!$row)
				return false;
			
			foreach ($row->childNodes as $field)
			
				$this->answer[$field->nodeName] = html_entity_decode($field->nodeValue, ENT_QUOTES);
			
			next($this->query);
			
			return true;
		}
		
		public function truncate($table) #Funziona solo con Entries
		{
			$this->xml->documentElement->replaceChild($this->xml->getElementsByTagName($this->tables[$table])->item(0)->cloneNode(false), $this->xml->getElementsByTagName($this->tables[$table])->item(0));
			
			$this->EDITED = true;
		}
		
		public function optimize($table)
		{
			return true;
		}
		
		public function row_delete($params) #Funziona solo con Entries, in settings cancellerebbe la "tabella"
		{
			list ($table, $where, $value) = $params;
			
			$rows = $this->xml->getElementsByTagName($where);
			
			foreach ($rows as $row)
				if ($row->nodeValue == $value)
					$this->xml->getElementsByTagName($this->tables[$table])->item(0)->removeChild($row->parentNode);
			
			$this->EDITED = true;
		}
		
		public function row_count($table) #Funziona solo con Entries, in settings conta i parametri come righe!
		{
			$this->query = array();
			
			$this->query[0] = $this->xml->getElementsByTagName($this->tables[$table])->item(0)->childNodes->length;
		}
		
		public function row_add($table) #Funziona solo con Entries, inserisce entry vuota (NON SERVE PIU'?)
		{
			$this->xml->getElementsByTagName($this->tables[$table])->item(0)->appendChild($this->xml->getElementsByTagName('structure')->item(0)->firstChild->cloneNode(true));
			
			$this->EDITED = true;
		}
		
		public function settings_load()
		{
			$this->query[] = $this->xml->getElementsByTagName('settings')->item(0)/*->childNodes*/;
		}
		
		public function settings_update($values)
		{
			$params = $this->xml->getElementsByTagName('settings')->item(0)->childNodes;
			
			for ($i = 0, $tot = count($values); $i < $tot; $i++)
			
				$params->item($i)->hasChildNodes()
				? $params->item($i)->firstChild->replaceData(0, $params->item($i)->firstChild->length, (string)$values[$i])
				: $params->item($i)->appendChild($this->xml->createTextNode($values[$i]))
				;
			
			$this->EDITED = true;
		}
		
		public function settings_restore()
		{
			foreach ($this->xml->getElementsByTagName('settings')->item(0)->childNodes as $param)
				
				$param->hasChildNodes()
				? $param->firstChild->replaceData(0, $param->firstChild->length, $param->getAttribute('default'))
				: $param->appendChild($this->xml->createTextNode($param->getAttribute('default')))
				;
			
			$this->EDITED = true;
		}
		
		public function entry_add($values)
		{
			array_unshift($values, (int) ($this->xml->getElementsByTagName('id')->item(0)->nodeValue + 1) ); # Inserisci ID incrementale all'inizio
			
			// Aggiungiamo come elemento #13 una <reply> vuota, scalando gli altri valori
			$values[15] = $values[14];
			$values[14] = $values[13];
			$values[13] = '';
			
			$newentry = $this->xml->getElementsByTagName('structure')->item(0)->getElementsByTagName('entry')->item(0)->cloneNode(true);
			
			for ($i = 0; $i < $newentry->childNodes->length; $i++)
			
				$newentry->childNodes->item($i)->hasChildNodes()
				?	$newentry->childNodes->item($i)->firstChild->replaceData(0, $newentry->childNodes->item($i)->firstChild->length, $values[$i])
				:	$newentry->childNodes->item($i)->appendChild($this->xml->createTextNode($values[$i]))
				;
				
			$this->xml->getElementsByTagName('entries')->item(0)->insertBefore($newentry, $this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry')->item(0));
			
			$this->EDITED = true;
		}
		
		public function entry_get_set($params)
		{
			$this->query = array();
			
			list($hidden, $offset, $limit, $ip) = $params;
			
#			if (!$this->xml->firstChild->lastChild->hasChildNodes) return false;
			
			$entries = $this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry');
			
			for ($i = $offset; $i < ($offset + $limit); $i++)
			{
				if (count($this->query) < $limit and $entries->item($i))
				{
					if (empty($hidden) or ( ($entries->item($i)->childNodes->item(14)->nodeValue == 1 and $entries->item($i)->childNodes->item(2)->nodeValue == 0) or $entries->item($i)->childNodes->item(1)->nodeValue == $ip) )
						$this->query[] = $entries->item($i);
					
				} else break;
			}
		}
		
		public function entry_get_one($id)
		{
			$entries = $this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry');
			
			foreach ($entries as $entry)
			
				if ($entry->childNodes->item(0)->nodeValue == $id)
				{
					$this->query[] = $entry;
					break;
				}
		}
		
		public function entry_edit($values)
		{
			$edit_fields = array(2,3,4,6,7,8,9,10,11,12,15);
			
			$avatar	= array_shift($values);
			$id		= array_pop($values);
			$rating	= array_pop($values);
			
			$avatar = empty($avatar) ? null : substr($avatar, 10, -1); // Distinguere tra SQL vuota (cancellare) e SQL inesistente (mantenere)
			
			array_push($values, $avatar, $rating);
			
			$entries = $this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry');
			
			foreach ($entries as $entry)
			
				if ($entry->childNodes->item(0)->nodeValue == $id)
				{
					for ($i = 0, $tot = count($values); $i < $tot; $i++)
					{
						if ($edit_fields[$i] == 12 and $avatar === null)
							continue; //saltiamo l'update dell'avatar e teniamo quello salvato
						
						$entry->childNodes->item($edit_fields[$i])->hasChildNodes()
						?	$entry->childNodes->item($edit_fields[$i])->firstChild->replaceData(0, $entry->childNodes->item($edit_fields[$i])->firstChild->length, $values[$i])
						:	$entry->childNodes->item($edit_fields[$i])->appendChild($this->xml->createTextNode($values[$i]))
						;
					}
					break;
				}
			
			$this->EDITED = true;
		}
		
		public function get_avatar($id)
		{
			foreach ($this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry') as $entry)
			
				if ($entry->childNodes->item(0)->nodeValue == $id)
				{
					$this->query = array($entry->childNodes->item(12)->firstChild->data);
					break;
				}
		}
		
		public function check_flood($ip)
		{
			$this->query = array(0);
			
#			if (!$this->xml->firstChild->lastChild->hasChildNodes) return false;
			
			foreach ($this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('entry') as $entry)
			
				if ($entry->childNodes->item(1)->nodeValue == $ip)
				{
					$this->query = array($entry->childNodes->item(5)->nodeValue);
					break;
				}
		}
		
		public function reply_save($params)
		{
			list($reply, $id) = $params;
			
			foreach ($this->xml->getElementsByTagName('id') as $Eid)
			
				if ($Eid->nodeValue == $id)
				{
					$Eid->parentNode->childNodes->item(13)->nodeValue = $reply;
					break;
				}
			
			$this->EDITED = true;
		}
		
		public function approve($id)
		{
			foreach ($this->xml->getElementsByTagName('id') as $Eid)
			
				if ($Eid->nodeValue == $id)
				{
					$Eid->parentNode->childNodes->item(14)->nodeValue = 1;
					break;
				}
			
			$this->EDITED = true;
		}
		
		public function ban_guest($ip_list)
		{
			$this->xml->getElementsByTagName('settings')->item(0)->childNodes->item(21)->nodeValue = $ip_list;
			
			$this->EDITED = true;
		}
		
		public function rating_stats()
		{
			$this->query = array(0);
			
			$ratings = array();
			
			foreach($this->xml->getElementsByTagName('entries')->item(0)->getElementsByTagName('rating') as $rating)
				if ($rating->nodeValue)
					$ratings[] = $rating->nodeValue;
			
			$response = new DOMDocument();
			$response->loadXML('<response><avg>'.array_avg($ratings).'</avg><tot>'.count($ratings).'</tot></response>');
			
			$this->query[0] = $response->getElementsByTagName('response')->item(0);
			
			unset($response);
			
			return true;
		}
		
		public function escape($raw_data)
		{
			return htmlentities($raw_data, ENT_QUOTES);
		}
		
		public function sql($sqlfile)
		{
			include ($sqlfile);
		}
		
		public function free_memory()
		{
			$this->answer = '';
			$this->query = array();
		}
		
		private function open($persistance = 1)
		{
			$this->db_file = $this->path.db_host.db_flag.(!db_name ? 'database' : db_name).'.xml.php';
			
			$this->xml = new DOMDocument();
			$this->xml->xmlVersion			= '1.0';
			$this->xml->encoding			= 'UTF-8';
			$this->xml->xmlStandalone		= true;
			$this->xml->preserveWhiteSpace	= false;
			
			if (file_exists($this->db_file))
				$this->xml->load($this->db_file);
			
			return true;
		}
		
		private function close()
		{
			if($this->xml and $this->EDITED) $this->xml->save($this->db_file);
		}
		
		public function query() #Fake function as a patch to be used when upgrading via SetupUtility
		{
			$this->query[] = $this->xml->getElementsByTagName('adminpass')->item(1)->nodeValue;
		}
	}
?>
Return current item: MJGUEST