Formatting, add Id tags

This commit is contained in:
Miles Lott 2001-08-18 14:37:52 +00:00
parent d247b25603
commit 927fb55c0a
6 changed files with 1339 additions and 1325 deletions

View File

@ -1,5 +1,5 @@
<?php <?php
/* /*
SOAPx4 SOAPx4
by Dietrich Ayala (C) 2001 dietrich@ganx4.com by Dietrich Ayala (C) 2001 dietrich@ganx4.com
@ -13,7 +13,7 @@
SOAP for PHP SOAP for PHP
by Victor Zou (C) 2000-2001 <victor@gigaideas.com.cn> by Victor Zou (C) 2000-2001 <victor@gigaideas.com.cn>
*/ */
/* changelog: /* changelog:
2001-07-04 2001-07-04
@ -30,6 +30,9 @@
// $path can be a complete endpoint url, with the other parameters left blank: // $path can be a complete endpoint url, with the other parameters left blank:
// $soap_client = new soap_client("http://path/to/soap/server"); // $soap_client = new soap_client("http://path/to/soap/server");
/* $Id$ */
class soap_client class soap_client
{ {
function soap_client($path,$server=False,$port=False) function soap_client($path,$server=False,$port=False)
@ -40,30 +43,30 @@
$this->errno; $this->errno;
$this->errstring; $this->errstring;
$this->debug_flag = False; $this->debug_flag = False;
$this->debug_str = ""; $this->debug_str = '';
$this->username = ""; $this->username = '';
$this->password = ""; $this->password = '';
$this->action = ""; $this->action = '';
$this->incoming_payload = ""; $this->incoming_payload = '';
$this->outgoing_payload = ""; $this->outgoing_payload = '';
$this->response = ""; $this->response = '';
$this->action = ""; $this->action = '';
// endpoint mangling // endpoint mangling
if(ereg("^http://",$path)) if(ereg("^http://",$path))
{ {
$path = str_replace("http://","",$path); $path = str_replace('http://','',$path);
$this->path = strstr($path,"/"); $this->path = strstr($path,'/');
$this->debug("path = $this->path"); $this->debug("path = $this->path");
if(ereg(":",$path)) if(ereg(':',$path))
{ {
$this->server = substr($path,0,strpos($path,":")); $this->server = substr($path,0,strpos($path,':'));
$this->port = substr(strstr($path,":"),1); $this->port = substr(strstr($path,':'),1);
$this->port = substr($this->port,0,strpos($this->port,"/")); $this->port = substr($this->port,0,strpos($this->port,'/'));
} }
else else
{ {
$this->server = substr($path,0,strpos($path,"/")); $this->server = substr($path,0,strpos($path,'/'));
} }
} }
if($port) if($port)
@ -132,19 +135,21 @@
} }
$soap_data = $msg->serialize(); $soap_data = $msg->serialize();
$this->outgoing_payload = "POST ". $this->outgoing_payload = 'POST '
$this->path. . $this->path
" HTTP/1.0\r\n". . " HTTP/1.0\r\n"
"User-Agent: SOAPx4 v0.13492\r\n". . 'User-Agent: phpGroupware/' . $cliversion . '(PHP) ' . "\r\n"
"Host: ".$this->server . "\r\n". . 'X-PHPGW-Server: ' . $this->server . "\r\n"
$credentials. . 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
"Content-Type: text/xml\r\nContent-Length: ".strlen($soap_data)."\r\n". . 'Host: '.$this->server . "\r\n"
"SOAPAction: \"$this->action\""."\r\n\r\n". . $credentials
$soap_data; . "Content-Type: text/xml\r\nContent-Length: " . strlen($soap_data) . "\r\n"
. 'SOAPAction: "' . $this->action . '"' . "\r\n\r\n"
. $soap_data;
// send // send
if(!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) if(!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload)))
{ {
$this->debug("Write error"); $this->debug('Write error');
} }
// get reponse // get reponse
@ -181,15 +186,17 @@
} }
$soap_data = $msg->serialize(); $soap_data = $msg->serialize();
$this->outgoing_payload = "POST ". $this->outgoing_payload = 'POST '
$this->path. . $this->path
" HTTP/1.0\r\n". . " HTTP/1.0\r\n"
"User-Agent: SOAPx4 v0.13492\r\n". . 'User-Agent: phpGroupware/' . $cliversion . '(PHP) ' . "\r\n"
"Host: ".$this->server . "\r\n". . 'X-PHPGW-Server: ' . $this->server . "\r\n"
$credentials. . 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
"Content-Type: text/xml\r\nContent-Length: ".strlen($soap_data)."\r\n". . 'Host: ' . $this->server . "\r\n"
"SOAPAction: \"$this->action\""."\r\n\r\n". . $credentials
$soap_data; . "Content-Type: text/xml\r\nContent-Length: " . strlen($soap_data) . "\r\n"
. 'SOAPAction: "' . $this->action . '"' . "\r\n\r\n"
. $soap_data;
// send // send
$ch = curl_init(); $ch = curl_init();

View File

