egroupware/phpgwapi/inc/class.wsdl.inc.php
2001-08-02 08:59:08 +00:00

280 lines
7.4 KiB
PHP

<?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)
{
@reset($this->ports);
while(list($port,$portAttrs) = @each($this->ports));
/* foreach($this->ports as $port => $portAttrs) */
{
$binding = substr($portAttrs["binding"],4);
@reset($this->bindings[$binding]["operations"]);
while(list($op,$opAttrs) = @each($this->bindings[$binding]["operations"]))
/* 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";
}
}
}
?>