mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 16:48:49 +01:00
Import SOAP classes
This commit is contained in:
parent
e02021ad21
commit
0593d5ed96
148
phpgwapi/inc/class.soap_client.inc.php
Normal file
148
phpgwapi/inc/class.soap_client.inc.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
SOAPx4
|
||||
by Dietrich Ayala (C) 2001 dietrich@ganx4.com
|
||||
|
||||
This project began based on code from the 2 projects below,
|
||||
and still contains some original code. The licenses of both must be respected.
|
||||
|
||||
XML-RPC for PHP
|
||||
originally by Edd Dumbill (C) 1999-2000
|
||||
|
||||
SOAP for PHP
|
||||
by Victor Zou (C) 2000-2001 <victor@gigaideas.com.cn>
|
||||
|
||||
*/
|
||||
|
||||
// $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 = False;
|
||||
$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)
|
||||
{
|
||||
// where msg is an soapmsg
|
||||
$msg->debug = $this->debug;
|
||||
$this->action = $action;
|
||||
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: SOAPx4 v0.13492\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
|
||||
//$msg->debug_flag = true;
|
||||
$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
|
||||
?>
|
365
phpgwapi/inc/class.soap_parser.inc.php
Normal file
365
phpgwapi/inc/class.soap_parser.inc.php
Normal file
@ -0,0 +1,365 @@
|
||||
<?php
|
||||
class soap_parser
|
||||
{
|
||||
function soap_parser($xml='')
|
||||
{
|
||||
global $soapTypes;
|
||||
|
||||
$this->soapTypes = $soapTypes;
|
||||
$this->xml = $xml;
|
||||
$this->xml_encoding = "UTF-8";
|
||||
$this->root_struct = "";
|
||||
// options: envelope,header,body,method
|
||||
$this->status = "";
|
||||
$this->position = 0;
|
||||
$this->pos_stat = 0;
|
||||
$this->depth = 0;
|
||||
$this->default_namespace = "";
|
||||
$this->namespaces = array();
|
||||
$this->message = array();
|
||||
$this->fault = false;
|
||||
$this->fault_code = "";
|
||||
$this->fault_str = "";
|
||||
$this->fault_detail = "";
|
||||
$this->eval_str = "";
|
||||
$this->depth_array = array();
|
||||
$this->debug_flag = False;
|
||||
$this->debug_str = "";
|
||||
$this->previous_element = "";
|
||||
|
||||
$this->entities = array (
|
||||
"&" => "&",
|
||||
"<" => "<",
|
||||
">" => ">",
|
||||
"'" => "'",
|
||||
'"' => """
|
||||
);
|
||||
|
||||
// Check whether content has been read.
|
||||
if(!empty($xml))
|
||||
{
|
||||
$this->debug("Entering soap_parser()");
|
||||
//$this->debug("DATA DUMP:\n\n$xml");
|
||||
// Create an XML parser.
|
||||
$this->parser = xml_parser_create($this->xml_encoding);
|
||||
// Set the options for parsing the XML data.
|
||||
//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
|
||||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
// Set the object for the parser.
|
||||
xml_set_object($this->parser, &$this);
|
||||
// Set the element handlers for the parser.
|
||||
xml_set_element_handler($this->parser, "start_element","end_element");
|
||||
xml_set_character_data_handler($this->parser,"character_data");
|
||||
xml_set_default_handler($this->parser, "default_handler");
|
||||
|
||||
// Parse the XML file.
|
||||
if(!xml_parse($this->parser,$xml,true))
|
||||
{
|
||||
// Display an error message.
|
||||
$this->debug(sprintf("XML error on line %d: %s",
|
||||
xml_get_current_line_number($this->parser),
|
||||
xml_error_string(xml_get_error_code($this->parser))));
|
||||
$this->fault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get final eval string
|
||||
$this->eval_str = "\$response = ".trim($this->build_eval($this->root_struct)).";";
|
||||
}
|
||||
xml_parser_free($this->parser);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug("xml was empty, didn't parse!");
|
||||
}
|
||||
}
|
||||
|
||||
// loop through msg, building eval_str
|
||||
function build_eval($pos)
|
||||
{
|
||||
$this->debug("inside build_eval() for $pos: ".$this->message[$pos]["name"]);
|
||||
$eval_str = $this->message[$pos]["eval_str"];
|
||||
// loop through children, building...
|
||||
if($this->message[$pos]["children"] != "")
|
||||
{
|
||||
$this->debug("children string = ".$this->message[$pos]["children"]);
|
||||
$children = explode("|",$this->message[$pos]["children"]);
|
||||
$this->debug("it has ".count($children)." children");
|
||||
foreach($children as $c => $child_pos)
|
||||
{
|
||||
//$this->debug("child pos $child_pos: ".$this->message[$child_pos]["name"]);
|
||||
if($this->message[$child_pos]["eval_str"] != "")
|
||||
{
|
||||
$this->debug("entering build_eval() for ".$this->message[$child_pos]["name"].", array pos $c, pos: $child_pos");
|
||||
$eval_str .= $this->build_eval($child_pos).", ";
|
||||
}
|
||||
}
|
||||
$eval_str = substr($eval_str,0,strlen($eval_str)-2);
|
||||
}
|
||||
// add current node's eval_str
|
||||
$eval_str .= $this->message[$pos]["end_eval_str"];
|
||||
return $eval_str;
|
||||
}
|
||||
|
||||
// start-element handler
|
||||
function start_element($parser, $name, $attrs)
|
||||
{
|
||||
// position in a total number of elements, starting from 0
|
||||
// update class level pos
|
||||
$pos = $this->position++;
|
||||
// and set mine
|
||||
$this->message[$pos]["pos"] = $pos;
|
||||
|
||||
// parent/child/depth determinations
|
||||
|
||||
// depth = how many levels removed from root?
|
||||
// set mine as current global depth and increment global depth value
|
||||
$this->message[$pos]["depth"] = $this->depth++;
|
||||
|
||||
// else add self as child to whoever the current parent is
|
||||
if($pos != 0)
|
||||
{
|
||||
$this->message[$this->parent]["children"] .= "|$pos";
|
||||
}
|
||||
// set my parent
|
||||
$this->message[$pos]["parent"] = $this->parent;
|
||||
// set self as current value for this depth
|
||||
$this->depth_array[$this->depth] = $pos;
|
||||
// set self as current parent
|
||||
$this->parent = $pos;
|
||||
|
||||
// set status
|
||||
if(ereg(":Envelope$",$name))
|
||||
{
|
||||
$this->status = "envelope";
|
||||
}
|
||||
elseif(ereg(":Header$",$name))
|
||||
{
|
||||
$this->status = "header";
|
||||
}
|
||||
elseif(ereg(":Body$",$name))
|
||||
{
|
||||
$this->status = "body";
|
||||
// set method
|
||||
}
|
||||
elseif($this->status == "body")
|
||||
{
|
||||
$this->status = "method";
|
||||
if(ereg(":",$name))
|
||||
{
|
||||
$this->root_struct_name = substr(strrchr($name,":"),1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->root_struct_name = $name;
|
||||
}
|
||||
$this->root_struct = $pos;
|
||||
$this->message[$pos]["type"] = "struct";
|
||||
}
|
||||
// set my status
|
||||
$this->message[$pos]["status"] = $this->status;
|
||||
|
||||
// set name
|
||||
$this->message[$pos]["name"] = htmlspecialchars($name);
|
||||
// set attrs
|
||||
$this->message[$pos]["attrs"] = $attrs;
|
||||
// get namespace
|
||||
if(ereg(":",$name))
|
||||
{
|
||||
$namespace = substr($name,0,strpos($name,":"));
|
||||
$this->message[$pos]["namespace"] = $namespace;
|
||||
$this->default_namespace = $namespace;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->message[$pos]["namespace"] = $this->default_namespace;
|
||||
}
|
||||
// loop through atts, logging ns and type declarations
|
||||
foreach($attrs as $key => $value)
|
||||
{
|
||||
// if ns declarations, add to class level array of valid namespaces
|
||||
if(ereg("xmlns:",$key))
|
||||
{
|
||||
$namespaces[substr(strrchr($key,":"),1)] = $value;
|
||||
if($name == $this->root_struct_name)
|
||||
{
|
||||
$this->methodNamespace = $value;
|
||||
}
|
||||
}
|
||||
// if it's a type declaration, set type
|
||||
elseif($key == "xsi:type")
|
||||
{
|
||||
// then get attname and set $type
|
||||
$type = substr(strrchr($value,":"),1);
|
||||
}
|
||||
}
|
||||
|
||||
// set type if available
|
||||
if($type)
|
||||
{
|
||||
$this->message[$pos]["type"] = $type;
|
||||
}
|
||||
|
||||
// debug
|
||||
//$this->debug("parsed $name start, eval = '".$this->message[$pos]["eval_str"]."'");
|
||||
}
|
||||
|
||||
// end-element handler
|
||||
function end_element($parser, $name)
|
||||
{
|
||||
// position of current element is equal to the last value left in depth_array for my depth
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
// bring depth down a notch
|
||||
$this->depth--;
|
||||
|
||||
// get type if not set already
|
||||
if($this->message[$pos]["type"] == "")
|
||||
{
|
||||
if($this->message[$pos]["cdata"] == "" && $this->message[$pos]["children"] != "")
|
||||
{
|
||||
$this->message[$pos]["type"] = "SOAPStruct";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->message[$pos]["type"] = "string";
|
||||
}
|
||||
}
|
||||
|
||||
// set eval str start if it has a valid type and is inside the method
|
||||
if($pos >= $this->root_struct)
|
||||
{
|
||||
$this->message[$pos]["eval_str"] .= "\n CreateObject(\"phpgwapi.soapval\",\"".htmlspecialchars($name)."\", \"".$this->message[$pos]["type"]."\" ";
|
||||
$this->message[$pos]["end_eval_str"] = ")";
|
||||
$this->message[$pos]["inval"] = "true";
|
||||
/*
|
||||
if($this->message[$pos]["name"] == $this->root_struct_name){
|
||||
$this->message[$pos]["end_eval_str"] .= " ,\"$this->methodNamespace\"";
|
||||
}
|
||||
*/
|
||||
if($this->message[$pos]["children"] != "")
|
||||
{
|
||||
$this->message[$pos]["eval_str"] .= ", array( ";
|
||||
$this->message[$pos]["end_eval_str"] .= " )";
|
||||
}
|
||||
}
|
||||
|
||||
// if i have no children and have cdata...then i must be a scalar value, so add my data to the eval_str
|
||||
if($this->status == "method" && $this->message[$pos]["children"] == "")
|
||||
{
|
||||
// add cdata w/ no quotes if only int/float/dbl
|
||||
if($this->message[$pos]["type"] == "string")
|
||||
{
|
||||
$this->message[$pos]["eval_str"] .= ", \"".$this->message[$pos]["cdata"]."\"";
|
||||
}
|
||||
elseif($this->message[$pos]["type"] == "int" || $this->message[$pos]["type"] == "float" || $this->message[$pos]["type"] == "double")
|
||||
{
|
||||
//$this->debug("adding cdata w/o quotes");
|
||||
$this->message[$pos]["eval_str"] .= ", ".trim($this->message[$pos]["cdata"]);
|
||||
}
|
||||
elseif(is_string($this->message[$pos]["cdata"]))
|
||||
{
|
||||
//$this->debug("adding cdata w/ quotes");
|
||||
$this->message[$pos]["eval_str"] .= ", \"".$this->message[$pos]["cdata"]."\"";
|
||||
}
|
||||
}
|
||||
// if in the process of making a soap_val, close the parentheses and move on...
|
||||
if($this->message[$pos]["inval"] == "true")
|
||||
{
|
||||
$this->message[$pos]["inval"] == "false";
|
||||
}
|
||||
// if tag we are currently closing is the method wrapper
|
||||
if($pos == $this->root_struct)
|
||||
{
|
||||
$this->status = "body";
|
||||
}
|
||||
elseif(ereg(":Body",$name))
|
||||
{
|
||||
$this->status = "header";
|
||||
}
|
||||
elseif(ereg(":Header",$name))
|
||||
{
|
||||
$this->status = "envelope";
|
||||
}
|
||||
// set parent back to my parent
|
||||
$this->parent = $this->message[$pos]["parent"];
|
||||
//$this->debug("parsed $name end, eval_str = '".trim($this->message[$pos]["eval_str"])."' and children = ".$this->message[$pos]["children"]);
|
||||
}
|
||||
|
||||
// element content handler
|
||||
function character_data($parser, $data)
|
||||
{
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
$this->message[$pos]["cdata"] .= $data;
|
||||
//$this->debug("parsed ".$this->message[$pos]["name"]." cdata, eval = '$this->eval_str'");
|
||||
}
|
||||
|
||||
// default handler
|
||||
function default_handler($parser, $data)
|
||||
{
|
||||
//$this->debug("DEFAULT HANDLER: $data");
|
||||
}
|
||||
|
||||
// function to get fault code
|
||||
function fault()
|
||||
{
|
||||
if($this->fault)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// have this return a soap_val object
|
||||
function get_response()
|
||||
{
|
||||
$this->debug("eval()ing eval_str: $this->eval_str");
|
||||
@eval("$this->eval_str");
|
||||
if($response)
|
||||
{
|
||||
$this->debug("successfully eval'd msg");
|
||||
return $response;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug("ERROR: did not successfully eval the msg");
|
||||
$this->fault = true;
|
||||
return CreateObject('phpgwapi.soapval',
|
||||
"Fault",
|
||||
"struct",
|
||||
array(
|
||||
CreateObject('phpgwapi.soapval',
|
||||
"faultcode",
|
||||
"string",
|
||||
"SOAP-ENV:Server"
|
||||
),
|
||||
CreateObject('phpgwapi.soapval',
|
||||
"faultstring",
|
||||
"string",
|
||||
"couldn't eval \"$this->eval_str\""
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function debug($string)
|
||||
{
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$this->debug_str .= "$string\n";
|
||||
}
|
||||
}
|
||||
|
||||
function decode_entities($text)
|
||||
{
|
||||
foreach($this->entities as $entity => $encoded)
|
||||
{
|
||||
$text = str_replace($encoded,$entity,$text);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
?>
|
360
phpgwapi/inc/class.soap_server.inc.php
Normal file
360
phpgwapi/inc/class.soap_server.inc.php
Normal file
@ -0,0 +1,360 @@
|
||||
<?php
|
||||
// SOAP server class
|
||||
|
||||
// for example usage, see the test_server.php file.
|
||||
|
||||
class soap_server
|
||||
{
|
||||
function soap_server($data,$serviceNow=False)
|
||||
{
|
||||
// create empty dispatch map
|
||||
$this->dispatch_map = array();
|
||||
$this->debug_flag = False;
|
||||
$this->debug_str = '';
|
||||
$this->headers = '';
|
||||
$this->request = '';
|
||||
$this->result = 'successful';
|
||||
$this->fault = false;
|
||||
$this->fault_code = '';
|
||||
$this->fault_str = '';
|
||||
$this->fault_actor = '';
|
||||
|
||||
if($serviceNow == 1)
|
||||
{
|
||||
$this->service($data);
|
||||
}
|
||||
}
|
||||
|
||||
// parses request and posts response
|
||||
function service($data)
|
||||
{
|
||||
// $response is a soap_msg object
|
||||
$response = $this->parseRequest($data);
|
||||
$this->debug("parsed request and got an object of this class '".get_class($response)."'");
|
||||
$this->debug("server sending...");
|
||||
// pass along the debug string
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$response->debug($this->debug_str);
|
||||
}
|
||||
$payload = $response->serialize();
|
||||
// print headers
|
||||
if($this->fault)
|
||||
{
|
||||
$header[] = "HTTP/1.0 500 Internal Server Error\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$header[] = "HTTP/1.0 200 OK\r\n";
|
||||
$header[] = "Status: 200\r\n";
|
||||
}
|
||||
$header[] = "Server: SOAPx4 Server v0.344359s\r\n";
|
||||
$header[] = "Connection: Close\r\n";
|
||||
$header[] = "Content-Type: text/xml; charset=UTF-8\r\n";
|
||||
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
|
||||
reset($header);
|
||||
foreach($header as $hdr)
|
||||
{
|
||||
header($hdr);
|
||||
}
|
||||
print $payload;
|
||||
}
|
||||
|
||||
function parseRequest($data="")
|
||||
{
|
||||
global $HTTP_SERVER_VARS;
|
||||
|
||||
$this->debug("entering parseRequest() on ".date("H:i Y-m-d"));
|
||||
$request_uri = $HTTP_SERVER_VARS["REQUEST_URI"];
|
||||
$this->debug("request uri: $request_uri");
|
||||
// get headers
|
||||
$headers_array = getallheaders();
|
||||
foreach($headers_array as $k=>$v)
|
||||
{
|
||||
$dump .= "$k: $v\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n".$data;
|
||||
$this->headers = $headers_array;
|
||||
$this->request = $dump;
|
||||
|
||||
// get SOAPAction header -> methodname
|
||||
if($headers_array["SOAPAction"])
|
||||
{
|
||||
$action = str_replace('"','',$headers_array["SOAPAction"]);
|
||||
if(ereg("^urn:",$action))
|
||||
{
|
||||
$this->service = substr($action,4);
|
||||
}
|
||||
elseif(ereg(".php",$action))
|
||||
{
|
||||
$this->service = ereg_replace('"|/','',substr(strrchr($action,".php"),4,strlen(strrchr($action,"/"))));
|
||||
}
|
||||
$this->debug("got service: $this->service");
|
||||
}
|
||||
else
|
||||
{
|
||||
// throw a fault if no soapaction
|
||||
$this->debug("ERROR: no SOAPAction header found");
|
||||
}
|
||||
// NOTE:::: throw a fault for no/bad soapaction here?
|
||||
|
||||
// parse response, get soap parser obj
|
||||
$parser = CreateObject('phpgwapi.soap_parser',$data);
|
||||
// get/set methodname
|
||||
$this->methodname = $parser->root_struct_name;
|
||||
$this->debug("method name: $this->methodname");
|
||||
|
||||
// does method exist?
|
||||
if(function_exists($this->methodname))
|
||||
{
|
||||
$this->debug("method '$this->methodname' exists");
|
||||
}
|
||||
else
|
||||
{
|
||||
// "method not found" fault here
|
||||
$this->debug("method '$this->methodname' not found!");
|
||||
$this->result = "fault: method not found";
|
||||
$this->make_fault("Server","method '$this->methodname' not defined in service '$this->service'");
|
||||
return $this->fault();
|
||||
}
|
||||
// if fault occurred during message parsing
|
||||
if($parser->fault())
|
||||
{
|
||||
// parser debug
|
||||
$this->debug($parser->debug_str);
|
||||
$this->result = "fault: error in msg parsing or eval";
|
||||
$this->make_fault("Server","error in msg parsing or eval:\n".$parser->get_response());
|
||||
// return soapresp
|
||||
return $this->fault();
|
||||
// else successfully parsed request into soapval object
|
||||
}
|
||||
else
|
||||
{
|
||||
// get eval_str
|
||||
$this->debug("calling parser->get_response()");
|
||||
// evaluate it, getting back a soapval object
|
||||
if(!$request_val = $parser->get_response())
|
||||
{
|
||||
return $this->fault();
|
||||
}
|
||||
// parser debug
|
||||
$this->debug($parser->debug_str);
|
||||
if(get_class($request_val) == "soapval")
|
||||
{
|
||||
// verify that soapval objects in request match the methods signature
|
||||
if($this->verify_method($request_val))
|
||||
{
|
||||
$this->debug("request data - name: $request_val->name, type: $request_val->type, value: $request_val->value");
|
||||
if($this->input_value)
|
||||
{// decode the soapval object, and pass resulting values to the requested method
|
||||
if(!$request_data = $request_val->decode())
|
||||
{
|
||||
$this->make_fault("Server","Unable to decode response from soapval object into native php type.");
|
||||
return $this->fault();
|
||||
}
|
||||
$this->debug("request data: $request_data");
|
||||
}
|
||||
|
||||
// if there are return values
|
||||
if($this->return_type = $this->get_return_type())
|
||||
{
|
||||
$this->debug("got return type: '$this->return_type'");
|
||||
// if there are parameters to pass
|
||||
if($request_data)
|
||||
{
|
||||
// call method with parameters
|
||||
$this->debug("about to call method '$this->methodname'");
|
||||
if(!$method_response = call_user_func_array("$this->methodname",$request_data))
|
||||
{
|
||||
$this->make_fault("Server","Method call failed for '$this->methodname' with params: ".join(",",$request_data));
|
||||
return $this->fault();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// call method w/ no parameters
|
||||
$this->debug("about to call method '$this->methodname'");
|
||||
if(!$method_response = call_user_func("$this->methodname"))
|
||||
{
|
||||
$this->make_fault("Server","Method call failed for '$this->methodname' with no params");
|
||||
return $this->fault();
|
||||
}
|
||||
}
|
||||
// no return values
|
||||
}
|
||||
else
|
||||
{
|
||||
if($request_data)
|
||||
{
|
||||
// call method with parameters
|
||||
$this->debug("about to call method '$this->methodname'");
|
||||
call_user_func_array("$this->methodname",$request_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call method w/ no parameters
|
||||
$this->debug("about to call method '$this->methodname'");
|
||||
call_user_func("$this->methodname",$request_data);
|
||||
}
|
||||
}
|
||||
|
||||
// create soap_val object w/ return values from method, use method signature to determine type
|
||||
if(get_class($method_response) != "soapval")
|
||||
{
|
||||
$return_val = CreateObject('phpgwapi.soapval',$this->methodname,$this->return_type,$method_response);
|
||||
}
|
||||
else
|
||||
{
|
||||
$return_val = $method_response;
|
||||
}
|
||||
$this->debug($return_val->debug_str);
|
||||
// response object is a soap_msg object
|
||||
$return_msg = CreateObject('phpgwapi.soapmsg',$this->methodname."Response",array($return_val),$this->service);
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$return_msg->debug_flag = true;
|
||||
}
|
||||
$this->result = "successful";
|
||||
return $return_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// debug
|
||||
$this->debug("ERROR: request not verified against method signature");
|
||||
$this->result = "fault: request failed validation against method signature";
|
||||
// return soapresp
|
||||
return $this->fault();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// debug
|
||||
$this->debug("ERROR: parser did not return soapval object: $request_val ".get_class($request_val));
|
||||
$this->result = "fault: parser did not return soapval object: $request_val";
|
||||
// return fault
|
||||
$this->make_fault("Server","parser did not return soapval object: $request_val");
|
||||
return $this->fault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function verify_method($request)
|
||||
{
|
||||
//return true;
|
||||
$this->debug("entered verify_method() w/ request name: ".$request->name);
|
||||
$params = $request->value;
|
||||
// if there are input parameters required...
|
||||
if($sig = $this->dispatch_map[$this->methodname]["in"])
|
||||
{
|
||||
$this->input_value = count($sig);
|
||||
if(is_array($params))
|
||||
{
|
||||
$this->debug("entered verify_method() with ".count($params)." parameters");
|
||||
foreach($params as $v)
|
||||
{
|
||||
$this->debug("param '$v->name' of type '$v->type'");
|
||||
}
|
||||
// validate the number of parameters
|
||||
if(count($params) == count($sig))
|
||||
{
|
||||
$this->debug("got correct number of parameters: ".count($sig));
|
||||
// make array of param types
|
||||
foreach($params as $param)
|
||||
{
|
||||
$p[] = strtolower($param->type);
|
||||
}
|
||||
// validate each param's type
|
||||
for($i=0; $i < count($p); $i++)
|
||||
{
|
||||
// type not match
|
||||
if(strtolower($sig[$i]) != strtolower($p[$i]))
|
||||
{
|
||||
$this->debug("mismatched parameter types: $sig[$i] != $p[$i]");
|
||||
$this->make_fault("Client","soap request contained mismatching parameters of name $v->name had type $p[$i], which did not match signature's type: $sig[$i]");
|
||||
return false;
|
||||
}
|
||||
$this->debug("parameter type match: $sig[$i] = $p[$i]");
|
||||
}
|
||||
return true;
|
||||
// oops, wrong number of paramss
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug("oops, wrong number of parameter!");
|
||||
$this->make_fault("Client","soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig)." and request provided ".count($params));
|
||||
return false;
|
||||
}
|
||||
// oops, no params...
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->debug("oops, no parameters sent! Method '$this->methodname' requires ".count($sig)." input parameters!");
|
||||
$this->make_fault("Client","soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig)." parameters, and request provided none");
|
||||
return false;
|
||||
}
|
||||
// no params
|
||||
}
|
||||
elseif( (count($params)==0) && (count($sig) <= 1) )
|
||||
{
|
||||
$this->input_values = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//$this->debug("well, request passed parameters to a method that requires none?");
|
||||
//$this->make_fault("Client","method '$this->methodname' requires no parameters. The request passed in ".count($params).": ".@implode(" param: ",$params) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// get string return type from dispatch map
|
||||
function get_return_type()
|
||||
{
|
||||
if(count($this->dispatch_map[$this->methodname]["out"]) >= 1)
|
||||
{
|
||||
$type = array_shift($this->dispatch_map[$this->methodname]["out"]);
|
||||
$this->debug("got return type from dispatch map: '$type'");
|
||||
return $type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// dbg
|
||||
function debug($string)
|
||||
{
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$this->debug_str .= "$string\n";
|
||||
}
|
||||
}
|
||||
|
||||
// add a method to the dispatch map
|
||||
function add_to_map($methodname,$in,$out)
|
||||
{
|
||||
$this->dispatch_map[$methodname]["in"] = $in;
|
||||
$this->dispatch_map[$methodname]["out"] = $out;
|
||||
}
|
||||
|
||||
// set up a fault
|
||||
function fault()
|
||||
{
|
||||
return CreateObject('phpgwapi.soapmsg',
|
||||
"Fault",
|
||||
array(
|
||||
"faultcode" => $this->fault_code,
|
||||
"faultstring" => $this->fault_str,
|
||||
"faultactor" => $this->fault_actor,
|
||||
"faultdetail" => $this->fault_detail.$this->debug_str
|
||||
),
|
||||
"http://schemas.xmlphpgwapi.org/soap/envelope/"
|
||||
);
|
||||
}
|
||||
|
||||
function make_fault($fault_code,$fault_string)
|
||||
{
|
||||
$this->fault_code = $fault_code;
|
||||
$this->fault_str = $fault_string;
|
||||
$this->fault = true;
|
||||
}
|
||||
}
|
||||
?>
|
151
phpgwapi/inc/class.soapclient.inc.php
Normal file
151
phpgwapi/inc/class.soapclient.inc.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/* soapx4 high level class
|
||||
|
||||
usage:
|
||||
|
||||
// instantiate client with server info
|
||||
$soapclient = new soapclient( string path [ ,boolean wsdl] );
|
||||
|
||||
// call method, get results
|
||||
echo $soapclient->call( string methodname [ ,array parameters] );
|
||||
|
||||
// bye bye client
|
||||
unset($soapclient);
|
||||
|
||||
*/
|
||||
|
||||
class soapclient
|
||||
{
|
||||
function soapclient($endpoint,$wsdl=False,$portName=False)
|
||||
{
|
||||
$this->debug_flag = False;
|
||||
$this->endpoint = $endpoint;
|
||||
$this->portName = False;
|
||||
|
||||
// make values
|
||||
if($wsdl)
|
||||
{
|
||||
$this->endpointType = 'wsdl';
|
||||
if($portName)
|
||||
{
|
||||
$this->portName = $portName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function call($method,$params=array(),$namespace=false,$soapAction=false)
|
||||
{
|
||||
if($this->endpointType == 'wsdl')
|
||||
{
|
||||
// instantiate wsdl class
|
||||
$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();
|
||||
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>";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
135
phpgwapi/inc/class.soapmsg.inc.php
Normal file
135
phpgwapi/inc/class.soapmsg.inc.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
// soap message class
|
||||
class soapmsg
|
||||
{
|
||||
// params is an array of soapval objects
|
||||
function soapmsg($method,$params,$method_namespace='http://testuri.org',$new_namespaces=False)
|
||||
{
|
||||
// globalize method namespace
|
||||
global $methodNamespace;
|
||||
$methodNamespace = $method_namespace;
|
||||
// make method struct
|
||||
$this->value = CreateObject('phpgwapi.soapval',$method,"struct",$params,$method_namespace);
|
||||
if(is_array($new_namespaces))
|
||||
{
|
||||
global $namespaces;
|
||||
$i = count($namespaces);
|
||||
foreach($new_namespaces as $v)
|
||||
{
|
||||
$namespaces[$v] = "ns".$i++;
|
||||
}
|
||||
$this->namespaces = $namespaces;
|
||||
}
|
||||
$this->payload = '';
|
||||
$this->debug_flag = False;
|
||||
$this->debug_str = "entering soapmsg() with soapval ".$this->value->name."\n";
|
||||
}
|
||||
|
||||
function make_envelope($payload)
|
||||
{
|
||||
global $namespaces;
|
||||
foreach($namespaces as $k => $v)
|
||||
{
|
||||
$ns_string .= " xmlns:$v=\"$k\"";
|
||||
}
|
||||
return "<SOAP-ENV:Envelope $ns_string SOAP-ENV:encodingStyle=\"http://schemas.xmlphpgwapi.org/soap/encoding/\">\n"
|
||||
. $payload . "</SOAP-ENV:Envelope>\n";
|
||||
}
|
||||
|
||||
function make_body($payload)
|
||||
{
|
||||
return "<SOAP-ENV:Body>\n" . $payload . "</SOAP-ENV:Body>\n";
|
||||
}
|
||||
|
||||
function createPayload()
|
||||
{
|
||||
$value = $this->value;
|
||||
$payload = $this->make_envelope($this->make_body($value->serialize()));
|
||||
$this->debug($value->debug_str);
|
||||
$payload = "<?xml version=\"1.0\"?>\n".$payload;
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$payload .= $this->serializeDebug();
|
||||
}
|
||||
$this->payload = str_replace("\n","\r\n", $payload);
|
||||
}
|
||||
|
||||
function serialize()
|
||||
{
|
||||
if($this->payload == '')
|
||||
{
|
||||
$this->createPayload();
|
||||
return $this->payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
}
|
||||
|
||||
// returns a soapval object
|
||||
function parseResponse($data)
|
||||
{
|
||||
$this->debug("Entering parseResponse()");
|
||||
//$this->debug(" w/ data $data");
|
||||
// get rid of headers here
|
||||
$clean_data = ereg_replace("\r\n","\n", $data);
|
||||
if(ereg("^.*\r\n\r\n",$data))
|
||||
{
|
||||
$this->debug("getting rid of headers, stringlen: ".strlen($data));
|
||||
$clean_data = ereg_replace("^.*\r\n\r\n","", $data);
|
||||
$this->debug("cleaned data, stringlen: ".strlen($clean_data));
|
||||
}
|
||||
elseif(ereg("^.*\n\n",$data))
|
||||
{
|
||||
$this->debug("getting rid of headers, stringlen: ".strlen($data));
|
||||
$clean_data = ereg_replace("^.*\n\n","", $data);
|
||||
$this->debug("cleaned data, stringlen: ".strlen($clean_data));
|
||||
}
|
||||
// if response is a proper http response, and is not a 200
|
||||
if(ereg("^HTTP",$clean_data) && !ereg("200$", $clean_data))
|
||||
{
|
||||
// get error data
|
||||
$errstr = substr($clean_data, 0, strpos($clean_data, "\n")-1);
|
||||
// return fault
|
||||
return CreateObject('phpgwapi.soapval',
|
||||
"fault",
|
||||
"SOAPStruct",
|
||||
array(
|
||||
CreateObject('phpgwapi.soapval',"faultcode","string","SOAP-MSG"),
|
||||
CreateObject('phpgwapi.soapval',"faultstring","string","HTTP error")
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->debug("about to create parser instance w/ data: $clean_data");
|
||||
// parse response
|
||||
$response = CreateObject('phpgwapi.soap_parser',$clean_data);
|
||||
// return array of parameters
|
||||
$ret = $response->get_response();
|
||||
$this->debug($response->debug_str);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// dbg
|
||||
function debug($string)
|
||||
{
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$this->debug_str .= "$string\n";
|
||||
}
|
||||
}
|
||||
|
||||
// preps debug data for encoding into soapmsg
|
||||
function serializeDebug()
|
||||
{
|
||||
if($this->debug_flag)
|
||||
{
|
||||
return "<!-- DEBUG INFO:\n".$this->debug_str."-->\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
416
phpgwapi/inc/class.soapval.inc.php
Normal file
416
phpgwapi/inc/class.soapval.inc.php
Normal file
@ -0,0 +1,416 @@
|
||||
<?php
|
||||
// soap value object
|
||||
class soapval
|
||||
{
|
||||
function soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False)
|
||||
{
|
||||
global $soapTypes, $typemap, $namespaces, $methodNamespace;
|
||||
|
||||
// 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 = $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($namespaces[$namespace]))
|
||||
{
|
||||
$namespaces[$namespace] = "ns".(count($namespaces)+1);
|
||||
}
|
||||
$this->prefix = $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($namespaces[$type_namespace]))
|
||||
{
|
||||
$namespaces[$type_namespace] = "ns".(count($namespaces)+1);
|
||||
}
|
||||
$this->type_prefix = $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 = $namespaces[$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 == $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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)))
|
||||
{
|
||||
$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))
|
||||
{
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// serialize
|
||||
function serialize()
|
||||
{
|
||||
return $this->serializeval($this);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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 $namespaces,$soapTypes,$typemap;
|
||||
|
||||
foreach($typemap as $namespace => $types)
|
||||
{
|
||||
if(in_array($type,$types))
|
||||
{
|
||||
return $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";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
275
phpgwapi/inc/class.wsdl.inc.php
Normal file
275
phpgwapi/inc/class.wsdl.inc.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
this is a class that loads a wsdl file and makes it's data available to an application
|
||||
it should provide methods that allow both client and server usage of it
|
||||
|
||||
also should have methods for creating a wsdl file from scratch and
|
||||
serializing wsdl into valid markup
|
||||
|
||||
*/
|
||||
|
||||
class wsdl
|
||||
{
|
||||
// constructor
|
||||
function wsdl($wsdl=false)
|
||||
{
|
||||
// define internal arrays of bindings, ports, operations, messages, etc.
|
||||
$this->complexTypes = array();
|
||||
$this->messages = array();
|
||||
$this->currentMessage;
|
||||
$this->portOperations = array();
|
||||
$this->currentOperation;
|
||||
$this->portTypes = array();
|
||||
$this->currentPortType;
|
||||
$this->bindings = array();
|
||||
$this->currentBinding;
|
||||
// debug switch
|
||||
$this->debug_flag = false;
|
||||
// parser vars
|
||||
$this->parser;
|
||||
$this->position;
|
||||
$this->depth;
|
||||
$this->depth_array = array();
|
||||
|
||||
if($wsdl == "-1")
|
||||
{
|
||||
$wsdl=false;
|
||||
}
|
||||
// Check whether content has been read.
|
||||
if($wsdl)
|
||||
{
|
||||
$wsdl_string = join("",file($wsdl));
|
||||
// Create an XML parser.
|
||||
$this->parser = xml_parser_create();
|
||||
// Set the options for parsing the XML data.
|
||||
//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
|
||||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
// Set the object for the parser.
|
||||
xml_set_object($this->parser, &$this);
|
||||
// Set the element handlers for the parser.
|
||||
xml_set_element_handler($this->parser, "start_element","end_element");
|
||||
xml_set_character_data_handler($this->parser,"character_data");
|
||||
//xml_set_default_handler($this->parser, "default_handler");
|
||||
|
||||
// Parse the XML file.
|
||||
if(!xml_parse($this->parser,$wsdl_string,true))
|
||||
{
|
||||
// Display an error message.
|
||||
$this->debug(sprintf("XML error on line %d: %s",
|
||||
xml_get_current_line_number($this->parser),
|
||||
xml_error_string(xml_get_error_code($this->parser))));
|
||||
$this->fault = true;
|
||||
}
|
||||
xml_parser_free($this->parser);
|
||||
}
|
||||
}
|
||||
|
||||
// start-element handler
|
||||
function start_element($parser, $name, $attrs)
|
||||
{
|
||||
// position in the total number of elements, starting from 0
|
||||
$pos = $this->position++;
|
||||
$depth = $this->depth++;
|
||||
// set self as current value for this depth
|
||||
$this->depth_array[$depth] = $pos;
|
||||
|
||||
// find status, register data
|
||||
switch($this->status)
|
||||
{
|
||||
case "types":
|
||||
switch($name)
|
||||
{
|
||||
case "schema":
|
||||
$this->schema = true;
|
||||
break;
|
||||
case "complexType":
|
||||
$this->currentElement = $attrs["name"];
|
||||
$this->schemaStatus = "complexType";
|
||||
break;
|
||||
case "element":
|
||||
$this->complexTypes[$this->currentElement]["elements"][$attrs["name"]] = $attrs;
|
||||
break;
|
||||
case "complexContent":
|
||||
|
||||
break;
|
||||
case "restriction":
|
||||
$this->complexTypes[$this->currentElement]["restrictionBase"] = $attrs["base"];
|
||||
break;
|
||||
case "sequence":
|
||||
$this->complexTypes[$this->currentElement]["order"] = "sequence";
|
||||
break;
|
||||
case "all":
|
||||
$this->complexTypes[$this->currentElement]["order"] = "all";
|
||||
break;
|
||||
case "attribute":
|
||||
if($attrs["ref"]){
|
||||
$this->complexTypes[$this->currentElement]["attrs"][$attrs["ref"]] = $attrs;
|
||||
} elseif($attrs["name"]){
|
||||
$this->complexTypes[$this->currentElement]["attrs"][$attrs["name"]] = $attrs;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "message":
|
||||
if($name == "part")
|
||||
{
|
||||
$this->messages[$this->currentMessage][$attrs["name"]] = $attrs["type"];
|
||||
}
|
||||
break;
|
||||
case "portType":
|
||||
switch($name)
|
||||
{
|
||||
case "operation":
|
||||
$this->currentOperation = $attrs["name"];
|
||||
$this->portTypes[$this->currentPortType][$attrs["name"]] = $attrs["parameterOrder"];
|
||||
break;
|
||||
default:
|
||||
$this->portOperations[$this->currentOperation][$name]= $attrs;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "binding":
|
||||
switch($name)
|
||||
{
|
||||
case "soap:binding":
|
||||
$this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding],$attrs);
|
||||
break;
|
||||
case "operation":
|
||||
$this->currentOperation = $attrs["name"];
|
||||
$this->bindings[$this->currentBinding]["operations"][$attrs["name"]] = array();
|
||||
break;
|
||||
case "soap:operation":
|
||||
$this->bindings[$this->currentBinding]["operations"][$this->currentOperation]["soapAction"] = $attrs["soapAction"];
|
||||
break;
|
||||
case "input":
|
||||
$this->opStatus = "input";
|
||||
case "soap:body":
|
||||
$this->bindings[$this->currentBinding]["operations"][$this->currentOperation][$this->opStatus] = $attrs;
|
||||
break;
|
||||
case "output":
|
||||
$this->opStatus = "output";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "service":
|
||||
switch($name)
|
||||
{
|
||||
case "port":
|
||||
$this->currentPort = $attrs["name"];
|
||||
$this->ports[$attrs["name"]] = $attrs;
|
||||
break;
|
||||
case "soap:address":
|
||||
$this->ports[$this->currentPort]["location"] = $attrs["location"];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// set status
|
||||
switch($name)
|
||||
{
|
||||
case "types":
|
||||
$this->status = "types";
|
||||
break;
|
||||
case "message":
|
||||
$this->status = "message";
|
||||
$this->messages[$attrs["name"]] = array();
|
||||
$this->currentMessage = $attrs["name"];
|
||||
break;
|
||||
case "portType":
|
||||
$this->status = "portType";
|
||||
$this->portTypes[$attrs["name"]] = array();
|
||||
$this->currentPortType = $attrs["name"];
|
||||
break;
|
||||
case "binding":
|
||||
$this->status = "binding";
|
||||
$this->currentBinding = $attrs["name"];
|
||||
$this->bindings[$attrs["name"]]["type"] = $attrs["type"];
|
||||
break;
|
||||
case "service":
|
||||
$this->status = "service";
|
||||
break;
|
||||
}
|
||||
// get element prefix
|
||||
if(ereg(":",$name))
|
||||
{
|
||||
$prefix = substr($name,0,strpos($name,":"));
|
||||
}
|
||||
}
|
||||
|
||||
function getEndpoint($portName)
|
||||
{
|
||||
if($endpoint = $this->ports[$portName]["location"])
|
||||
{
|
||||
return $endpoint;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getPortName($operation)
|
||||
{
|
||||
foreach($this->ports as $port => $portAttrs)
|
||||
{
|
||||
$binding = substr($portAttrs["binding"],4);
|
||||
foreach($this->bindings[$binding]["operations"] as $op => $opAttrs)
|
||||
{
|
||||
if($op == $operation)
|
||||
{
|
||||
return $port;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSoapAction($portName,$operation)
|
||||
{
|
||||
if($binding = substr($this->ports[$portName]["binding"],4))
|
||||
{
|
||||
if($soapAction = $this->bindings[$binding]["operations"][$operation]["soapAction"])
|
||||
{
|
||||
return $soapAction;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getNamespace($portName,$operation)
|
||||
{
|
||||
if($binding = substr($this->ports[$portName]["binding"],4))
|
||||
{
|
||||
//$this->debug("looking for namespace using binding '$binding', port '$portName', operation '$operation'");
|
||||
if($namespace = $this->bindings[$binding]["operations"][$operation]["input"]["namespace"])
|
||||
{
|
||||
return $namespace;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// end-element handler
|
||||
function end_element($parser, $name)
|
||||
{
|
||||
// position of current element is equal to the last value left in depth_array for my depth
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
// bring depth down a notch
|
||||
$this->depth--;
|
||||
}
|
||||
|
||||
// element content handler
|
||||
function character_data($parser, $data)
|
||||
{
|
||||
$pos = $this->depth_array[$this->depth];
|
||||
$this->message[$pos]["cdata"] .= $data;
|
||||
}
|
||||
|
||||
function debug($string)
|
||||
{
|
||||
if($this->debug_flag)
|
||||
{
|
||||
$this->debug_str .= "$string\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user