@ -1,373 +1,375 @@
<?php <?php
class soap_parser /* $Id$ */
{
function soap_parser($xml='',$encoding='UTF-8') class soap_parser
{ {
global $soapTypes; function soap_parser($xml='',$encoding='UTF-8')
$this->soapTypes = $soapTypes;
$this->xml = $xml;
$this->xml_encoding = $encoding;
$this->root_struct = "";
// options: envelope,header,body,method
// determines where in the message we are (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 = True;
$this->debug_str = "";
$this->previous_element = "";
$this->entities = array (
"&" => "&amp;",
"<" => "&lt;",
">" => "&gt;",
"'" => "&apos;",
'"' => "&quot;"
);
// Check whether content has been read.
if(!empty($xml))
{ {
$this->debug("Entering soap_parser()"); global $soapTypes;
//$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. $this->soapTypes = $soapTypes;
if(!xml_parse($this->parser,$xml,true)) $this->xml = $xml;
$this->xml_encoding = $encoding;
$this->root_struct = "";
// options: envelope,header,body,method
// determines where in the message we are (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 = True;
$this->debug_str = '';
$this->previous_element = '';
$this->entities = array (
'&' => '&amp;',
'<' => '&lt;',
'>' => '&gt;',
"'" => '&apos;',
'"' => '&quot;'
);
// Check whether content has been read.
if(!empty($xml))
{ {
// Display an error message. $this->debug('Entering soap_parser()');
$this->debug(sprintf("XML error on line %d: %s", //$this->debug("DATA DUMP:\n\n$xml");
xml_get_current_line_number($this->parser), // Create an XML parser.
xml_error_string(xml_get_error_code($this->parser)))); $this->parser = xml_parser_create($this->xml_encoding);
$this->fault = true; // 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 else
{ {
// get final eval string $this->debug("xml was empty, didn't parse!");
$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 // loop through msg, building eval_str
function build_eval($pos) 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"]); $this->debug("inside build_eval() for $pos: ".$this->message[$pos]["name"]);
$children = explode("|",$this->message[$pos]["children"]); $eval_str = $this->message[$pos]['eval_str'];
$this->debug("it has ".count($children)." children"); // loop through children, building...
@reset($children); if($this->message[$pos]['children'] != '')
while(list($c,$child_pos) = @each($children))
/* foreach($children as $c => $child_pos) */
{ {
//$this->debug("child pos $child_pos: ".$this->message[$child_pos]["name"]); $this->debug('children string = '.$this->message[$pos]['children']);
if($this->message[$child_pos]["eval_str"] != "") $children = explode('|',$this->message[$pos]['children']);
$this->debug('it has '.count($children).' children');
@reset($children);
while(list($c,$child_pos) = @each($children))
/* foreach($children as $c => $child_pos) */
{ {
$this->debug("entering build_eval() for ".$this->message[$child_pos]["name"].", array pos $c, pos: $child_pos"); //$this->debug("child pos $child_pos: ".$this->message[$child_pos]["name"]);
$eval_str .= $this->build_eval($child_pos).", "; 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);
} }
$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;
} }
// add current node's eval_str
$eval_str .= $this->message[$pos]["end_eval_str"];
return $eval_str;
}
// start-element handler // start-element handler
function start_element($parser, $name, $attrs) function start_element($parser, $name, $attrs)
{ {
// position in a total number of elements, starting from 0 // position in a total number of elements, starting from 0
// update class level pos // update class level pos
$pos = $this->position++; $pos = $this->position++;
// and set mine // and set mine
$this->message[$pos]["pos"] = $pos; $this->message[$pos]['pos'] = $pos;
// parent/child/depth determinations // parent/child/depth determinations
// depth = how many levels removed from root? // depth = how many levels removed from root?
// set mine as current global depth and increment global depth value // set mine as current global depth and increment global depth value
$this->message[$pos]["depth"] = $this->depth++; $this->message[$pos]['depth'] = $this->depth++;
// else add self as child to whoever the current parent is // else add self as child to whoever the current parent is
if($pos != 0) if($pos != 0)
{ {
$this->message[$this->parent]["children"] .= "|$pos"; $this->message[$this->parent]['children'] .= "|$pos";
} }
// set my parent // set my parent
$this->message[$pos]["parent"] = $this->parent; $this->message[$pos]['parent'] = $this->parent;
// set self as current value for this depth // set self as current value for this depth
$this->depth_array[$this->depth] = $pos; $this->depth_array[$this->depth] = $pos;
// set self as current parent // set self as current parent
$this->parent = $pos; $this->parent = $pos;
// set status // set status
if(ereg(":Envelope$",$name)) if(ereg(":Envelope$",$name))
{ {
$this->status = "envelope"; $this->status = 'envelope';
} }
elseif(ereg(":Header$",$name)) elseif(ereg(":Header$",$name))
{ {
$this->status = "header"; $this->status = 'header';
} }
elseif(ereg(":Body$",$name)) elseif(ereg(":Body$",$name))
{ {
$this->status = "body"; $this->status = 'body';
// set method // set method
} }
elseif($this->status == "body") elseif($this->status == 'body')
{ {
$this->status = "method"; $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)) if(ereg(":",$name))
{ {
$this->root_struct_name = substr(strrchr($name,":"),1); $namespace = substr($name,0,strpos($name,':'));
$this->message[$pos]['namespace'] = $namespace;
$this->default_namespace = $namespace;
} }
else else
{ {
$this->root_struct_name = $name; $this->message[$pos]['namespace'] = $this->default_namespace;
} }
$this->root_struct = $pos; // loop through atts, logging ns and type declarations
$this->message[$pos]["type"] = "struct"; @reset($attrs);
} while (list($key,$value) = @each($attrs))
// set my status /* foreach($attrs as $key => $value) */
$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
@reset($attrs);
while (list($key,$value) = @each($attrs))
/* 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 ns declarations, add to class level array of valid namespaces
if($name == $this->root_struct_name) if(ereg('xmlns:',$key))
{ {
$this->methodNamespace = $value; $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);
} }
} }
// if it's a type declaration, set type
elseif($key == "xsi:type") // set type if available
if($type)
{ {
// then get attname and set $type $this->message[$pos]['type'] = $type;
$type = substr(strrchr($value,":"),1);
} }
// debug
//$this->debug("parsed $name start, eval = '".$this->message[$pos]["eval_str"]."'");
} }
// set type if available // end-element handler
if($type) function end_element($parser, $name)
{ {
$this->message[$pos]["type"] = $type; // 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--;
// debug // get type if not set already
//$this->debug("parsed $name start, eval = '".$this->message[$pos]["eval_str"]."'"); if($this->message[$pos]['type'] == '')
}
// 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"] != "")
if($this->message[$pos]["children"] != "")
{ {
$this->message[$pos]["type"] = "SOAPStruct"; // if($this->message[$pos]['cdata'] == '' && $this->message[$pos]['children'] != '')
if($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, type '".$this->message[$pos]['type']."'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 else
{ {
$this->message[$pos]["type"] = "string"; return false;
} }
} }
// set eval str start if it has a valid type and is inside the method // have this return a soap_val object
if($pos >= $this->root_struct) function get_response()
{ {
$this->message[$pos]["eval_str"] .= "\n CreateObject(\"phpgwapi.soapval\",\"".htmlspecialchars($name)."\", \"".$this->message[$pos]["type"]."\" "; $this->debug("eval()ing eval_str: $this->eval_str");
$this->message[$pos]["end_eval_str"] = ")"; @eval("$this->eval_str");
$this->message[$pos]["inval"] = "true"; if($response)
/*
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->debug("successfully eval'd msg");
$this->message[$pos]["end_eval_str"] .= " )"; return $response;
} }
} else
// 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"]."\""; $this->debug('ERROR: did not successfully eval the msg');
} $this->fault = true;
elseif($this->message[$pos]["type"] == "int" || $this->message[$pos]["type"] == "float" || $this->message[$pos]["type"] == "double") return CreateObject('phpgwapi.soapval',
{ 'Fault',
//$this->debug("adding cdata w/o quotes"); 'struct',
$this->message[$pos]["eval_str"] .= ", ".trim($this->message[$pos]["cdata"]); array(
} CreateObject('phpgwapi.soapval',
elseif(is_string($this->message[$pos]["cdata"])) 'faultcode',
{ 'string',
//$this->debug("adding cdata w/ quotes"); 'SOAP-ENV:Server'
$this->message[$pos]["eval_str"] .= ", \"".$this->message[$pos]["cdata"]."\""; ),
} CreateObject('phpgwapi.soapval',
} 'faultstring',
// if in the process of making a soap_val, close the parentheses and move on... 'string',
if($this->message[$pos]["inval"] == "true") "couldn't eval \"$this->eval_str\""
{ )
$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, type '".$this->message[$pos]["type"]."'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) function debug($string)
{
if($this->debug_flag)
{ {
$this->debug_str .= "$string\n"; if($this->debug_flag)
{
$this->debug_str .= "$string\n";
}
} }
}
function decode_entities($text) function decode_entities($text)
{
@reset($this->entities);
while(list($entity,$encoded) = @each($this->entities))
/* foreach($this->entities as $entity => $encoded) */
{ {
$text = str_replace($encoded,$entity,$text); @reset($this->entities);
while(list($entity,$encoded) = @each($this->entities))
/* foreach($this->entities as $entity => $encoded) */
{
$text = str_replace($encoded,$entity,$text);
}
return $text;
} }
return $text;
} }
}
?> ?>

View File

@ -1,443 +1,444 @@
<?php <?php
// SOAP server class // SOAP server class
// for example usage, see the test_server.php file. // for example usage, see the test_server.php file.
/* changelog: /* changelog:
2001-07-05 2001-07-05
- detection of character encoding in Content-Type header. server - detection of character encoding in Content-Type header. server
will now call the soap_parser object with the specified encoding will now call the soap_parser object with the specified encoding
- server will now return the Content-Type header with the sender's encoding type specified - server will now return the Content-Type header with the sender's encoding type specified
must still learn more bout encoding, and figure out what i have to do to be able to must still learn more bout encoding, and figure out what i have to do to be able to
make sure that my response is *actually* encoded correctly make sure that my response is *actually* encoded correctly
2001-07-21 2001-07-21
- force proper error reporting for windows compatibility - force proper error reporting for windows compatibility
2001-07-27 2001-07-27
- get_all_headers() check for windows compatibility - get_all_headers() check for windows compatibility
*/ */
/* $Id$ */
// make errors handle properly in windows // make errors handle properly in windows
error_reporting(2039); error_reporting(2039);
class soap_server class soap_server
{
function soap_server()
{ {
// create empty dispatch map function soap_server()
$this->dispatch_map = array();
$this->debug_flag = True;
$this->debug_str = '';
$this->headers = '';
$this->request = '';
$this->xml_encoding = 'UTF-8';
$this->fault = false;
$this->fault_code = '';
$this->fault_str = '';
$this->fault_actor = '';
// for logging interop results to db
$this->result = 'successful';
}
// parses request and posts response
function service($data)
{
// $response is a soap_msg object
$response = $this->parse_request($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); // create empty dispatch map
} $this->dispatch_map = array();
$payload = $response->serialize(); $this->debug_flag = True;
// print headers $this->debug_str = '';
if($this->fault) $this->headers = '';
{ $this->request = '';
$header[] = "HTTP/1.0 500 Internal Server Error\r\n"; $this->xml_encoding = 'UTF-8';
} $this->fault = false;
else $this->fault_code = '';
{ $this->fault_str = '';
$header[] = "HTTP/1.0 200 OK\r\n"; $this->fault_actor = '';
$header[] = "Status: 200\r\n"; // for logging interop results to db
} $this->result = 'successful';
$header[] = "Server: SOAPx4 Server v0.344359s\r\n";
$header[] = "Connection: Close\r\n";
$header[] = "Content-Type: text/xml; charset=$this->xml_encoding\r\n";
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
@reset($header);
while(list($null,$hdr) = @each($header))
/* foreach($header as $hdr) */
{
header($hdr);
}
print $payload;
}
function parse_request($data='')
{
global $HTTP_SERVER_VARS;
$this->debug("entering parse_request() on ".date("H:i Y-m-d"));
$request_uri = $HTTP_SERVER_VARS["REQUEST_URI"];
$this->debug("request uri: $request_uri");
// get headers
if(function_exists("getallheaders"))
{
$this->headers = getallheaders();
while(list($k,$v) = @each($this->headers))
/* foreach($this->headers as $k=>$v) */
{
$dump .= "$k: $v\r\n";
}
// get SOAPAction header
if($this->headers["SOAPAction"])
{
$this->SOAPAction = str_replace('"','',$this->headers["SOAPAction"]);
$this->service = $this->SOAPAction;
}
// get character encoding
if(ereg("=",$this->headers["Content-Type"]))
{
$this->xml_encoding = str_replace("\"","",substr(strstr($this->headers["Content-Type"],"="),1));
}
elseif(ereg("^text/xml",$this->headers["Content-Type"]))
{
$this->xml_encoding = "us-ascii";
}
$this->debug("got encoding: $this->xml_encoding");
}
$this->request = $dump."\r\n\r\n".$data;
// 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
{
/* phpgroupware customization - createobject based on methodname */
list($app,$class,$method) = explode('.',$this->methodname);
$obj = CreateObject(sprintf('%s.%s',$app,$class));
/*
// "method not found" fault here
$this->debug("method '$obj->method' not found!");
$this->result = "fault: method not found";
$this->make_fault("Server","method '$obj->method' not defined in service '$this->service'");
return $this->fault();
*/
} }
// if fault occurred during message parsing // parses request and posts response
if($parser->fault()) function service($data)
{ {
// parser debug // $response is a soap_msg object
$this->debug($parser->debug_str); $response = $this->parse_request($data);
$this->result = "fault: error in msg parsing or eval"; $this->debug("parsed request and got an object of this class '".get_class($response)."'");
$this->make_fault("Server","error in msg parsing or eval:\n".$parser->get_response()); $this->debug("server sending...");
// return soapresp // pass along the debug string
return $this->fault(); if($this->debug_flag)
// 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(); $response->debug($this->debug_str);
} }
// parser debug $payload = $response->serialize();
$this->debug($parser->debug_str); // print headers
if(get_class($request_val) == "soapval") if($this->fault)
{ {
if (is_object($obj)) $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=$this->xml_encoding\r\n";
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
@reset($header);
while(list($null,$hdr) = @each($header))
/* foreach($header as $hdr) */
{
header($hdr);
}
print $payload;
}
function parse_request($data='')
{
global $HTTP_SERVER_VARS;
$this->debug('entering parse_request() on '.date('H:i Y-m-d'));
$request_uri = $HTTP_SERVER_VARS['REQUEST_URI'];
$this->debug("request uri: $request_uri");
// get headers
if(function_exists('getallheaders'))
{
$this->headers = getallheaders();
while(list($k,$v) = @each($this->headers))
/* foreach($this->headers as $k=>$v) */
{ {
/* Add the function to the server map */ $dump .= "$k: $v\r\n";
$in = "array('" . implode("','",$obj->soap_functions[$method]['in']) . "')";
$out = "array('" . implode("','",$obj->soap_functions[$method]['out']) . "')";
$evalmap = "\$this->add_to_map(\$this->methodname,$in,$out);";
eval($evalmap);
} }
/* verify that soapval objects in request match the methods signature */ // get SOAPAction header
if($this->verify_method($request_val)) if($this->headers['SOAPAction'])
{ {
$this->debug("request data - name: $request_val->name, type: $request_val->type, value: $request_val->value"); $this->SOAPAction = str_replace('"','',$this->headers['SOAPAction']);
if($this->input_value) $this->service = $this->SOAPAction;
{ }
/* decode the soapval object, and pass resulting values to the requested method */ // get character encoding
if(!$request_data = $request_val->decode()) if(ereg("=",$this->headers['Content-Type']))
{ {
$this->make_fault("Server","Unable to decode response from soapval object into native php type."); $this->xml_encoding = str_replace("\"","",substr(strstr($this->headers["Content-Type"],"="),1));
return $this->fault(); }
} elseif(ereg("^text/xml",$this->headers['Content-Type']))
$this->debug("request data: $request_data"); {
} $this->xml_encoding = 'us-ascii';
}
$this->debug("got encoding: $this->xml_encoding");
}
$this->request = $dump."\r\n\r\n".$data;
// 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");
/* if there are return values */ // does method exist?
if($this->return_type = $this->get_return_type()) if(function_exists($this->methodname))
{
$this->debug("method '$this->methodname' exists");
}
else
{
/* phpgroupware customization - createobject based on methodname */
list($app,$class,$method) = explode('.',$this->methodname);
$obj = CreateObject(sprintf('%s.%s',$app,$class));
/*
// "method not found" fault here
$this->debug("method '$obj->method' not found!");
$this->result = "fault: method not found";
$this->make_fault("Server","method '$obj->method' 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')
{
if (is_object($obj))
{ {
$this->debug("got return type: '$this->return_type'"); /* Add the function to the server map */
/* if there are parameters to pass */ $in = "array('" . implode("','",$obj->soap_functions[$method]['in']) . "')";
if($request_data) $out = "array('" . implode("','",$obj->soap_functions[$method]['out']) . "')";
$evalmap = "\$this->add_to_map(\$this->methodname,$in,$out);";
eval($evalmap);
}
/* 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)
{ {
if (is_object($obj)) /* decode the soapval object, and pass resulting values to the requested method */
if(!$request_data = $request_val->decode())
{ {
$code = "\$method_response = call_user_method(\$method,\$obj,"; $this->make_fault("Server","Unable to decode response from soapval object into native php type.");
$this->debug("about to call method '$class -> $method'"); return $this->fault();
} }
else $this->debug("request data: $request_data");
{ }
$code = "\$method_response = call_user_func(\$this->methodname,";
$this->debug("about to call method '$this->methodname'"); /* if there are return values */
} if($this->return_type = $this->get_return_type())
/* call method with parameters */ {
$this->debug("about to call method '$class -> $method'"); $this->debug("got return type: '$this->return_type'");
while(list($x,$y) = each($request_data)) /* if there are parameters to pass */
{ if($request_data)
$code .= "\$request_data[$x]" . ',';
}
$code = substr($code,0,-1) .");";
if(eval($code))
{ {
if (is_object($obj)) if (is_object($obj))
{ {
$this->make_fault("Server","Method call failed for '$obj->method' with params: ".join(",",$request_data)); $code = "\$method_response = call_user_method(\$method,\$obj,";
$this->debug("about to call method '$class -> $method'");
} }
else else
{ {
$this->make_fault("Server","Method call failed for '$this->methodname' with params: ".join(",",$request_data)); $code = "\$method_response = call_user_func(\$this->methodname,";
$this->debug("about to call method '$this->methodname'");
} }
return $this->fault(); /* call method with parameters */
} $this->debug("about to call method '$class -> $method'");
} while(list($x,$y) = each($request_data))
else
{
/* call method w/ no parameters */
if (is_object($obj))
{
$this->debug("about to call method '$obj->method'");
if(!$method_response = call_user_method($method,$obj))
{ {
$this->make_fault("Server","Method call failed for '$obj->method' with no params"); $code .= "\$request_data[$x]" . ',';
}
$code = substr($code,0,-1) .');';
if(eval($code))
{
if (is_object($obj))
{
$this->make_fault("Server","Method call failed for '$obj->method' with params: ".join(",",$request_data));
}
else
{
$this->make_fault("Server","Method call failed for '$this->methodname' with params: ".join(",",$request_data));
}
return $this->fault(); return $this->fault();
} }
} }
else else
{ {
$this->debug("about to call method '$this->methodname'"); /* call method w/ no parameters */
if(!$method_response = call_user_func($this->methodname)) if (is_object($obj))
{ {
$this->make_fault("Server","Method call failed for '$this->methodname' with no params"); $this->debug("about to call method '$obj->method'");
return $this->fault(); if(!$method_response = call_user_method($method,$obj))
{
$this->make_fault("Server","Method call failed for '$obj->method' with no params");
return $this->fault();
}
}
else
{
$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 */
} }
/* no return values */ else
}
else
{
if($request_data)
{ {
/* call method with parameters */ if($request_data)
$code = "\$method_response = call_user_method(\$method,\$obj,";
while(list($x,$y) = each($request_data))
{ {
$code .= "\$request_data[$x]" . ','; /* call method with parameters */
$code = "\$method_response = call_user_method(\$method,\$obj,";
while(list($x,$y) = each($request_data))
{
$code .= "\$request_data[$x]" . ',';
}
$code = substr($code,0,-1) .');';
$this->debug("about to call method '$obj->method'");
eval($code);
} }
$code = substr($code,0,-1) .");"; else
$this->debug("about to call method '$obj->method'"); {
eval($code); /* call method w/ no parameters */
$this->debug("about to call method '$obj->method'");
call_user_method($method,$obj);
}
}
/* return fault */
if(get_class($method_response) == 'soapmsg')
{
if(eregi('fault',$method_response->value->name))
{
$this->fault = True;
}
$return_msg = $method_response;
} }
else else
{ {
/* call method w/ no parameters */ /* return soapval object */
$this->debug("about to call method '$obj->method'");
call_user_method($method,$obj); if(get_class($method_response) == 'soapval')
{
$return_val = $method_response;
/* create soap_val object w/ return values from method, use method signature to determine type */
}
else
{
$return_val = CreateObject('phpgwapi.soapval',$method,$this->return_type,$method_response);
}
$this->debug($return_val->debug_str);
/* response object is a soap_msg object */
$return_msg = CreateObject('phpgwapi.soapmsg',$method.'Response',array($return_val),$this->service);
} }
} if($this->debug_flag)
/* return fault */
if(get_class($method_response) == "soapmsg")
{
if(eregi("fault",$method_response->value->name))
{ {
$this->fault = True; $return_msg->debug_flag = true;
} }
$return_msg = $method_response; $this->result = 'successful';
return $return_msg;
} }
else else
{ {
/* return soapval object */ // debug
$this->debug("ERROR: request not verified against method signature");
if(get_class($method_response) == "soapval") $this->result = "fault: request failed validation against method signature";
{ // return soapresp
$return_val = $method_response; return $this->fault();
/* create soap_val object w/ return values from method, use method signature to determine type */
}
else
{
$return_val = CreateObject('phpgwapi.soapval',$method,$this->return_type,$method_response);
}
$this->debug($return_val->debug_str);
/* response object is a soap_msg object */
$return_msg = CreateObject('phpgwapi.soapmsg',$method."Response",array($return_val),$this->service);
} }
if($this->debug_flag)
{
$return_msg->debug_flag = true;
}
$this->result = "successful";
return $return_msg;
} }
else else
{ {
// debug // debug
$this->debug("ERROR: request not verified against method signature"); $this->debug("ERROR: parser did not return soapval object: $request_val ".get_class($request_val));
$this->result = "fault: request failed validation against method signature"; $this->result = "fault: parser did not return soapval object: $request_val";
// return soapresp // return fault
$this->make_fault('Server',"parser did not return soapval object: $request_val");
return $this->fault(); 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) 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); //return true;
if(is_array($params)) $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->debug("entered verify_method() with ".count($params)." parameters"); $this->input_value = count($sig);
@reset($params); if(is_array($params))
while(list($null,$v) = @each($params))
/* foreach($params as $v) */
{ {
$this->debug("param '$v->name' of type '$v->type'"); $this->debug('entered verify_method() with '.count($params).' parameters');
}
// validate the number of parameters
if(count($params) == count($sig))
{
$this->debug("got correct number of parameters: ".count($sig));
// make array of param types
@reset($params); @reset($params);
while(list($null,$param) = @each($params)) while(list($null,$v) = @each($params))
/* foreach($params as $param) */ /* foreach($params as $v) */
{ {
$p[] = strtolower($param->type); $this->debug("param '$v->name' of type '$v->type'");
} }
// validate each param's type // validate the number of parameters
for($i=0; $i < count($p); $i++) if(count($params) == count($sig))
{ {
// type not match $this->debug("got correct number of parameters: ".count($sig));
if(strtolower($sig[$i]) != strtolower($p[$i])) // make array of param types
@reset($params);
while(list($null,$param) = @each($params))
/* foreach($params as $param) */
{ {
$this->debug("mismatched parameter types: $sig[$i] != $p[$i]"); $p[] = strtolower($param->type);
$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]"); // 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
} }
return true; else
// oops, wrong number of paramss {
$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 else
{ {
$this->debug("oops, wrong number of parameter!"); $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' required ".count($sig)." and request provided ".count($params)); $this->make_fault('Client',"soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig)." parameters, and request provided none");
return false; return false;
} }
// oops, no params... // no params
}
elseif( (count($params)==0) && (count($sig) <= 1) )
{
$this->input_values = 0;
return true;
} }
else else
{ {
$this->debug("oops, no parameters sent! Method '$this->methodname' requires ".count($sig)." input parameters!"); //$this->debug("well, request passed parameters to a method that requires none?");
$this->make_fault("Client","soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig)." parameters, and request provided none"); //$this->make_fault("Client","method '$this->methodname' requires no parameters. The request passed in ".count($params).": ".@implode(" param: ",$params) );
return false; return true;
} }
// no params
} }
elseif( (count($params)==0) && (count($sig) <= 1) )
// get string return type from dispatch map
function get_return_type()
{ {
$this->input_values = 0; if(count($this->dispatch_map[$this->methodname]['out']) >= 1)
return true; {
$type = array_shift($this->dispatch_map[$this->methodname]['out']);
$this->debug("got return type from dispatch map: '$type'");
return $type;
}
return false;
} }
else
// dbg
function debug($string)
{ {
//$this->debug("well, request passed parameters to a method that requires none?"); if($this->debug_flag)
//$this->make_fault("Client","method '$this->methodname' requires no parameters. The request passed in ".count($params).": ".@implode(" param: ",$params) ); {
return true; $this->debug_str .= "$string\n";
}
} }
}
// get string return type from dispatch map // add a method to the dispatch map
function get_return_type() function add_to_map($methodname,$in,$out)
{
if(count($this->dispatch_map[$this->methodname]["out"]) >= 1)
{ {
$type = array_shift($this->dispatch_map[$this->methodname]["out"]); $this->dispatch_map[$methodname]['in'] = $in;
$this->debug("got return type from dispatch map: '$type'"); $this->dispatch_map[$methodname]['out'] = $out;
return $type;
} }
return false;
}
// dbg // set up a fault
function debug($string) function fault()
{
if($this->debug_flag)
{ {
$this->debug_str .= "$string\n"; 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.xmlsoap.org/soap/envelope/'
);
}
function make_fault($fault_code,$fault_string)
{
$this->fault_code = $fault_code;
$this->fault_str = $fault_string;
$this->fault = true;
} }
} }
// 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.xmlsoap.org/soap/envelope/"
);
}
function make_fault($fault_code,$fault_string)
{
$this->fault_code = $fault_code;
$this->fault_str = $fault_string;
$this->fault = true;
}
}
?> ?>

