<?php
	/**
	* 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 $Id: class.phpgw_soapclient.inc.php 18147 2007-05-23 13:14:20Z 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 client
	*
	* @package phpgwapi
	* @subpackage communication
	* $path can be a complete endpoint url, with the other parameters left blank:
	* $soap_client = new phpgw_soapclient("http://path/to/soap/server");
	*
	* soapx4 high level class
	*
	* usage:
	*
	* // instantiate client with server info
	* $soapclient = new phpgw_soapclient( string path [ ,boolean wsdl] );
	*
	* // call method, get results
	* echo $soapclient->call( string methodname [ ,array parameters] );
	*
	* // bye bye client
	* unset($soapclient);
	*/
	class phpgw_soapclient
	{
		function phpgw_soapclient($endpoint,$wsdl=False,$portName=False)
		{
			$this->debug_flag = True;
			$this->endpoint = $endpoint;
			$this->portName = False;

			// make values
			if($wsdl)
			{
				$this->endpointType = 'wsdl';
				if($portName)
				{
					$this->portName = $portName;
				}
			}
		}

		function call($method,$params='',$namespace=false,$soapAction=false)
		{
			if($this->endpointType == 'wsdl')
			{
				// instantiate wsdl class
				if(!is_object($this->wsdl))
				{
					$this->wsdl = CreateObject('phpgwapi.wsdl',$this->endpoint);
				}
				// get portName
				if(!$this->portName)
				{
					$this->portName = $this->wsdl->getPortName($method);
				}
				// get endpoint
				if(!$this->endpoint = $this->wsdl->getEndpoint($this->portName))
				{
					die("no port of name '$this->portName' in the wsdl at that location!");
				}
				$this->debug("endpoint: $this->endpoint");
				$this->debug("portName: $this->portName");
			}
			// get soapAction
			if(!$soapAction)
			{
				if($this->endpointType != 'wsdl')
				{
					die("method call requires soapAction if wsdl is not available!");
				}
				if(!$soapAction = $this->wsdl->getSoapAction($this->portName,$method))
				{
					die("no soapAction for operation: $method!");
				}
			}
			$this->debug("soapAction: $soapAction");
			// get namespace
			if(!$namespace)
			{
				if($this->endpointType != 'wsdl')
				{
					die("method call requires namespace if wsdl is not available!");
				}
				if(!$namespace = $this->wsdl->getNamespace($this->portName,$method))
				{
					die("no soapAction for operation: $method!");
				}
			}
			$this->debug("namespace: $namespace");

			// make message
			$soapmsg = CreateObject('phpgwapi.soapmsg',$method,$params,$namespace);
			/* _debug_array($soapmsg); */
			
			// instantiate client
			$dbg = "calling server at '$this->endpoint'...";
			if($soap_client = CreateObject('phpgwapi.soap_client',$this->endpoint))
			{
				//$soap_client->debug_flag = true;
				$this->debug($dbg.'instantiated client successfully');
				$this->debug("client data:<br />server: $soap_client->server<br />path: $soap_client->path<br />port: $soap_client->port");
				// send
				$dbg = "sending msg w/ soapaction '$soapAction'...";
				if($return = $soap_client->send($soapmsg,$soapAction))
				{
					$this->request = $soap_client->outgoing_payload;
					$this->response = $soap_client->incoming_payload;
					$this->debug($dbg . "sent message successfully and got a '$return' back");
					// check for valid response
					if(get_class($return) == 'soapval')
					{
						// fault?
						if(eregi('fault',$return->name))
						{
							$this->debug('got fault');
							$faultArray = $return->decode();
							@reset($faultArray);
							while(list($k,$v) = @each($faultArray))
							/* foreach($faultArray as $k => $v) */
							{
								print "$k = $v<br />";
							}
							return false;
						}
						else
						{
							$returnArray = $return->decode();
							if(is_array($returnArray))
							{
								return array_shift($returnArray);
							}
							else
							{
								$this->debug("didn't get array back from decode() for $return->name");
								return false;
							}
						}
					}
					else
					{
						$this->debug("didn't get soapval object back from client");
						return false;
					}
				}
				else
				{
					$this->debug('client send/recieve error');
					return false;
				}
			}
		}

		function debug($string)
		{
			if($this->debug_flag)
			{
				print $string . '<br />';
			}
		}
	}
?>
