<?php
 /**
 * DISCLAIMER : That's poor php, quick and very dirty ... blame me if you want, but then do better !
 * Regards, Caeies.
 */

if ( ! $argv[1] ) {
	printf("Please specify the file !\n");
	exit;
}

/* The header that we put into each file (btw, that the header for this file too !!)*/
$header = "\t/**\n".
	"\t* This file is generated automaticaly from the nusoap library for\n".
	"\t* phpGroupWare, using the nusoap2phpgwapi.php script written for this purpose by \n".
	"\t* Caeies (caeies@phpgroupware.org)\n".
	"\t* @copyright Portions Copyright (C) 2003,2006 Free Software Foundation, Inc. http://www.fsf.org/\n".
	"\t* @package phpgwapi\n".
	"\t* @subpackage communication\n".
	"\t* Please see original header after this one and class.nusoap_base.inc.php\n".
	"\t* @version \$Id: nusoap2phpgwapi 17828 2006-12-28 18:02:30Z Caeies $\n".
	"\t*/\n\n";

print "Processing ".$argv[1]."\n";

/* split the tags in the file 
 * I know his is possible with a php preg_replace or something like that
 * But I don't have any documentation here about this function
 */
/* system("sed -e 's/?><?php/?>\\n<?php/g' -e 's/class soapval/class new_soapval/g' -e 's/function soapval/function new_soapval/g' $argv[1] > ./$argv[1].tmp"); */
$f = file_get_contents($argv[1]);
$f = preg_replace('/\?><\?php/', "?>\n<?php", $f);
$fd = fopen("./$argv[1].tmp","w+");
fwrite($fd,$f);
fclose($fd);

$g = file($argv[0]);
$l = '';
$l1 = '';
$b = False;
$fd;
foreach( $g as $line ) {
	if ( ! $b ) {
		$l1 = $l;
		$l = $line;
	} else {
		fwrite($fd,$line);
	}
	if ( ereg(strtoupper('soap_client'),$line) ) {
		$b = True;
		$fd = fopen("./$argv[1].tmp","a+");
		fwrite($fd,$l1);
	}
}
fclose($fd);
system("sync");
$f =  file($argv[1].".tmp");
unlink($argv[1].".tmp");
$i = 0;
$j = 3;
$a = array();
$current_class ='_not_me_';
foreach( $f as $line ) {
	/* Change the XMLSchema to soap_XMLSchema to avoid collisions */
	$line = ereg_replace('XMLSchema |xmlschema ','soap_XMLSchema ',$line);
//	$line = ereg_replace('xmlschema[^[:alpha:]]','soap_XMLSchema',$line);
	$line = ereg_replace('XMLSchema\(|xmlschema\(','soap_XMLSchema(',$line);
	if ( ereg('^class',$line) ) {
		$tmp = explode(' ',$line);
		$current_class = trim($tmp[1]);
		echo "current class : $current_class\n";
		if ( ereg('extends',$line) ) {
			trim($tmp[3]);
			$a[$i][2] = "/* Please see class.base_nusoap.inc.php for more information */\n\n".
	"if (@!".'$GLOBALS'."['phpgw_info']['flags']['included_classes']['$tmp[3]'])\n".
	"{\n\trequire_once(PHPGW_API_INC.\"/class.$tmp[3].inc.php\");\n\t".
	'$GLOBALS'."['phpgw_info']['flags']['included_classes']['$tmp[3]'] = True;\n}\n";
		$line = ereg_replace($tmp[3], "phpgwapi_$tmp[3]", $line);
		} else {
			$a[$i][2] = "/*\n".
				"* @internal : This is an internal class which is used as the base for the Soap Api\n".
				"* @access : private\n".
				"*/\n\n";
		}
		print "class.$tmp[1].inc.php\n";
		$a[$i][0] = "class.$tmp[1].inc.php";
		$line = ereg_replace('^class ([a-zA-Z_]+)','class phpgwapi_\\1', $line);
	} elseif ( ereg("function $current_class", $line) ) {
		/* we modify the constructor */
		$line = ereg_replace("function $current_class", "function phpgwapi_$current_class", $line);
		$current_class = '_not_me_';
	} elseif ( ereg('parent::', $line) ) {
		/* we need to change call to parent classes */
		$line = ereg_replace('parent::([a-zA-Z_]+)', 'parent::phpgwapi_\\1', $line);
	} elseif ( ereg('\$Id[:]',$line) ) {
		/* Replace the version wih the based on */
		$line = ereg_replace('\$Id[:]', '$ I d :', $line ) ;
	} elseif ( ereg('new ', $line) && ! ereg('\$new|makeObj|lib_bwcheck',$line) && !ereg('\*|//',$line) && !ereg('->debug', $line) ) {
		if ( ! ereg('eval', $line) && ! ereg('"',$line) && !ereg('new \$class',$line) ) {
			if ( !ereg('new [[:alpha:]]+;',$line) ) {
				/* Replace the '(' for the constructor into a '",' */
				$line = ereg_replace('\(','",',$line);
				/* Then replace the new by the createObject */
				$line = ereg_replace('new ','createObject ("phpgwapi.', $line );
				/* Avoid to use =& for functions ! */
				$line = ereg_replace('=&', '=', $line);
			} else {
				if ( ! ereg('\.',$line) )
				{
					$line = ereg_replace('new ','createObject ("phpgwapi.', $line );
					$line = ereg_replace(';','");',$line);
				}
				else
				{
					print "\n".'WARNING !! : Please take a look at the \'new\' near line '.($j + 15)."\n";
				}
			}
		} else {
			/* This is more tricky if the new is inside an eval .. */
			print "\n".'WARNING !! : Please take a look at the \'new\' near line '.($j + 15 )."\n";
			/* This is commented because eval is dangerous 
			see the soapclient class */
//			$line = ereg_replace('\(','\\",',$line);
//			$line = ereg_replace('eval\\\",','eval(',$line );
//			$line = ereg_replace('new ','createObject (\"phpgwapi.', $line );
		}
	}
	if ( ereg('createobject',$line) && ereg('soap_XMLSchema ',$line) )
	{
		$line = ereg_replace('soap_XMLSchema ','soap_XMLSchema',$line);
	}
	/*  Change the user Agent of the nusoap base ?? */
	#$line = ereg_replace('var \$title = \'[[:alpha:]]*\'','var $title = \'phpGroupware/\' . $cliversion . \'(PHP / NuSOAP ) \'',$line);
	$line = ereg_replace('var \$title = \'[[:alpha:]]*\'','var $title = \'phpGroupware / (PHP / \1 ) \'',$line);
	if ( ereg('^<\?php',$line) ) {
		$a[$i][1] = $line;
	} else {
		$a[$i][$j++] = $line;
	}
	if ( ereg('^\?>',$line) ) {
		$j = 3;
		$i++;
	}
}