View File

@ -1,153 +1,153 @@
<?php <?php
/* soapx4 high level class /* soapx4 high level class
usage: usage:
// instantiate client with server info // instantiate client with server info
$soapclient = new soapclient( string path [ ,boolean wsdl] ); $soapclient = new soapclient( string path [ ,boolean wsdl] );
// call method, get results // call method, get results
echo $soapclient->call( string methodname [ ,array parameters] ); echo $soapclient->call( string methodname [ ,array parameters] );
// bye bye client // bye bye client
unset($soapclient); unset($soapclient);
*/ */
/* $Id$ */
class soapclient class soapclient
{
function soapclient($endpoint,$wsdl=False,$portName=False)
{ {
$this->debug_flag = True; function soapclient($endpoint,$wsdl=False,$portName=False)
$this->endpoint = $endpoint; {
$this->portName = False; $this->debug_flag = True;
$this->endpoint = $endpoint;
$this->portName = False;
// make values // make values
if($wsdl) if($wsdl)
{
$this->endpointType = 'wsdl';
if($portName)
{ {
$this->portName = $portName; $this->endpointType = 'wsdl';
} if($portName)
}
}
function call($method,$params='',$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? $this->portName = $portName;
if(eregi("fault",$return->name)) }
}
}
function call($method,$params='',$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')
{ {
$this->debug("got fault"); // fault?
$faultArray = $return->decode(); if(eregi('fault',$return->name))
@reset($faultArray);
while(list($k,$v) = @each($faultArray))
/* foreach($faultArray as $k => $v) */
{ {
print "$k = $v<br>"; $this->debug('got fault');
} $faultArray = $return->decode();
return false; @reset($faultArray);
} while(list($k,$v) = @each($faultArray))
else /* foreach($faultArray as $k => $v) */
{ {
$returnArray = $return->decode(); print "$k = $v<br>";
if(is_array($returnArray)) }
{ return false;
return array_shift($returnArray);
} }
else else
{ {
$this->debug("didn't get array back from decode() for $return->name"); $returnArray = $return->decode();
return false; 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 else
{ {
$this->debug("didn't get soapval object back from client"); $this->debug('client send/recieve error');
return false; return false;
} }
} }
else }
function debug($string)
{
if($this->debug_flag)
{ {
$this->debug("client send/recieve error"); print $string . '<br>';
return false;
} }
} }
} }
function debug($string)
{
if($this->debug_flag)
{
print $string."<br>";
}
}
}
?> ?>

