<?php
/*************************************************************************/
/* SPAGHETTILEARNING - E-Learning System                                 */
/* ============================================                          */
/*                                                                       */
/* Copyright (c) 2004 by Emanuele Sandri (esandri@tiscali.it)  			 */
/*																		 */
/* This program is free software. You can redistribute it and/or modify  */
/* it under the terms of the GNU General Public License as published by  */
/* the Free Software Foundation; either version 2 of the License.        */
/*************************************************************************/

/**
 * @module Module to handle scorm tracking of lessons
 * 
 * @version $Id: scorm_tracking.php 229 2006-04-10 11:35:05Z ema $
 * @copyright 2004
 */
 
require_once(dirname(__FILE__) . '/config.scorm.php');
require_once(dirname(__FILE__) . '/scorm_utils.php');

$direct_access_params['cmi.core.student_id'] 		= 'student_id';
$direct_access_params['cmi.core.student_name'] 		= 'student_name';
$direct_access_params['cmi.core.lesson_location'] 	= 'lesson_location';
$direct_access_params['cmi.core.credit'] 			= 'credit';
$direct_access_params['cmi.core.lesson_status'] 	= 'lesson_status';
$direct_access_params['cmi.core.entry'] 			= 'entry';
$direct_access_params['cmi.core.score.raw'] 		= 'score_raw';
$direct_access_params['cmi.core.score.max'] 		= 'score_max';
$direct_access_params['cmi.core.score.min'] 		= 'score_min';
$direct_access_params['cmi.core.total_time'] 		= 'total_time';
$direct_access_params['cmi.core.lesson_mode'] 		= 'lesson_mode';
$direct_access_params['cmi.core.exit'] 				= 'exit';
$direct_access_params['cmi.core.session_time'] 		= 'session_time';
$direct_access_params['cmi.suspend_data'] 			= 'suspend_data';
$direct_access_params['cmi.launch_data'] 			= 'launch_data';
$direct_access_params['cmi.comments'] 				= 'comments';
$direct_access_params['cmi.comments_from_lms'] 		= 'comments_from_lms';

$GLOBALS['xpathwritedb'] = array( 	'lesson_location' => '//cmi/core/lesson_location',
					'lesson_status' => '//cmi/core/lesson_status',
					'entry' => '//cmi/core/entry',
					'score_raw' => '//cmi/core/score/raw',
					'score_min' => '//cmi/core/score/min',
					'score_max' => '//cmi/core/score/max',
					'exit' => '//cmi/core/exit',
					'session_time' => '//cmi/core/session_time'
					);

/**
 * Scorm_Tracking
 * 
 * @package SCORM
 * @author Emanuele Sandri
 * @copyright Copyright (c) 2004
 * @version $Id: scorm_tracking.php 229 2006-04-10 11:35:05Z ema $
 * @access public
 **/
class Scorm_Tracking {
	var $idUser;
	var $idReference;
	var $idscrom_item;
	var $idscorm_package;
	var $idtrack;
	var $dbconn;
	var $err_code = 0;
	var $err_text = "";
	var $xmldoc;

	var $tracktable = "scorm_tracking";