/* Write the final files */
$k = 0;
foreach($a as $tab) {
	$fd = fopen($tab[0],"w+");
	for($k = 1; isset($tab[$k]); $k++ ) 
	{
		fwrite($fd,$tab[$k]);
		if ( $k == 1 ) 
		{
			fwrite($fd,$header);
		}
	}
	fclose($fd);
	/* Check if the syntax is ok */
	if ( system("php -l $tab[0]") != 0 ) 
	{
		print "I miss the $tab[0] file !\n";
	}
}

?>
<?php
/*Dummy definition ! */
	class phpgwapi_soap_transport_http 
	{
		function phpgwapi_soap_transport() {
		}
	}
?>
<?php
/* Dummy definition ! */
	class phpgwapi_soapval 
	{
		function phpgwapi_soapval() {
		}
	}
?>
<?php
/* SOAP_CLIENT */
/***************************************************************************
* TOTALY DEPRECATED , DON'T USE
*/
	/**
	* SOAPx4 client
	* @author Edd Dumbill <edd@usefulinc.com>
	* @author Victor Zou <victor@gigaideas.com.cn>
	* @author Dietrich Ayala <dietrich@ganx4.com>
	* @copyright Copyright (C) 1999-2000 Edd Dumbill
	* @copyright Copyright (C) 2000-2001 Victor Zou
	* @copyright Copyright (C) 2001 Dietrich Ayala
	* @copyright Portions Copyright (C) 2003,2004 Free Software Foundation, Inc. http://www.fsf.org/
	* @package phpgwapi
	* @subpackage communication
	* @version $ I d: class.soap_client.inc.php,v 1.6.4.3 2004/02/10 13:51:19 ceb
Exp $
	* @internal This project began based on code from the 2 projects below,
	* @internal and still contains some original code. The licenses of both must be respected.
	* @internal XML-RPC for PHP; SOAP for PHP
	*/

	/**
	* SOAPx4 client
	* @package phpgwapi
	* @subpackage communication
	* $path can be a complete endpoint url, with the other parameters left blank:
	* $soap_client = new soap_client("http://path/to/soap/server");
	* @deprecated : this is a wrapper to class.soap_transport_http.inc.php
	*/

