<?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.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");
	*/
	class soap_client
	{
		 function soap_client($path,$server=False,$port=False)
		 {
			$this->port = 80;
			$this->path = $path;
			$this->server = $server;
			$this->errno;
			$this->errstring;
			$this->debug_flag = True;
			$this->debug_str = '';
			$this->username = '';
			$this->password = '';
			$this->action = '';
			$this->incoming_payload = '';
			$this->outgoing_payload = '';
			$this->response = '';
			$this->action = '';

			// endpoint mangling
			if(ereg("^http://",$path))
			{
				$path = str_replace('http://','',$path);
				$this->path = strstr($path,'/');
				$this->debug("path = $this->path");
				if(ereg(':',$path))
				{
					$this->server = substr($path,0,strpos($path,':'));
					$this->port = substr(strstr($path,':'),1);
					$this->port = substr($this->port,0,strpos($this->port,'/'));
				}
				else
				{
					$this->server = substr($path,0,strpos($path,'/'));
				}
			}
			if($port)
			{
				$this->port = $port;
			}
		}

		function setCredentials($u, $p)
		{
			$this->username = $u;
			$this->password = $p;
		}

		function send($msg, $action, $timeout=0, $ssl=False)
		{
			// where msg is an soapmsg
			$msg->debug_flag = $this->debug_flag;
			$this->action = $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='')
		{	
			if($timeout > 0)
			{
				$fp = fsockopen($server, $port,&$this->errno, &$this->errstr, $timeout);
			}
			else
			{
				$fp = fsockopen($server, $port,&$this->errno, &$this->errstr);
			}
			if (!$fp)
			{
				$this->debug("Couldn't open socket connection to server!");
				$this->debug("Server: $this->server"); 
				return 0;
			}

			// thanks to Grant Rauscher <grant7@firstworld.net> for this
			$credentials = '';
			if ($username != '')
			{
				$credentials = "Authorization: Basic " . base64_encode($username . ":" . $password) . "\r\n";
			}

			$soap_data = $msg->serialize();
			$this->outgoing_payload = 'POST '
				. $this->path
				. " HTTP/1.0\r\n"
				. 'User-Agent: phpGroupware/' . $cliversion . '(PHP) ' . "\r\n"
				. 'X-PHPGW-Server: ' . $this->server . "\r\n"
				. 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
				. 'Host: '.$this->server . "\r\n"
				. $credentials
				. "Content-Type: text/xml\r\nContent-Length: " . strlen($soap_data) . "\r\n"
				. 'SOAPAction: "' . $this->action . '"' . "\r\n\r\n"
				. $soap_data;
			// send
			if(!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload)))
			{
				$this->debug('Write error');
			}

			// get reponse
			while($data = fread($fp, 32768))
			{
				$incoming_payload .= $data;
			}

			fclose($fp);
			$this->incoming_payload = $incoming_payload;
			// $response is a soapmsg object
			$this->response = $msg->parseResponse($incoming_payload);
			$this->debug($msg->debug_str);
			return $this->response;
		}

		function ssl_sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='')
		{
			if(!function_exists(curl_init))
			{
				$this->errstr = 'No curl functions available - use of ssl is invalid';
				return False;
			}
			/* curl Method borrowed from:
			  http://sourceforge.net/tracker/index.php?func=detail&aid=427359&group_id=23199&atid=377731
			*/

			// thanks to Grant Rauscher <grant7@firstworld.net>
			// for this
			$credentials = '';
			if ($username!='')
			{
				$credentials = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n";
			}

			$soap_data = $msg->serialize();
			$this->outgoing_payload = 'POST '
				. $this->path
				. " HTTP/1.0\r\n"
				. 'User-Agent: phpGroupware/' . $cliversion . '(PHP) ' . "\r\n"
				. 'X-PHPGW-Server: ' . $this->server . "\r\n"
				. 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
				. 'Host: ' . $this->server . "\r\n"
				. $credentials
				. "Content-Type: text/xml\r\nContent-Length: " . strlen($soap_data) . "\r\n"
				. 'SOAPAction: "' . $this->action . '"' . "\r\n\r\n"
				. $soap_data;

			// send
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL,$this->server);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			$incoming_payload = curl_exec($ch);
			curl_close($ch);

			$this->incoming_payload = $incoming_payload;
			// $response is a soapmsg object
			$this->response = $msg->parseResponse($incoming_payload);
			$this->debug($msg->debug_str);
			return $this->response;
		}

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