	/**
	 * Constructor of the Scorm_Tracking
	 * @param $idUser
	 * @param $idReference
	 * @param $id if $idUser is null => $idscorm_tracking, 
	 * 			  if $id_isitemid is true => $idscorm_item, and $idRefrence is needed
	 * 			  else idsco from manifest
	 * @param $idscorm_package
	 * @param $connection
	 * @param $createonfile
	 */
	function Scorm_Tracking($idUser, $idRefernce, $id, $idscorm_package, $connection, $createonfail = true, $id_isitemid = false)
	{
		$this->idUser = $idUser;
		$this->idReference = $idRefernce;
		$this->idscorm_item = NULL;
		$this->idscorm_package = $idscorm_package;
		$this->dbconn = $connection; 
		$this->xmldoc = null;
		$this->tracktable = $GLOBALS['prefix_lms']."_scorm_tracking";
		
		// Find the idtrack for this peer iditem, iduser
		//$query = "SELECT idscorm_tracking FROM $this->tracktable WHERE idscorm_resource = $this->idscoresource and idUser = $this->iduser";
		if( $idUser === null ) {
			// id is idscorm_tracking
			$query = "SELECT idUser, idscorm_item FROM ".$GLOBALS['prefix_lms']."_scorm_tracking WHERE idscorm_tracking='".(int)$id."'";
			$rs = mysql_query($query, $this->dbconn);
			if ($rs == false || mysql_num_rows($rs) == 0) {
				return false;
			}
			list($this->idUser, $this->idscorm_item) = mysql_fetch_row($rs);
			$this->idtrack = $id;
			return true;
		}
		if( $id_isitemid ) {
			$query = "SELECT tracking.idscorm_item, tracking.idscorm_tracking"
					." FROM ".$GLOBALS['prefix_lms']."_scorm_tracking tracking"
					." WHERE tracking.idscorm_item=".$id
					." AND tracking.idUser=".$idUser;
		} else {
			// FIXME: if not needed => to elminate otherwise to fix completly (base all on item not on resource)
			die( "Code to fix Scorm_Tracking::Scorm_Tracking" );
			$query = "SELECT res.idscorm_item, tracking.idscorm_tracking"
					." FROM ".$GLOBALS['prefix_lms']."_scorm_resources res, ".$GLOBALS['prefix_lms']."_scorm_tracking tracking"
					." WHERE res.idscorm_package = ". $idscorm_package
					." AND res.idsco = '". $id ."'"
					." AND tracking.idUser =". $idUser
					." AND res.idscorm_resource = tracking.idscorm_resource";
		}
		//die($query);
		$rs = mysql_query($query, $this->dbconn);
		if( $rs == false ) {
			$this->setError(1, "Scorm_Tracking::Scorm_Tracking " . mysql_error($this->dbconn) . "[" .$query ."]");
			return false;
		}
		if ( mysql_num_rows($rs) == 0) {
			if ($createonfail) {
				// not found => create new track record
				$query = "INSERT INTO $this->tracktable "
				." (idUser, idReference, idscorm_item)"
				." VALUES"
				." ( $this->idUser, $this->idReference, $id )";
				if (mysql_query($query, $this->dbconn)) {
					if (mysql_affected_rows($this->dbconn) == 1) {
						// get the id of the last insert = idscorm_tracking
						$this->idtrack = mysql_insert_id($this->dbconn);
					} else {
						$this->setError(1, "Scorm_Tracking::Scorm_Tracking " . mysql_error($this->dbconn) . "[" .$query ."]");
						return false;
					} 
				} else {
					$this->setError(1, "Scorm_Tracking::Scorm_Tracking " . mysql_error($this->dbconn) . "[" .$query ."]");
					return false;
				} 
			} else {
				$this->setError(1, "Scorm_Tracking::Scorm_Tracking " . mysql_error($this->dbconn) . "[" .$query ."]");
				return false;
			} 
		} else {
			list($this->idscorm_item, $this->idtrack) = mysql_fetch_array($rs);
			mysql_free_result($rs);
		} 
		return true;
	} 

	function setError($ecode, $etext)
	{
		$this->err_code = $ecode;
		$this->err_text = $etext;
		soap__dbgOut("Scorm_Tracking::setError( $ecode, $etext);" , SOAP_DBG_LEVEL_ERROR, SOAP_DBG_FILTER_SETERROR );
	} 

	function getErrorCode()
	{
		return $this->err_code;
	} 
	function getErrorText()
	{
		return $this->err_text;
	} 