class soap_client extends phpgwapi_soap_transport_http 
	{
		 function soap_client($path,$server=False,$port=False)
		 {
			$url = '';
			/* We MUST Heavily test this !! */
			/* Would be better if we "just" change class.interserver.inc.php */
			if ( $server ) {
				$url .= $server;
			}
			if ( $port ) {
				$url .= ':'.$port;
			}
			$url .= $path;
			/* Call our parent constructor */
			$this->soap_transport_http($url);
		}

		function send($msg, $action, $timeout=0, $ssl=False)
		{
			// where msg is an soapmsg
			$msg->debug_flag = $this->debug_flag;
			//$this->action = $action;
			$this->setSOAPAction($action);
			if($ssl)
			{
				return $this->ssl_sendPayloadHTTP10(
					$msg,
					$this->server,
					$this->port,
					$timeout,
					$this->username,
					$this->password
				);
			}
			else
			{
				return $this->sendPayloadHTTP10(
					$msg,
					$this->server,
					$this->port,
					$timeout,
					$this->username,
					$this->password
				);
			}
		}

		function sendPayloadHTTP10($msg, $server, $port, $timeout=0, $username='', $password='')
		{	
			$this->scheme = 'http';
			/* Add some specific headers */
			$this->outgoing_headers['X-PHPGW-Server'] = $this->server; // ?? strange ...
			$this->outgoing_headers['X-PHPGW-Version'] = $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] ;
			if ( $username ) {
				$this->setCredentials($username,$password);
			}
			return soap_transport_http::send($msg,$timeout);
		}

		function ssl_sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='')
		{
			$this->scheme = 'https';
			/* Add some specific headers */
			$this->outgoing_headers['X-PHPGW-Server'] = $this->server; // ?? strange ...
			$this->outgoing_headers['X-PHPGW-Version'] = $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] ;
			if ( $username ) {
				$this->setCredentials($username,$password);
			}
			return soap_transport_http::send($msg,$timeout);
		}

	} // end class soap_client
?>
<?php
	/**
	* SOAPx4 value object
	* @author Edd Dumbill <edd@usefulinc.com>
	* @author Victor Zou <victor@gigaideas.com.cn>
	* @author Dietrich Ayala <dietrich@ganx4.com>
	* @copyright Copyright (C) 1999-2000 Edd Dumbill
	* @copyright Copyright (C) 2000-2001 Victor Zou
	* @copyright Copyright (C) 2001 Dietrich Ayala
	* @copyright Portions Copyright (C) 2003,2004 Free Software Foundation, Inc. http://www.fsf.org/
	* @package phpgwapi
	* @subpackage communication
	* @version $Id: nusoap2phpgwapi 17828 2006-12-28 18:02:30Z Caeies $
	* @internal This project began based on code from the 2 projects below,
	* @internal and still contains some original code. The licenses of both must be respected.
	* @internal XML-RPC for PHP; SOAP for PHP
	*/

	/**
	* SOAPx4 value object
	*
	* @package phpgwapi
	* @subpackage communication
	*/
