Location: PHPKode > scripts > db2XML > classes/db2xml/db2xml.class.inc
<?php
/**
 * The db2XML class provide an easy way to create XML file
 * from a mysql database.
 * Designed to be very flexible in the way it should create the XML file :
 * Database data is extracted and saved into the object in save points
 * These save points will be loaded and inserted in the XML.
 * See the sample file
 * 
 * @author Fourat ZOUARI <hide@address.com>
 * @version 0.2
 * @license GPL, see LICENSE
 * 
 * TODO:
 * 	Separate the database layer to do only XML works, database stuff should be done from other sources
 * 		That should offer more flexibility and ease the integration of the class
 */
class db2XML {
	/**
     * Provides the base skeleton data for the Output XML data.
     * @var string
     */
	private $xmlSkeleton = null;

	/**
     * Handle used for mysql connection
     * @var handle
     */
	private $dbHandle = null;

	/**
     * Provides the last error message
     * If empty, then no error was thrown
     * @var string
     */
	private $lastErrorMsg = '';

	/**
     * Provides saved data from database
     * This data will be parsed into XML
     * @var array
     */
	private $DBData = array();

	/**
     * Returns the XML data
     * This should be the output member
     *
     * @return string
     */
	public function getXML() {
		return $this->xmlSkeleton->asXML();
	}

	/**
     * Returns saved data for a given $savePoint
     *
     * @return string
     */
	public function getDBData($savePoint) {
		if (isset($this->DBData[$savePoint])) $ret = $this->DBData[$savePoint];
		else $ret = false;

		return $ret;
	}

	/**
     * Set the last error message
     *
     * @return void
     */    
	private function setLastErrorMsg($errorMsg) {
		$this->lastErrorMsg = $errorMsg;
	}

	/**
     * This handler is called on the catch() bloc
     * Should allways return false
     * And it sets the last error message if the $msg is not empty
     *
     * @return void
     */    
	private function exceptionHandler($msg, $code = null) {
		// if the error message was defined
		// so save it
		if (!empty($msg)) {
			$this->setLastErrorMsg($msg);
		}
		// if not, then load previously saved error msg
		else {
			$msg = $this->lastErrorMsg;
		}

		throw new Exception($msg, $code);

		return false;
	}



	/**
     * Gets the content of $fileName
     * Returns false and set the $this->lastErrorMsg if
     * 1.The file was not found
     * 2.The file is not readable
     *
     * @param string $fileName
     * @return string	The file data
     */    
	private function getXMLfromFile($fileName) {
		try {
			if (!file_exists($fileName)) throw new Exception('File '.$fileName.' is not found');
			if (!is_readable($fileName)) throw new Exception('File '.$fileName.' is unreadable');

			$data = file_get_contents($fileName);

			if ($data === false) throw new Exception('Can\'t get contents of this file '.$fileName);

			// return the file data
			$ret = $data;
		}
		catch (Exception $e) {
			$ret = $this->exceptionHandler($e->getMessage());
		}

		return $ret;
	}

	/**
     * Connect to mysql
     * return false on failure, true on success
     * defines the $this->dbHandle on success
     *
     * @param string $hostname
     * @param string $user
     * @param string $password
     * @param string $dbname
     * @param string $persistentDB
     * @return boolean
     */    
	private function mysql_connect($hostname, $user, $password, $dbname, $persistentDB) {
		try {
			// connect to database
			if ($persistentDB) {
				$tmp = @mysql_pconnect($hostname, $user, $password);
			}
			else {
				$tmp = @mysql_connect($hostname, $user, $password);
			}
			if ($tmp == false) throw new Exception('Can\'t connect to database. : '.mysql_error());

			// sets the global db handler
			$this->dbHandle = $tmp;

			// select the database
			$tmp = mysql_select_db($dbname, $this->dbHandle);
			if ($tmp == false) throw new Exception('Can\'t select database. : '.mysql_error());

			$ret = true;
		}
		catch (Exception $e) {
			$ret = $this->exceptionHandler($e->getMessage());
		}

		return $ret;
	}