	function getXmlDoc()
	{
		if( $this->xmldoc != null )
			return $this->xmldoc;
			
		$rs = mysql_query("SELECT xmldata FROM $this->tracktable WHERE idscorm_tracking = $this->idtrack", $this->dbconn);
		if ($rs === false) {
			// set error and exit with false
			$this->setError(1, "Scorm_Tracking::getXmlDoc " . mysql_error($this->dbconn));
			return false;
		} 

		$data = mysql_fetch_row($rs);
		if (strlen($data[0]) == 0) {
			$this->xmldoc = new DoceboDOMDocument('1.0');
			$this->precompileXmlDoc();
		} else {
			$this->xmldoc = DoceboDOMDocument::loadXML(stripslashes($data[0]));
		} 
		return $this->xmldoc;
	} 

	function precompileXmlDoc() {
		$root = $this->xmldoc->createElement('trackobj');
		$root = $this->xmldoc->appendChild($root);
		$root->setAttribute('iduser', $this->idUser);
		$root->setAttribute('idresource', $this->idscoresource);
		$this->setParam('cmi.core.student_id', $this->idUser, false, true);
	}
	
	function setXmlDoc(&$xmldoc)
	{
		$this->xmldoc = $xmldoc;
		$query = "UPDATE $this->tracktable SET "
		 . "xmldata = '" . addslashes($xmldoc->saveXML()) . "' "
		 . "WHERE idscorm_tracking = $this->idtrack";
		soap__dbgOut("Scorm_Tracking::setXmlDoc exec query ".$query);
		if (mysql_query($query)) {
			if (mysql_affected_rows($this->dbconn) == 1) {
				return true;
			} else {
				if(	mysql_errno($this->dbconn) != 0 ) {
					$this->setError(1, "Scorm_Tracking::setXmlDoc " . mysql_error($this->dbconn));
					return false;
				} else 
					return true;
			} 
		} else {
			$this->setError(1, "Scorm_Tracking::setXmlDoc " . mysql_error($this->dbconn));
			return false;
		} 
	} 
	