View File

@ -1,149 +1,151 @@
<?php <?php
// soap message class /* $Id$ */
class soapmsg
{ // soap message class
// params is an array of soapval objects class soapmsg
function soapmsg($method,$params,$method_namespace='http://testuri.org',$new_namespaces=False)
{ {
// globalize method namespace // params is an array of soapval objects
global $methodNamespace; function soapmsg($method,$params,$method_namespace='http://testuri.org',$new_namespaces=False)
$methodNamespace = $method_namespace; {
// make method struct // globalize method namespace
$this->value = CreateObject('phpgwapi.soapval',$method,"struct",$params,$method_namespace); global $methodNamespace;
if(is_array($new_namespaces)) $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);
@reset($new_namespaces);
while(list($null,$v) = @each($new_namespaces))
/* foreach($new_namespaces as $v) */
{
$namespaces[$v] = 'ns' . $i++;
}
$this->namespaces = $namespaces;
}
$this->payload = '';
$this->debug_flag = True;
$this->debug_str = "entering soapmsg() with soapval ".$this->value->name."\n";
}
function make_envelope($payload)
{ {
global $namespaces; global $namespaces;
$i = count($namespaces); @reset($namespaces);
@reset($new_namespaces); while(list($k,$v) = @each($namespaces))
while(list($null,$v) = @each($new_namespaces)) /* foreach($namespaces as $k => $v) */
/* foreach($new_namespaces as $v) */
{ {
$namespaces[$v] = "ns".$i++; $ns_string .= " xmlns:$v=\"$k\"";
} }
$this->namespaces = $namespaces; return "<SOAP-ENV:Envelope $ns_string SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
. $payload . "</SOAP-ENV:Envelope>\n";
} }
$this->payload = '';
$this->debug_flag = True;
$this->debug_str = "entering soapmsg() with soapval ".$this->value->name."\n";
}
function make_envelope($payload) function make_body($payload)
{
global $namespaces;
@reset($namespaces);
while(list($k,$v) = @each($namespaces))
/* foreach($namespaces as $k => $v) */
{ {
$ns_string .= " xmlns:$v=\"$k\""; return "<SOAP-ENV:Body>\n" . $payload . "</SOAP-ENV:Body>\n";
} }
return "<SOAP-ENV:Envelope $ns_string SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
. $payload . "</SOAP-ENV:Envelope>\n";
}
function make_body($payload) function createPayload()
{
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(); $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);
} }
$this->payload = str_replace("\n","\r\n", $payload);
}
function serialize() function serialize()
{
if($this->payload == '')
{ {
$this->createPayload(); if($this->payload == '')
return $this->payload; {
$this->createPayload();
return $this->payload;
}
else
{
return $this->payload;
}
} }
else
// returns a soapval object
function parseResponse($data)
{ {
return $this->payload; $this->debug("Entering parseResponse()");
//$this->debug(" w/ data $data");
// strip headers here
//$clean_data = ereg_replace("\r\n","\n", $data);
if(ereg("^.*\r\n\r\n<",$data))
{
$this->debug("found proper seperation of headers and document");
$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));
}
else
{
// return fault
return CreateObject('phpgwapi.soapval',
'fault',
'SOAPStruct',
Array(
CreateObject('phpgwapi.soapval','faultcode','string','SOAP-MSG'),
CreateObject('phpgwapi.soapval','faultstring','string','HTTP Error'),
CreateObject('phpgwapi.soapval','faultdetail','string','HTTP headers were not immediately followed by \'\r\n\r\n\'')
)
);
}
/*
// 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 '';
}
} }
} }
// returns a soapval object
function parseResponse($data)
{
$this->debug("Entering parseResponse()");
//$this->debug(" w/ data $data");
// strip headers here
//$clean_data = ereg_replace("\r\n","\n", $data);
if(ereg("^.*\r\n\r\n<",$data))
{
$this->debug("found proper seperation of headers and document");
$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));
}
else
{
// return fault
return CreateObject('phpgwapi.soapval',
'fault',
'SOAPStruct',
Array(
CreateObject('phpgwapi.soapval','faultcode','string','SOAP-MSG'),
CreateObject('phpgwapi.soapval','faultstring','string','HTTP Error'),
CreateObject('phpgwapi.soapval','faultdetail','string','HTTP headers were not immediately followed by \'\r\n\r\n\'')
)
);
}
/*
// 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 '';
}
}
}
?> ?>

View File

@ -1,436 +1,438 @@
<?php <?php
// soap value object /* $Id$ */
class soapval
{ // soap value object
// function soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False) class soapval
function soapval($name='',$type=False,$value=0,$namespace=False,$type_namespace=False)
{ {
global $soapTypes, $typemap, $namespaces, $methodNamespace; // function soapval($name='',$type=False,$value=-1,$namespace=False,$type_namespace=False)
function 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) global $soapTypes, $typemap, $namespaces, $methodNamespace;
// detect type if not passed
if(!$type)
{ {
if(ereg("[a-zA-Z0-9\-]*",key($v))) if(is_array($value) && count($value) >= 1)
{ {
$type = "struct"; if(ereg("[a-zA-Z0-9\-]*",key($v)))
}
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 = True;
$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)
{
@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';
{
$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 else
{ {
$type = gettype($v); $type = 'array';
} }
$new_val = CreateObject('phpgwapi.soapval',"item",$type,$v);
$this->debug($new_val->debug_str);
$this->value[] = $new_val;
} }
} elseif(is_int($v))
}
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; $type = 'int';
$this->debug($v->debug_str); }
// else make obj and serialize elseif(is_float($v) || $v == 'NaN' || $v == 'INF')
{
$type = 'float';
} }
else else
{ {
if(is_array($v)) $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 = True;
$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)
{
@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')
{ {
@reset($v); $this->value[] = $v;
while(list($a,$b) = @each($v)) $this->debug($v->debug_str);
/* foreach($v as $a => $b) */ // else make obj and serialize
}
else
{
if(is_array($v))
{ {
if($a == "0") if(ereg("[a-zA-Z\-]*",key($v)))
{ {
$type = "array"; $type = 'struct';
} }
else else
{ {
$type = "struct"; $type = 'array';
} }
break;
} }
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;
} }
// elseif(is_array($k) && in_array($k,array_keys($this->soapTypes))) }
elseif(is_array($k,in_array($k,array_keys($this->soapTypes)))) }
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->debug("got type '$type' for value '$v' from soapTypes array!"); $this->value[] = $v;
$type = $k; $this->debug($v->debug_str);
} // else make obj and serialize
elseif(is_int($v))
{
$type = "int";
}
elseif(is_float($v) || $v == "NaN" || $v == "INF")
{
$type = "float";
} }
else else
{ {
$type = gettype($v); if(is_array($v))
$this->debug("got type '$type' for value '$v' from php gettype()!"); {
@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;
} }
$new_val = CreateObject('phpgwapi.soapval',$k,$type,$v);
$this->debug($new_val->debug_str);
$this->value[] = $new_val;
} }
} }
} else
else {
{ $this->value = array();
$this->value = array(); }
} return true;
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) // turn soapvals into xml, woohoo!
function serializeval($soapval=false)
{ {
case 3: if(!$soapval)
// struct {
$this->debug("got a struct"); $soapval = $this;
if($soapval->prefix && $soapval->type_prefix) }
{ $this->debug("serializing '$soapval->name' of type '$soapval->type'");
$xml .= "<$soapval->prefix:$soapval->name xsi:type=\"$soapval->type_prefix:$soapval->type\">\n"; if($soapval->name == '')
} {
elseif($soapval->type_prefix) $soapval->name = 'return';
{ }
$xml .= "<$soapval->name xsi:type=\"$soapval->type_prefix:$soapval->type\">\n";
} switch($soapval->type_code)
elseif($soapval->prefix) {
{ case 3:
$xml .= "<$soapval->prefix:$soapval->name>\n"; // struct
} $this->debug('got a struct');
else if($soapval->prefix && $soapval->type_prefix)
{ {
$xml .= "<$soapval->name>\n"; $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;
}
// 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)) if(is_array($soapval->value))
{ {
@reset($soapval->value); @reset($soapval->value);
while(list($k,$v) = @each($soapval->value)) while(list($null,$item) = @each($soapval->value))
/* foreach($soapval->value as $k => $v) */ /* foreach($soapval->value as $item) */
{ {
$xml .= $this->serializeval($v); $return[] = $this->decode($item);
} }
} return $return;
if($soapval->prefix)
{
$xml .= "</$soapval->prefix:$soapval->name>\n";
} }
else else
{ {
$xml .= "</$soapval->name>\n"; return array();
} }
break; // struct decode
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;
}
// 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))
{
@reset($soapval->value);
while(list($null,$item) = @each($soapval->value))
/* foreach($soapval->value as $item) */
{
$return[] = $this->decode($item);
}
return $return;
} }
else elseif($soapval->type_code == 3)
{ {
return array(); if(is_array($soapval->value))
}
// 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); @reset($soapval->value);
while(list($null,$item) = @each($soapval->value))
/* foreach($soapval->value as $item) */
{
$return[$item->name] = $this->decode($item);
}
return $return;
} }
return $return; else
}
else
{
return array();
}
}
}
// verify type
function verify_type($type)
{
if ($type)
{
// global $namespaces,$soapTypes,$typemap;
global $namespaces,$typemap;
@reset($typemap);
while(list($namespace,$types) = @each($typemap))
/* foreach($typemap as $namespace => $types) */
{
if(in_array($type,$types))
{ {
return $namespaces[$namespace]; return array();
} }
} }
} }
return false;
}
// alias for verify_type() - pass it a type, and it returns it's prefix // verify type
function get_prefix($type) function verify_type($type)
{
if($prefix = $this->verify_type($type))
{ {
return $prefix; if ($type)
{
// global $namespaces,$soapTypes,$typemap;
global $namespaces,$typemap;
@reset($typemap);
while(list($namespace,$types) = @each($typemap))
/* foreach($typemap as $namespace => $types) */
{
if(in_array($type,$types))
{
return $namespaces[$namespace];
}
}
}
return false;
} }
return false;
}
function debug($string) // alias for verify_type() - pass it a type, and it returns it's prefix
{ function get_prefix($type)
if($this->debug_flag)
{ {
$this->debug_str .= "$string\n"; if($prefix = $this->verify_type($type))
{
return $prefix;
}
return false;
}
function debug($string)
{
if($this->debug_flag)
{
$this->debug_str .= "$string\n";
}
} }
} }
}
?> ?>