	/**
     * Executes a query
     * return the resource
     *
     * @param string $query
     * @return resource
     */    
	private function mysql_query($query) {
		try {
			$tmp = mysql_query($query, $this->dbHandle);
			if ($tmp == false) throw new Exception('Can\'t query database. : '.mysql_error());

			$ret = $tmp;
		}
		catch (Exception $e) {
			$ret = $this->exceptionHandler($e->getMessage());
		}

		return $ret;
	}

	/**
     * Fetch results into an array
     *
     * @param resource $res
     * @return array
     */    
	private function mysql_fetch_all($res) {
		$ret = array();

		while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) {
			$ret[] = $row;
		}
		
		// avoid doing $ret[0] when we have only one element in that array
		//if (count($ret) == 1) $ret = $ret[0];

		return $ret;
	}

	/**
     * Build the $XMLSkelData
     * if an error was thrown, return false
     * The class should be intiated under a try .. catch bloc
     *
     * @param string $xmlSkelFile
     * @param string $hostname
     * @param string $user
     * @param string $password
     * @param string $dbname
     * @param string $persistentDB
     * @return boolean
     */    
	public function __construct($xmlSkelFile, $dbHostname, $dbUser, $dbPassword, $dbName, $persistentDB = false) {
		$ret = true;
		
		// get the XMLSkelData
		$XMLSkelData = $this->getXMLfromFile($xmlSkelFile);

		$this->xmlSkeleton = $XMLSkelData;

		// connect to database
		$this->mysql_connect($dbHostname, $dbUser, $dbPassword, $dbName, $persistentDB);

		// instantiate the SimpleXMLElement
		$sxe = new SimpleXMLElement($this->xmlSkeleton);
		if (!$sxe) $ret = $this->exceptionHandler('Can\'t load the xmlSkeleton.');
		
		$this->xmlSkeleton = $sxe;
		
		return $ret;
	}

	/**
     * Destruct the DB handle
     *
     * @return void
     */    
	public function __destruct() {
		if (!is_null($this->dbHandle)) mysql_close($this->dbHandle);
	}

	/**
     * Create a new child named $details['name']
     * It sets its type if $details['attribute'] is given
     * Same thing with value.
     *
     * @param array $details
     * @param string $parent	The parent element
     * @return boolean
     */    
	public function newChild($details, $parentElement='') {
		try {
			// load the XML data
			$sxe = $this->xmlSkeleton;

			// if we have to go to a parent element
			if (!empty($parentElement)) {
				$parent = $sxe->xpath($parentElement);
				if ($parent == false) throw new Exception('Can\'t get the parent. '.$parentElement);
				$sxe = $parent[0];// set it to the root
			}

			// create the child
			if (!isset($details['name'])) throw new Exception('You should define name of the child in the $details.');
			$value = (isset($details['value'])) ? urlencode($details['value']) : null;
			$child = $sxe->addChild($details['name'], $value);

			// set the attributes if given
			if (isset($details['attribute'])) {
				if (!isset($details['attribute']['name'])) throw new Exception('You should define name of the attribute in the $details.');
				if (!isset($details['attribute']['value'])) throw new Exception('You should define value of the attribute in the $details.');

				$child->addAttribute($details['attribute']['name'], $details['attribute']['value']);
			}

			$ret = true;
		}
		catch (Exception $e) {
			$ret = $this->exceptionHandler($e->getMessage());
		}

		return $ret;
	}

	/**
     * Fetch data from DB and save it to a given save point
     * Data is returned and saved to $this->DBData[$dataSavePoint] for later use
     *
     * @param string $dataSavePoint
     * @param string $query
     * @return array
     */    
	public function setDataFromDB($dataSavePoint, $query) {
		// query and fetch results
		$res = $this->mysql_query($query);
		$rows = $this->mysql_fetch_all($res);

		// save the data
		$this->DBData[$dataSavePoint] = $rows;

		// optionally return the fetched data
		return $rows;
	}
}
?>
Return current item: db2XML