	function getParam($parampath, $SCOAccessibility = true) {
		soap__dbgOut("+Scorm_Tracking::getParam($parampath, $SCOAccessibility)",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
		$aelem = getElementsArrayTrackingTemplate($parampath);
		// if last element is false => signal error
		$last = $aelem[count($aelem)-1];
		//soap__dbgOut(" last[1] = {$last[1]} ");
		if( $last[1] == false ) {
			switch( $last[0] ){
				case '_count':
					$this->setError(203, 'Element not an array. Cannot have count.');
					return false;
				break;
				case '_children':
					$this->setError(202, 'Element cannot have children');
					return false;
				break;
				default:
					$this->setError(201, 'Invalid argument error');
					return false;
				break;
			}
		} else {
			// if it is write only return error
			if( is_object($last[1]) 
			 && $last[1]->getAttribute('SCOAccessibility') == 'writeonly' 
			 && $SCOAccessibility ) {
				$this->setError(404, 'Element is write only');
				return false;
			}
		}
		
		if( is_object($last[1]) ) {
			soap__dbgOut(" Scorm_Tracking::getParam try to get value from direct map in table",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
			// try to get value from direct map in table
			$fieldMap = $last[1]->getAttribute('dbRef');
			if( strlen($fieldMap) > 0 ) {
				soap__dbgOut(" Scorm_Tracking::getParam param direct access in db",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
				// extract value from the db
				$query = "SELECT `$fieldMap` FROM $this->tracktable WHERE idscorm_tracking = $this->idtrack";
				$rs = mysql_query( $query, $this->dbconn);
				if ($rs === false) {
					// set error and exit with false
					$this->setError(1, "Scorm_Tracking::getParam [$query] " . mysql_error($this->dbconn));
					return false;
				} else {
					list($value) = mysql_fetch_array($rs);
					soap__dbgOut( "-Scorm_Tracking::getParam return ".$value,SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM );
					return $value;
				}			
			}
			soap__dbgOut(" Scorm_Tracking::getParam value not fount in table map => go ahead",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
		}
		// navigate troughout elements of xmldoc
		if( $this->xmldoc == null )
			$this->getXmlDoc();
		$elem = $this->xmldoc->documentElement;
		if( $aelem[count($aelem)-1][0] == '_children' ) {
			soap__dbgOut(" Scorm_Tracking::getParam requested _children",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
			// the last token in name of requested param is _children
			$result = array();
			$childs = $aelem[count($aelem)-2][1]->childNodes;
			for( $iChild = 0; $iChild < $childs->length; $iChild++ ) {
				$node = $childs->item($iChild);
				if( $node->nodeType == XML_ELEMENT_NODE )
					$result[] = $node->tagName;
			}
			soap__dbgOut("-Scorm_Tracking::getParam return ".implode(',', $result),SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
			return implode(',', $result);		
		}
		for( $i = 0; $i < count($aelem) && $elem; $i++ ) {
			$infotemplate = $aelem[$i];
			$elemtemplate = $infotemplate[1];
			soap__dbgOut(" Scorm_Tracking::getParam analyze ". $infotemplate[0],SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
			switch( $infotemplate[0] ) {
				case '_count': // not used jet. See default
					soap__dbgOut(" value is _count return it!");
					$childs = $elem->childNodes;
					return $childs->length;
				break;
				case '_children':
					$result = array();
					$childs = $aelem[$i-1][1]->childNodes;
					for( $iChild = 0; $iChild < $childs->length; $iChild++ ) {
						$node =& $childs->item($iChild);
						if( $node->nodeType == XML_ELEMENT_NODE )
							$result[] = $node->tagName;
					}
					return implode(',', $result);
				break;
				default:
					if( $elemtemplate->getAttribute('item') == 'no' 
					 && $elemtemplate->getAttribute('index') == 'yes' ) {
						// we must search for indexed element (index is in $infotemplate[0] 
						soap__dbgOut(" Scorm_Tracking::getParam [1] getelementbynameattrib( " . $elem->tagName .", ". $elemtemplate->tagName .", 'index',". $infotemplate[0] .") ",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
						if( $i < (count($aelem)-1) ) {
							// next element is _count ?
							if( $aelem[$i+1][0] == "_count" ) {
								$elemList = $elem->getElementsByTagname( $elemtemplate->tagName );
								return $elemList->length;
							} 
						}
							
						$elem = getelementbynameattrib($elem, $elemtemplate->tagName, 'index', $infotemplate[0]);
					} else {
						// if element is terminal or nothing is not important now
						soap__dbgOut(" Scorm_Tracking::getParam [2] getelementbynameattrib( " . $elem->tagName .", ". $elemtemplate->tagName .", 'index',". $infotemplate[0] .") ",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM);
						$elem = getelementbynameattrib($elem, $elemtemplate->tagName);
					}
				break;
			}
		}
		// if elem is null return empty string, the value is not initialized
		if( $elem ) {
			$textelem = $elem->firstChild;
			if( !$textelem )
				return $elem->textContent;
			else
				return $textelem->textContent;
		} else {
			if( !is_object($last[1]) ) { // is _count but not all path are been present now
				soap__dbgOut( "-Scorm_Tracking::getParam return 0",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM );
				return "0";
			} 
			soap__dbgOut( "-Scorm_Tracking::getParam return \"\"",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_GETPARAM );
			return "";
		}
		
	}
	
	function setParam($parampath, $paramval, $SCOAccessibility = true, $create = true)
	{
		soap__dbgOut( "+Scorm_Tracking::setParam($parampath, $paramval, $SCOAccessibility, $create)",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_SETPARAM);
		$aelem = getElementsArrayTrackingTemplate($parampath);
		// if last element is false => signal error
		$last = $aelem[count($aelem)-1];
		if( $last[1] == false ) {
			switch( $last[0] ){
				case '_count':
				case '_children':
				case 'version':
					$this->setError(402, 'Invalid set value, element is a keyword');
					return false;
				break;
				default:
					$this->setError(201, 'Invalid argument error');
					return false;
				break;
			}
		} else {
			// if it is read only return error
			if( is_object($last[1]) 
			 && $last[1]->getAttribute('SCOAccessibility') == 'readonly' 
			 && $SCOAccessibility ) {
				$this->setError(403, 'Element is read only');
				return false;
			}
		}

		// try to get value from direct map in table
		$fieldMap = $last[1]->getAttribute('dbRef');
		soap__dbgOut( " Scorm_Tracking::setParam found filedMap = $fieldMap" , SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );

		if( strlen($fieldMap) > 0 ) {
			// set value to the db
			$query = "UPDATE $this->tracktable SET ";
			$dataType = $last[1]->getAttribute('DataType');
			if( $dataType == 'CMIIdentifier' || $dataType == 'CMIVocabulary'
				|| $dataType == 'CMITimespan' || strncmp($dataType, 'CMIString', 9) == 0 ) {
				$query .= "`$fieldMap` = '" . addslashes($paramval) . "' ";
			} else {
				$query .= "`$fieldMap` = " . $paramval . " ";
			}
	 		$query .= "WHERE idscorm_tracking = $this->idtrack";
			
			soap__dbgOut( " Scorm_Tracking::setParam query for update fieldMap = $query", SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_SETPARAM );

			if (mysql_query($query, $this->dbconn)) {
				if (mysql_affected_rows($this->dbconn) == 1) {
					// return true;
					// We must also set the value in xmlData filed!
					soap__dbgOut( " Scorm_Tracking::setParam OK affected row = 1" ,SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_SETPARAM );
				} else {
					// mysql return 0 also when $fieldMap is already $paramval
					soap__dbgOut( " Scorm_Tracking::setParam affected row != 1" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
					if( mysql_errno($this->dbconn) != 0 ) {
						soap__dbgOut( " Scorm_Tracking::setParam report Error" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
						$this->setError(1, "Scorm_Tracking::setParam 1 [ $query ] " . mysql_error($this->dbconn));
						return false;
					}
				} 
			} else {
				soap__dbgOut( " Scorm_Tracking::setParam report Error" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
				$this->setError(1, "Scorm_Tracking::setParam 2 [ $query ] " . mysql_error($this->dbconn));
				return false;
			} 
		}

		
		// navigate troughout elements of xmldoc
		if( $this->xmldoc == null ) 
			$this->getXmlDoc();
		$elem = $this->xmldoc->documentElement;
		for( $i = 0; $i < count($aelem) && $elem; $i++ ) {
			$infotemplate = $aelem[$i];
			switch( $infotemplate[0] ) {
				case '_count':
				case '_children':
					$this->setError(402, 'Invalid set value, element is a keyword' );
					return false;
				break;
				default:
					$elemtemplate = $infotemplate[1];
					if( $elemtemplate->getAttribute('item') == 'no' 
					 && $elemtemplate->getAttribute('index') == 'yes' ) {
						// we must search for indexed element (index is in $infotemplate[0] 
						$newelem = getelementbynameattrib($elem, $elemtemplate->tagName, 'index', $infotemplate[0]);
					} else {
						// if element is terminal or nothing is not important now
						$newelem = getelementbynameattrib($elem, $elemtemplate->tagName);
					}
					if( !$newelem && $create) {
						$newelem = $this->xmldoc->createElement($elemtemplate->tagName);
						if( $elemtemplate->getAttribute('index') == 'yes')
							$newelem->setAttribute('index',$infotemplate[0]);
						if( $elemtemplate->getAttribute('item') == 'yes') 
							$newelem->setAttribute('item', 'yes');
						else
							$newelem->setAttribute('item', 'no');
						$elem->appendChild($newelem);
					} 
					$elem = $newelem;				
				break;
			}
		}
		// now $elem point to the element to set
		$textelem = $elem->firstChild;
		/*if( !$textelem ) {
			soap__dbgOut( " Scorm_Tracking::setParam firstChild of ".$elem->tagName." not found", SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );
			$elem->textContent = $paramval;
			soap__dbgOut( " Scorm_Tracking::setParam put value ".$paramval." on elem->textContent = ".$elem->textContent, SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );
		} else {
			soap__dbgOut( " Scorm_Tracking::setParam firstChild of ".$elem->tagName." found", SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );
			$textelem->textContent = $paramval;
			soap__dbgOut( " Scorm_Tracking::setParam put value ".$paramval." on textelem->textContent = ".$textelem->textContent, SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );
		}*/
		
		while( $elem->firstChild !== NULL  )
			$elem->removeChild($elem->firstChild);
		
		$textelem = $this->xmldoc->createTextNode($paramval);
		$elem->appendChild(	$textelem );	
		
		soap__dbgOut( " Scorm_Tracking::setParam add value ".$elem->firstChild->textContent." to ".$elem->tagName, SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );
		soap__dbgOut( " Scorm_Tracking::setParam dump xmldoc ".$this->xmldoc->saveXML(), SOAP_DBG_LEVEL_LOG, SOAP_DBG_FILTER_SETPARAM );	
		
		$this->setXmlDoc($this->xmldoc);
		soap__dbgOut( "-Scorm_Tracking::setParam return true ",SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_SETPARAM );

		return true;
	} 
	
	function setParamXML( $xmldoc ) {
		$arrFields = array();
		$xpath = new DoceboDOMXPath($xmldoc);
		foreach( $GLOBALS['xpathwritedb'] as $fieldName => $xpathquery ) {
			$xpath_ns = $xpath->query( $xpathquery );
			//$xpath_ns = $xpath_result->nodeset;
			if( $xpath_ns->length > 0 ) {
				$elem = $xpath_ns->item(0);
				$arrFields[$fieldName] = $elem->textContent;
			}
		}
		
		if( count( $arrFields ) > 0 ) {
			$isFirst = TRUE;
			$query = "UPDATE $this->tracktable SET ";
			foreach( $arrFields as $fname => $fvalue ) {
				if( $isFirst ) {
					$query .= "`$fname` = '" . addslashes($fvalue) . "' ";
					$isFirst = FALSE;					
				} else {
					$query .= ", `$fname` = '" . addslashes($fvalue) . "' ";
				}
			}
	 		$query .= "WHERE idscorm_tracking = $this->idtrack";
			//echo "<!-- $query -->\n";
			if (mysql_query($query, $this->dbconn)) {
				if (mysql_affected_rows($this->dbconn) == 1) {
					// return true;
					// We must also set the value in xmlData filed!
					soap__dbgOut( " Scorm_Tracking::setParam OK affected row = 1" ,SOAP_DBG_LEVEL_LOG,SOAP_DBG_FILTER_SETPARAM );
				} else {
					// mysql return 0 also when $fieldMap is already $paramval
					soap__dbgOut( " Scorm_Tracking::setParam affected row != 1" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
					if( mysql_errno($this->dbconn) != 0 ) {
						soap__dbgOut( " Scorm_Tracking::setParam report Error" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
						$this->setError(1, "Scorm_Tracking::setParam 1 [ $query ] " . mysql_error($this->dbconn));
						return false;
					}
				} 
			} else {
				soap__dbgOut( " Scorm_Tracking::setParam report Error" ,SOAP_DBG_LEVEL_ERROR,SOAP_DBG_FILTER_SETPARAM );
				$this->setError(1, "Scorm_Tracking::setParam 2 [ $query ] " . mysql_error($this->dbconn));
				return false;
			}
			 				
		}
		
		$this->setXmlDoc($xmldoc);
		
	}
	
} 

?>