class phpgw_soapval extends phpgwapi_soapval 
	{
	// 	function phpgw_soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False)
		function phpgw_soapval($name='',$type=False,$value=0,$namespace=False,$type_namespace=False)
		{
			// detect type if not passed
			if(!$type)
			{
				if(is_array($value) && count($value) >= 1)
				{
					if(ereg("[a-zA-Z0-9\-]*",key($v)))
					{
						$type = 'struct';
					}
					else
					{
						$type = 'array';
					}
				}
				elseif(is_int($v))
				{
					$type = 'int';
				}
				elseif(is_float($v) || $v == 'NaN' || $v == 'INF')
				{
					$type = 'float';
				}
				else
				{
					$type = gettype($value);
				}
			}
			// php type name mangle
			if($type == 'integer')
			{
				$type = 'int';
			}

			$this->soapTypes = $GLOBALS['soapTypes'];
			$this->name = $name;
			$this->value = '';
			$this->type = $type;
			$this->type_code = 0;
			$this->type_prefix = false;
			$this->array_type = '';
			$this->debug_flag = False;
			$this->debug_str = '';
			$this->debug("Entering soapval - name: '$name' type: '$type'");

			if($namespace)
			{
				$this->namespace = $namespace;
				if(!isset($GLOBALS['namespaces'][$namespace]))
				{
					$GLOBALS['namespaces'][$namespace] = "ns".(count($GLOBALS['namespaces'])+1);
				}
				$this->prefix = $GLOBALS['namespaces'][$namespace];
			}

			// get type prefix
			if(ereg(":",$type))
			{
				$this->type = substr(strrchr($type,':'),1,strlen(strrchr($type,':')));
				$this->type_prefix = substr($type,0,strpos($type,':'));
			}
			elseif($type_namespace)
			{
				if(!isset($GLOBALS['namespaces'][$type_namespace]))
				{
					$GLOBALS['namespaces'][$type_namespace] = 'ns'.(count($GLOBALS['namespaces'])+1);
				}
				$this->type_prefix = $GLOBALS['namespaces'][$type_namespace];
			}

			// if type namespace was not explicitly passed, and we're not in a method struct:
			elseif(!$this->type_prefix && !isset($this->namespace))
			{
				// try to get type prefix from typeMap
				if(!$this->type_prefix = $this->verify_type($type))
				{
					// else default to method namespace
					$this->type_prefix = $GLOBALS['namespaces'][$GLOBALS['methodNamespace']];
				}
			}

			// if scalar
			if($this->soapTypes[$this->type] == 1)
			{
				$this->type_code = 1;
				$this->addScalar($value,$this->type,$name);
			// if array
			}
			elseif($this->soapTypes[$this->type] == 2)
			{
				$this->type_code = 2;
				$this->addArray($value);
			// if struct
			}
			elseif($this->soapTypes[$this->type] == 3)
			{
				$this->type_code = 3;
				$this->addStruct($value);
			}
			else
			{
				//if($namespace == $GLOBALS['methodNamespace']){
					$this->type_code = 3;
					$this->addStruct($value);
				//}
			}
		}

		function addScalar($value, $type, $name="")
		{
			$this->debug("adding scalar '$name' of type '$type'");
			
			// if boolean, change value to 1 or 0
			if ($type == "boolean")
			{
				if((strcasecmp($value,"true") == 0) || ($value == 1))
				{
					$value = 1;
				}
				else
				{
					$value = 0;
				}
			}

			$this->value = $value;
			return true;
		}

		function addArray($vals)
		{
			$this->debug("adding array '$this->name' with ".count($vals)." vals");
			$this->value = array();
			if(is_array($vals) && count($vals) >= 1)
			{
				@reset($vals);
				while(list($k,$v) = @each($vals))
				/* foreach($vals as $k => $v) */
				{
					$this->debug("checking value $k : $v");
					// if soapval, add..
					if(get_class($v) == 'soapval')
					{
						$this->value[] = $v;
						$this->debug($v->debug_str);
					// else make obj and serialize
					}
					else
					{
						if(is_array($v))
						{
							if(ereg("[a-zA-Z\-]*",key($v)))
							{
								$type = 'struct';
							}
							else
							{
								$type = 'array';
							}
						}
						elseif(!ereg("^[0-9]*$",$k) && in_array($k,array_keys($this->soapTypes)))
						{
							$type = $k;
						}
						elseif(is_int($v))
						{
							$type = 'int';
						}
						elseif(is_float($v) || $v == 'NaN' || $v == 'INF')
						{
							$type = 'float';
						}
						else
						{
							$type = gettype($v);
						}
						$new_val = createObject('phpgwapi.soapval','item',$type,$v);
						$this->debug($new_val->debug_str);
						$this->value[] = $new_val;
					}
				}
			}
			return true;
		}

		function addStruct($vals)
		{
			$this->debug("adding struct '$this->name' with ".count($vals).' vals');
			if(is_array($vals) && count($vals) >= 1)
			{
				@reset($vals);
				while(list($k,$v) = @each($vals))
				/* foreach($vals as $k => $v) */
				{
					// if serialize, if soapval
					if(get_class($v) == 'soapval')
					{
						$this->value[] = $v;
						$this->debug($v->debug_str);
					// else make obj and serialize
					}
					else
					{
						if(is_array($v))
						{
							@reset($v);
							while(list($a,$b) = @each($v))
							/* foreach($v as $a => $b) */
							{
								if($a == "0")
								{
									$type = 'array';
								}
								else
								{
									$type = 'struct';
								}
								break;
							}
						}
						elseif(is_array($k) && in_array($k,array_keys($this->soapTypes)))
//						elseif(is_array($k,in_array($k,array_keys($this->soapTypes))))
						{
							$this->debug("got type '$type' for value '$v' from soapTypes array!");
							$type = $k;
						}
						elseif(is_int($v))
						{
							$type = 'int';
						}
						elseif(is_float($v) || $v == "NaN" || $v == "INF")
						{
							$type = 'float';
						}
						else
						{
							$type = gettype($v);
							$this->debug("got type '$type' for value '$v' from php gettype()!");
						}
						$new_val = createObject('phpgwapi.soapval',$k,$type,$v);
						$this->debug($new_val->debug_str);
						$this->value[] = $new_val;
					}
				}
			}
			else
			{
				$this->value = array();
			}
			return true;
		}

		// turn soapvals into xml, woohoo!
		function serializeval($soapval=false)
		{
			if(!$soapval)
			{
				$soapval = $this;
			}
			$this->debug("serializing '$soapval->name' of type '$soapval->type'");
			if($soapval->name == '')
			{
				$soapval->name = 'return';
			}

			switch($soapval->type_code)
			{
				case 3:
					// struct
					$this->debug('got a struct');
					if($soapval->prefix && $soapval->type_prefix)
					{
						$xml .= "<$soapval->prefix:$soapval->name xsi:type=\"$soapval->type_prefix:$soapval->type\">\n";
					}
					elseif($soapval->type_prefix)
					{
						$xml .= "<$soapval->name xsi:type=\"$soapval->type_prefix:$soapval->type\">\n";
					}
					elseif($soapval->prefix)
					{
						$xml .= "<$soapval->prefix:$soapval->name>\n";
					}
					else
					{
						$xml .= "<$soapval->name>\n";
					}
					if(is_array($soapval->value))
					{
						@reset($soapval->value);
						while(list($k,$v) = @each($soapval->value))
						/* foreach($soapval->value as $k => $v) */
						{
							$xml .= $this->serializeval($v);
						}
					}
					if($soapval->prefix)
					{
						$xml .= "</$soapval->prefix:$soapval->name>\n";
					}
					else
					{
						$xml .= "</$soapval->name>\n";
					}
					break;
				case 2:
					// array
					@reset($soapval->value);
					while(list($null,$array_val) = @each($soapval->value))
					/* foreach($soapval->value as $array_val) */
					{
						$array_types[$array_val->type] = 1;
						$xml .= $this->serializeval($array_val);
					}
					if(count($array_types) > 1)
					{
						$array_type = 'xsd:ur-type';
					}
					elseif(count($array_types) >= 1)
					{
						$array_type = $array_val->type_prefix.":".$array_val->type;
					}

					$xml = "<$soapval->name xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_type."[".sizeof($soapval->value)."]\">\n".$xml."</$soapval->name>\n";
					break;
				case 1:
					$xml .= "<$soapval->name xsi:type=\"$soapval->type_prefix:$soapval->type\">$soapval->value</$soapval->name>\n";
					break;
				default:
					break;
			}
			return $xml;
		}

		function decode($soapval=false)
		{
			if(!$soapval)
			{
				$soapval = $this;
			}
			// scalar decode
			if($soapval->type_code == 1)
			{
				return $soapval->value;
			// array decode
			}
			elseif($soapval->type_code == 2)
			{
				if(is_array($soapval->value))
				{
					@reset($soapval->value);
					while(list($null,$item) = @each($soapval->value))
					/* foreach($soapval->value as $item) */
					{
						$return[] = $this->decode($item);
					}
					return $return;
				}
				else
				{
					return array();
				}
			// struct decode
			}
			elseif($soapval->type_code == 3)
			{
				if(is_array($soapval->value))
				{
					@reset($soapval->value);
					while(list($null,$item) = @each($soapval->value))
					/* foreach($soapval->value as $item) */
					{
						$return[$item->name] = $this->decode($item);
					}
					return $return;
				}
				else
				{
					return array();
				}
			}
		}

		// verify type
		function verify_type($type)
		{
			if ($type)
			{
//				global $GLOBALS['namespaces'],$GLOBALS['soapTypes'],$GLOBALS['typemap'];
//				global $GLOBALS['namespaces'],$GLOBALS['typemap'];

				@reset($GLOBALS['typemap']);
				while(list($namespace,$types) = @each($GLOBALS['typemap']))
				/* foreach($GLOBALS['typemap'] as $namespace => $types) */
				{
					if(in_array($type,$types))
					{
						return $GLOBALS['namespaces'][$namespace];
					}
				}
			}
			return false;
		}

		// alias for verify_type() - pass it a type, and it returns it's prefix
		function get_prefix($type)
		{
			if($prefix = $this->verify_type($type))
			{
				return $prefix;
			}
			return false;
		}

		function debug($string)
		{
			if($this->debug_flag)
			{
				$this->debug_str .= "$string\n";
			}
		}
	}
?>
