For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
985 $start = gettimeofday();
989 $stop = gettimeofday();
990 $timePassed = 1000000 * ($stop[
'sec'] - $start[
'sec'])
991 + $stop[
'usec'] - $start[
'usec'];
993 while ($timePassed < $usec);
1042 function __construct($faultcode,$faultactor=
'',$faultstring=
'',$faultdetail=
''){
1058 foreach($this->namespaces as $k => $v){
1059 $ns_string .=
"\n xmlns:$k=\"$v\"";
1062 '<?xml version="1.0" encoding="'.$this->soap_defencoding.
'"?>'.
1063 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.
">\n".
1070 '</SOAP-ENV:Fault>'.
1072 '</SOAP-ENV:Envelope>';
1102 var $enclosingNamespaces;
1104 var $schemaInfo = array();
1105 var $schemaTargetNamespace =
'';
1108 var $complexTypes = array();
1109 var $complexTypeStack = array();
1110 var $currentComplexType = null;
1111 var $elements = array();
1112 var $elementStack = array();
1113 var $currentElement = null;
1114 var $simpleTypes = array();
1115 var $simpleTypeStack = array();
1116 var $currentSimpleType = null;
1118 var $imports = array();
1123 var $depth_array = array();
1125 var $defaultNamespace = array();
1137 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
1139 $this->schema = $schema;
1144 $this->namespaces = array_merge($this->namespaces,
$namespaces);
1148 $this->
debug(
'initial schema file: '.$schema);
1149 $this->parseFile($schema,
'schema');
1154 $this->
debug(
'initial xml file: '.$xml);
1155 $this->parseFile($xml,
'xml');
1168 function parseFile($xml,
$type){
1171 $xmlStr = @join(
"",@file($xml));
1173 $msg =
'Error reading XML from '.$xml;
1178 $this->
debug(
"parsing $xml");
1179 $this->parseString($xmlStr,
$type);
1180 $this->
debug(
"done parsing $xml");
1194 function parseString($xml,
$type){
1199 $this->parser = xml_parser_create();
1201 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1204 xml_set_object($this->parser, $this);
1207 if(
$type ==
"schema"){
1208 xml_set_element_handler($this->parser,
'schemaStartElement',
'schemaEndElement');
1209 xml_set_character_data_handler($this->parser,
'schemaCharacterData');
1210 } elseif(
$type ==
"xml"){
1211 xml_set_element_handler($this->parser,
'xmlStartElement',
'xmlEndElement');
1212 xml_set_character_data_handler($this->parser,
'xmlCharacterData');
1216 if(!xml_parse($this->parser,$xml,
true)){
1218 $errstr = sprintf(
'XML error parsing XML schema on line %d: %s',
1219 xml_get_current_line_number($this->parser),
1220 xml_error_string(xml_get_error_code($this->parser))
1222 $this->
debug($errstr);
1223 $this->
debug(
"XML payload:\n" . $xml);
1227 xml_parser_free($this->parser);
1229 $this->
debug(
'no xml passed to parseString()!!');
1230 $this->
setError(
'no xml passed to parseString()!!');
1241 function CreateTypeName($ename) {
1243 for (
$i = 0;
$i < count($this->complexTypeStack);
$i++) {
1244 $scope .= $this->complexTypeStack[
$i] .
'_';
1246 return $scope . $ename .
'_ContainedType';
1257 function schemaStartElement($parser,
$name, $attrs) {
1260 $pos = $this->position++;
1261 $depth = $this->depth++;
1263 $this->depth_array[$depth] = $pos;
1264 $this->message[$pos] = array(
'cdata' =>
'');
1266 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1268 $this->defaultNamespace[$pos] =
false;
1280 if(count($attrs) > 0){
1281 foreach($attrs as $k => $v){
1283 if(preg_match(
'/^xmlns/',$k)){
1286 if($ns_prefix = substr(strrchr($k,
':'),1)){
1288 $this->namespaces[$ns_prefix] = $v;
1290 $this->defaultNamespace[$pos] = $v;
1292 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $v;
1295 if($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema'){
1296 $this->XMLSchemaVersion = $v;
1297 $this->namespaces[
'xsi'] = $v.
'-instance';
1301 foreach($attrs as $k => $v){
1303 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1304 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1318 $this->complexTypes[$this->currentComplexType][
'compositor'] =
$name;
1325 $this->xdebug(
"parsing attribute:");
1327 if (!isset($attrs[
'form'])) {
1328 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1330 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1331 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1332 if (!strpos($v,
':')) {
1334 if ($this->defaultNamespace[$pos]) {
1336 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1340 if(isset($attrs[
'name'])){
1341 $this->attributes[$attrs[
'name']] = $attrs;
1342 $aname = $attrs[
'name'];
1343 } elseif(isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1344 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1345 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1349 } elseif(isset($attrs[
'ref'])){
1350 $aname = $attrs[
'ref'];
1351 $this->attributes[$attrs[
'ref']] = $attrs;
1354 if($this->currentComplexType){
1355 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1358 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType'){
1359 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1361 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1362 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1366 if(strpos($v,
'[,]')){
1367 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1369 $v = substr($v,0,strpos($v,
'['));
1370 if(!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
1371 $v = $this->XMLSchemaVersion.
':'.$v;
1373 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1376 case 'complexContent':
1379 array_push($this->complexTypeStack, $this->currentComplexType);
1380 if(isset($attrs[
'name'])){
1383 $this->xdebug(
'processing named complexType '.$attrs[
'name']);
1385 $this->currentComplexType = $attrs[
'name'];
1386 $this->complexTypes[$this->currentComplexType] = $attrs;
1387 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1395 if(isset($attrs[
'base']) && preg_match(
'/:Array$/',$attrs[
'base'])){
1396 $this->xdebug(
'complexType is unusual array');
1397 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1399 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1402 $name = $this->CreateTypeName($this->currentElement);
1403 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' .
$name);
1404 $this->currentComplexType =
$name;
1406 $this->complexTypes[$this->currentComplexType] = $attrs;
1407 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1415 if(isset($attrs[
'base']) && preg_match(
'/:Array$/',$attrs[
'base'])){
1416 $this->xdebug(
'complexType is unusual array');
1417 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1419 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1424 array_push($this->elementStack, $this->currentElement);
1425 if (!isset($attrs[
'form'])) {
1426 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1428 if(isset($attrs[
'type'])){
1429 $this->xdebug(
"processing typed element ".$attrs[
'name'].
" of type ".$attrs[
'type']);
1430 if (! $this->
getPrefix($attrs[
'type'])) {
1431 if ($this->defaultNamespace[$pos]) {
1432 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1433 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1443 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1444 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1445 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1447 $this->currentElement = $attrs[
'name'];
1448 $ename = $attrs[
'name'];
1449 } elseif(isset($attrs[
'ref'])){
1450 $this->xdebug(
"processing element as ref to ".$attrs[
'ref']);
1451 $this->currentElement =
"ref to ".$attrs[
'ref'];
1454 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1455 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' .
$type);
1456 $this->currentElement = $attrs[
'name'];
1457 $attrs[
'type'] = $this->schemaTargetNamespace .
':' .
$type;
1458 $ename = $attrs[
'name'];
1460 if (isset($ename) && $this->currentComplexType) {
1461 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1462 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1463 } elseif (!isset($attrs[
'ref'])) {
1464 $this->xdebug(
"add element $ename to elements array");
1465 $this->elements[ $attrs[
'name'] ] = $attrs;
1466 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1470 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1471 if ($this->currentSimpleType) {
1472 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1473 } elseif ($this->currentComplexType) {
1474 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1478 $this->xdebug(
'extension ' . $attrs[
'base']);
1479 if ($this->currentComplexType) {
1480 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1484 if (isset($attrs[
'schemaLocation'])) {
1486 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1489 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1491 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $attrs[
'namespace'];
1498 $this->xdebug(
'restriction ' . $attrs[
'base']);
1499 if($this->currentSimpleType){
1500 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1501 } elseif($this->currentComplexType){
1502 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1503 if(strstr($attrs[
'base'],
':') ==
':Array'){
1504 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1509 $this->schemaInfo = $attrs;
1511 if (isset($attrs[
'targetNamespace'])) {
1512 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1514 if (!isset($attrs[
'elementFormDefault'])) {
1515 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1517 if (!isset($attrs[
'attributeFormDefault'])) {
1518 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1521 case 'simpleContent':
1524 array_push($this->simpleTypeStack, $this->currentSimpleType);
1525 if(isset($attrs[
'name'])){
1526 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1527 $this->currentSimpleType = $attrs[
'name'];
1528 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1529 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1530 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1532 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1533 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' .
$name);
1534 $this->currentSimpleType =
$name;
1536 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1537 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1554 function schemaEndElement($parser,
$name) {
1558 if(isset($this->depth_array[$this->depth])){
1559 $pos = $this->depth_array[$this->depth];
1569 if(
$name ==
'complexType'){
1570 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1571 $this->currentComplexType = array_pop($this->complexTypeStack);
1574 if(
$name ==
'element'){
1575 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1576 $this->currentElement = array_pop($this->elementStack);
1578 if(
$name ==
'simpleType'){
1579 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1580 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1591 function schemaCharacterData($parser,
$data){
1592 $pos = $this->depth_array[$this->depth - 1];
1593 $this->message[$pos][
'cdata'] .=
$data;
1601 function serializeSchema(){
1606 if (
sizeof($this->imports) > 0) {
1607 foreach($this->imports as $ns => $list) {
1608 foreach ($list as $ii) {
1609 if ($ii[
'location'] !=
'') {
1610 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1612 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1618 foreach($this->complexTypes as $typeName => $attrs){
1621 if(isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)){
1622 foreach($attrs[
'elements'] as $element => $eParts){
1623 if(isset($eParts[
'ref'])){
1624 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1626 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1627 foreach ($eParts as $aName => $aValue) {
1629 if ($aName !=
'name' && $aName !=
'type') {
1630 $contentStr .=
" $aName=\"$aValue\"";
1633 $contentStr .=
"/>\n";
1637 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1638 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n".$contentStr.
" </$schemaPrefix:$attrs[compositor]>\n";
1642 if(isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)){
1643 foreach($attrs[
'attrs'] as $attr => $aParts){
1644 $contentStr .=
" <$schemaPrefix:attribute";
1645 foreach ($aParts as
$a => $v) {
1646 if (
$a ==
'ref' ||
$a ==
'type') {
1647 $contentStr .=
" $a=\"".$this->contractQName($v).
'"';
1648 } elseif (
$a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1649 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1650 $contentStr .=
' wsdl:arrayType="'.$this->contractQName($v).
'"';
1652 $contentStr .=
" $a=\"$v\"";
1655 $contentStr .=
"/>\n";
1659 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
''){
1660 $contentStr =
" <$schemaPrefix:restriction base=\"".$this->contractQName($attrs[
'restrictionBase']).
"\">\n".$contentStr.
" </$schemaPrefix:restriction>\n";
1662 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)){
1663 $contentStr =
" <$schemaPrefix:complexContent>\n".$contentStr.
" </$schemaPrefix:complexContent>\n";
1667 if($contentStr !=
''){
1668 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr.
" </$schemaPrefix:complexType>\n";
1670 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1672 $xml .= $contentStr;
1675 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
1676 foreach($this->simpleTypes as $typeName => $eParts){
1677 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts[
'type']).
"\">\n";
1678 if (isset($eParts[
'enumeration'])) {
1679 foreach ($eParts[
'enumeration'] as
$e) {
1680 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1683 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1687 if(isset($this->elements) && count($this->elements) > 0){
1688 foreach($this->elements as $element => $eParts){
1689 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts[
'type']).
"\"/>\n";
1693 if(isset($this->attributes) && count($this->attributes) > 0){
1694 foreach($this->attributes as $attr => $aParts){
1695 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts[
'type']).
"\"\n/>";
1700 foreach ($this->schemaInfo as $k => $v) {
1701 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1702 $attr .=
" $k=\"$v\"";
1705 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1706 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1707 $el .=
" xmlns:$nsp=\"$ns\"";
1709 $xml = $el .
">\n".$xml.
"</$schemaPrefix:schema>\n";
1719 function xdebug($string){
1720 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> '.$string);
1735 function getPHPType(
$type,$ns){
1736 if(isset($this->typemap[$ns][
$type])){
1738 return $this->typemap[$ns][
$type];
1739 } elseif(isset($this->complexTypes[$type])){
1741 return $this->complexTypes[
$type][
'phpType'];
1768 function getTypeDef($type){
1770 if (substr($type, -1) ==
'^') {
1772 $type = substr($type, 0, -1);
1777 if((! $is_element) && isset($this->complexTypes[$type])){
1778 $this->xdebug(
"in getTypeDef, found complexType $type");
1779 return $this->complexTypes[
$type];
1780 } elseif((! $is_element) && isset($this->simpleTypes[$type])){
1781 $this->xdebug(
"in getTypeDef, found simpleType $type");
1782 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1785 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1786 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1787 $etype = $this->getTypeDef($uqType);
1789 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1790 $this->xdebug($this->
varDump($etype));
1791 if (isset($etype[
'phpType'])) {
1792 $this->simpleTypes[
$type][
'phpType'] = $etype[
'phpType'];
1794 if (isset($etype[
'elements'])) {
1795 $this->simpleTypes[
$type][
'elements'] = $etype[
'elements'];
1799 return $this->simpleTypes[
$type];
1800 } elseif(isset($this->elements[$type])){
1801 $this->xdebug(
"in getTypeDef, found element $type");
1802 if (!isset($this->elements[$type][
'phpType'])) {
1804 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1805 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1806 $etype = $this->getTypeDef($uqType);
1808 $this->xdebug(
"in getTypeDef, found type for element $type:");
1809 $this->xdebug($this->
varDump($etype));
1810 if (isset($etype[
'phpType'])) {
1811 $this->elements[
$type][
'phpType'] = $etype[
'phpType'];
1813 if (isset($etype[
'elements'])) {
1814 $this->elements[
$type][
'elements'] = $etype[
'elements'];
1816 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1817 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1818 $this->elements[
$type][
'phpType'] =
'scalar';
1821 return $this->elements[
$type];
1822 } elseif(isset($this->attributes[$type])){
1823 $this->xdebug(
"in getTypeDef, found attribute $type");
1824 return $this->attributes[
$type];
1825 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1826 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1827 $typeDef[
'typeClass'] =
'simpleType';
1828 $typeDef[
'phpType'] =
'scalar';
1829 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1832 $this->xdebug(
"in getTypeDef, did not find $type");
1844 function serializeTypeDef($type){
1846 if($typeDef = $this->getTypeDef($type)){
1848 if(is_array($typeDef[
'attrs'])){
1849 foreach($typeDef[
'attrs'] as $attName =>
$data){
1850 $str .=
" $attName=\"{type = ".$data[
'type'].
"}\"";
1853 $str .=
" xmlns=\"".$this->schema[
'targetNamespace'].
"\"";
1854 if(count($typeDef[
'elements']) > 0){
1856 foreach($typeDef[
'elements'] as $element => $eData){
1857 $str .= $this->serializeTypeDef($element);
1860 } elseif($typeDef[
'typeClass'] ==
'element') {
1861 $str .=
"></$type>";
1880 function typeToForm(
$name,$type){
1882 if($typeDef = $this->getTypeDef($type)){
1884 if($typeDef[
'phpType'] ==
'struct'){
1885 $buffer .=
'<table>';
1886 foreach($typeDef[
'elements'] as $child => $childDef){
1888 <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef[
'type']).
"):</td> 1889 <td><input type='text' name='parameters[".
$name.
"][$childDef[name]]'></td></tr>";
1891 $buffer .=
'</table>';
1893 } elseif($typeDef[
'phpType'] ==
'array'){
1894 $buffer .=
'<table>';
1897 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1898 <td><input type='text' name='parameters[".$name.
"][]'></td></tr>";
1900 $buffer .=
'</table>';
1903 $buffer .=
"<input type='text' name='parameters[$name]'>";
1906 $buffer .=
"<input type='text' name='parameters[$name]'>";
1952 function addComplexType(
$name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',$elements=array(),$attrs=array(),$arrayType=
''){
1953 $this->complexTypes[
$name] = array(
1955 'typeClass' => $typeClass,
1956 'phpType' => $phpType,
1957 'compositor'=> $compositor,
1958 'restrictionBase' => $restrictionBase,
1959 'elements' => $elements,
1961 'arrayType' => $arrayType
1964 $this->xdebug(
"addComplexType $name:");
1980 function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array()) {
1981 $this->simpleTypes[
$name] = array(
1983 'typeClass' => $typeClass,
1984 'phpType' => $phpType,
1985 'type' => $restrictionBase,
1986 'enumeration' => $enumeration
1989 $this->xdebug(
"addSimpleType $name:");
2000 function addElement($attrs) {
2001 if (! $this->
getPrefix($attrs[
'type'])) {
2002 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
2004 $this->elements[ $attrs[
'name'] ] = $attrs;
2005 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
2007 $this->xdebug(
"addElement " . $attrs[
'name']);
2088 function __construct($name=
'soapval',$type=
false,$value=-1,$element_ns=
false,$type_ns=
false,$attributes=
false) {
2090 $this->name =
$name;
2091 $this->type =
$type;
2092 $this->value = $value;
2093 $this->element_ns = $element_ns;
2094 $this->type_ns = $type_ns;
2106 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2116 return $this->value;
2139 var $digest_uri =
'';
2144 var $request_method =
'POST';
2145 var $protocol_version =
'1.0';
2147 var $outgoing_headers = array();
2148 var $incoming_headers = array();
2149 var $incoming_cookies = array();
2150 var $outgoing_payload =
'';
2151 var $incoming_payload =
'';
2152 var $response_status_line;
2153 var $useSOAPAction =
true;
2154 var $persistentConnection =
false;
2156 var $ch_options = array();
2157 var $use_curl =
false;
2162 var $digestRequest = array();
2163 var $certRequest = array();
2180 function __construct($url, $curl_options = NULL, $use_curl =
false){
2182 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2184 $this->setURL($url);
2185 if (is_array($curl_options)) {
2186 $this->ch_options = $curl_options;
2188 $this->use_curl = $use_curl;
2189 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2190 $this->setHeader(
'User-Agent', $this->title.
'/'.$this->version.
' ('.$rev[1].
')');
2200 function setCurlOption($option, $value) {
2201 $this->
debug(
"setCurlOption option=$option, value=");
2203 curl_setopt($this->ch, $option, $value);
2213 function setHeader(
$name, $value) {
2214 $this->outgoing_headers[
$name] = $value;
2215 $this->
debug(
"set header $name: $value");
2224 function unsetHeader(
$name) {
2225 if (isset($this->outgoing_headers[
$name])) {
2226 $this->
debug(
"unset header $name");
2227 unset($this->outgoing_headers[$name]);
2237 function setURL($url) {
2240 $u = parse_url($url);
2241 foreach($u as $k => $v){
2242 $this->
debug(
"parsed URL $k = $v");
2247 if(isset($u[
'query']) && $u[
'query'] !=
''){
2248 $this->path .=
'?' . $u[
'query'];
2252 if(!isset($u[
'port'])){
2253 if($u[
'scheme'] ==
'https'){
2260 $this->uri = $this->path;
2261 $this->digest_uri = $this->uri;
2264 if (!isset($u[
'port'])) {
2265 $this->setHeader(
'Host', $this->host);
2267 $this->setHeader(
'Host', $this->host.
':'.$this->port);
2270 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2271 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2281 function io_method() {
2282 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm'))
2284 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm'))
2297 function connect($connection_timeout=0,$response_timeout=30){
2310 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2311 if ($this->io_method() ==
'socket') {
2312 if (!is_array($this->proxy)) {
2313 $host = $this->host;
2314 $port = $this->port;
2316 $host = $this->proxy[
'host'];
2317 $port = $this->proxy[
'port'];
2321 if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
2322 if (!feof($this->fp)) {
2323 $this->
debug(
'Re-use persistent connection');
2327 $this->
debug(
'Closed persistent connection at EOF');
2331 if ($this->scheme ==
'ssl') {
2332 $host =
'ssl://' . $host;
2334 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2337 if($connection_timeout > 0){
2338 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2340 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
2345 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2349 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2357 $this->
debug(
'set response timeout to ' . $response_timeout);
2358 socket_set_timeout( $this->fp, $response_timeout);
2360 $this->
debug(
'socket connected');
2362 }
else if ($this->io_method() ==
'curl') {
2363 if (!extension_loaded(
'curl')) {
2365 $this->
setError(
'The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to included cURL.');
2369 if (defined(
'CURLOPT_CONNECTIONTIMEOUT'))
2370 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2372 $CURLOPT_CONNECTIONTIMEOUT = 78;
2373 if (defined(
'CURLOPT_HTTPAUTH'))
2374 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2376 $CURLOPT_HTTPAUTH = 107;
2377 if (defined(
'CURLOPT_PROXYAUTH'))
2378 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2380 $CURLOPT_PROXYAUTH = 111;
2381 if (defined(
'CURLAUTH_BASIC'))
2382 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2384 $CURLAUTH_BASIC = 1;
2385 if (defined(
'CURLAUTH_DIGEST'))
2386 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2388 $CURLAUTH_DIGEST = 2;
2389 if (defined(
'CURLAUTH_NTLM'))
2390 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2394 $this->
debug(
'connect using cURL');
2396 $this->ch = curl_init();
2398 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2400 $hostURL .= $this->path;
2401 $this->setCurlOption(CURLOPT_URL, $hostURL);
2403 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2404 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2405 $this->
debug(
'safe_mode = ');
2407 $this->
debug(
'open_basedir = ');
2410 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2413 $this->setCurlOption(CURLOPT_HEADER, 1);
2415 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2422 if ($this->persistentConnection) {
2428 $this->persistentConnection =
false;
2429 $this->setHeader(
'Connection',
'close');
2432 if ($connection_timeout != 0) {
2433 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2435 if ($response_timeout != 0) {
2436 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2439 if ($this->scheme ==
'https') {
2440 $this->
debug(
'set cURL SSL verify options');
2445 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2446 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2449 if ($this->authtype ==
'certificate') {
2450 $this->
debug(
'set cURL certificate options');
2451 if (isset($this->certRequest[
'cainfofile'])) {
2452 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2454 if (isset($this->certRequest[
'verifypeer'])) {
2455 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2457 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2459 if (isset($this->certRequest[
'verifyhost'])) {
2460 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2462 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2464 if (isset($this->certRequest[
'sslcertfile'])) {
2465 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2467 if (isset($this->certRequest[
'sslkeyfile'])) {
2468 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2470 if (isset($this->certRequest[
'passphrase'])) {
2471 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2473 if (isset($this->certRequest[
'certpassword'])) {
2474 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2478 if ($this->authtype && ($this->authtype !=
'certificate')) {
2479 if ($this->username) {
2480 $this->
debug(
'set cURL username/password');
2481 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2483 if ($this->authtype ==
'basic') {
2484 $this->
debug(
'set cURL for Basic authentication');
2485 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2487 if ($this->authtype ==
'digest') {
2488 $this->
debug(
'set cURL for digest authentication');
2489 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2491 if ($this->authtype ==
'ntlm') {
2492 $this->
debug(
'set cURL for NTLM authentication');
2493 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2496 if (is_array($this->proxy)) {
2497 $this->
debug(
'set cURL proxy options');
2498 if ($this->proxy[
'port'] !=
'') {
2499 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'].
':'.$this->proxy[
'port']);
2501 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2503 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2504 $this->
debug(
'set cURL proxy authentication options');
2505 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'].
':'.$this->proxy[
'password']);
2506 if ($this->proxy[
'authtype'] ==
'basic') {
2507 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2509 if ($this->proxy[
'authtype'] ==
'ntlm') {
2510 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2514 $this->
debug(
'cURL connection set up');
2517 $this->
setError(
'Unknown scheme ' . $this->scheme);
2518 $this->
debug(
'Unknown scheme ' . $this->scheme);
2533 function send(
$data, $timeout=0, $response_timeout=30, $cookies=NULL) {
2535 $this->
debug(
'entered send() with data of length: '.strlen(
$data));
2537 $this->tryagain =
true;
2539 while ($this->tryagain) {
2540 $this->tryagain =
false;
2543 if (!$this->connect($timeout, $response_timeout)){
2548 if (!$this->sendRequest(
$data, $cookies)){
2553 $respdata = $this->getResponse();
2555 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2558 $this->
debug(
'end of send()');
2574 function sendHTTPS(
$data, $timeout=0, $response_timeout=30, $cookies) {
2575 return $this->
send(
$data, $timeout, $response_timeout, $cookies);
2588 function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array()) {
2589 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2591 $this->
debug(
"certRequest=");
2594 if ($authtype ==
'basic') {
2595 $this->setHeader(
'Authorization',
'Basic '.base64_encode(str_replace(
':',
'',$username).
':'.$password));
2596 } elseif ($authtype ==
'digest') {
2597 if (isset($digestRequest[
'nonce'])) {
2598 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2603 $A1 = $username.
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2609 $A2 = $this->request_method .
':' . $this->digest_uri;
2625 $unhashedDigest =
'';
2626 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2628 if ($digestRequest[
'qop'] !=
'') {
2629 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2631 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2634 $hashedDigest = md5($unhashedDigest);
2637 if (isset($digestRequest[
'opaque'])) {
2638 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2641 $this->setHeader(
'Authorization',
'Digest username="' . $username .
'", realm="' . $digestRequest[
'realm'] .
'", nonce="' . $nonce .
'", uri="' . $this->digest_uri . $opaque .
'", cnonce="' . $cnonce .
'", nc=' . sprintf(
"%08x", $digestRequest[
'nc']) .
', qop="' . $digestRequest[
'qop'] .
'", response="' . $hashedDigest .
'"');
2643 } elseif ($authtype ==
'certificate') {
2644 $this->certRequest = $certRequest;
2645 $this->
debug(
'Authorization header not set for certificate');
2646 } elseif ($authtype ==
'ntlm') {
2648 $this->
debug(
'Authorization header not set for ntlm');
2650 $this->username = $username;
2652 $this->authtype = $authtype;
2653 $this->digestRequest = $digestRequest;
2662 function setSOAPAction($soapaction) {
2663 $this->setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2672 function setEncoding($enc=
'gzip, deflate') {
2673 if (function_exists(
'gzdeflate')) {
2674 $this->protocol_version =
'1.1';
2675 $this->setHeader(
'Accept-Encoding', $enc);
2676 if (!isset($this->outgoing_headers[
'Connection'])) {
2677 $this->setHeader(
'Connection',
'close');
2678 $this->persistentConnection =
false;
2680 #set_magic_quotes_runtime(0); 2682 $this->encoding = $enc;
2696 function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic') {
2698 $this->proxy = array(
2699 'host' => $proxyhost,
2700 'port' => $proxyport,
2701 'username' => $proxyusername,
2702 'password' => $proxypassword,
2703 'authtype' => $proxyauthtype
2705 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2706 $this->setHeader(
'Proxy-Authorization',
' Basic '.base64_encode($proxyusername.
':'.$proxypassword));
2709 $this->
debug(
'remove proxy');
2711 unsetHeader(
'Proxy-Authorization');
2724 function isSkippableCurlHeader(&
$data) {
2725 $skipHeaders = array(
'HTTP/1.1 100',
2732 'HTTP/1.0 200 Connection established');
2733 foreach ($skipHeaders as $hd) {
2734 $prefix = substr(
$data, 0, strlen($hd));
2735 if ($prefix == $hd)
return true;
2751 function decodeChunked($buffer, $lb){
2758 $chunkend = strpos($buffer, $lb);
2759 if ($chunkend == FALSE) {
2760 $this->
debug(
'no linebreak found in decodeChunked');
2763 $temp = substr($buffer,0,$chunkend);
2764 $chunk_size = hexdec( trim($temp) );
2765 $chunkstart = $chunkend + strlen($lb);
2767 while ($chunk_size > 0) {
2768 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2769 $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
2772 if ($chunkend == FALSE) {
2773 $chunk = substr($buffer,$chunkstart);
2776 $length += strlen($chunk);
2781 $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2785 $length += strlen($chunk);
2787 $chunkstart = $chunkend + strlen($lb);
2789 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2790 if ($chunkend == FALSE) {
2793 $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2794 $chunk_size = hexdec( trim($temp) );
2795 $chunkstart = $chunkend;
2808 function buildPayload(
$data, $cookie_str =
'') {
2814 $this->setHeader(
'Content-Length', strlen(
$data));
2822 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2823 $this->
debug(
"HTTP request: $req");
2824 $this->outgoing_payload =
"$req\r\n";
2827 foreach($this->outgoing_headers as $k => $v){
2829 $this->
debug(
"HTTP header: $hdr");
2830 $this->outgoing_payload .=
"$hdr\r\n";
2834 if ($cookie_str !=
'') {
2835 $hdr =
'Cookie: '.$cookie_str;
2836 $this->
debug(
"HTTP header: $hdr");
2837 $this->outgoing_payload .=
"$hdr\r\n";
2841 $this->outgoing_payload .=
"\r\n";
2844 $this->outgoing_payload .=
$data;
2855 function sendRequest(
$data, $cookies = NULL) {
2857 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2860 $this->buildPayload(
$data, $cookie_str);
2862 if ($this->io_method() ==
'socket') {
2864 if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2865 $this->
setError(
'couldn\'t write message data to socket');
2866 $this->
debug(
'couldn\'t write message data to socket');
2869 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2871 }
else if ($this->io_method() ==
'curl') {
2877 $curl_headers = array();
2878 foreach($this->outgoing_headers as $k => $v){
2879 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2880 $this->
debug(
"Skip cURL header $k: $v");
2882 $curl_headers[] =
"$k: $v";
2885 if ($cookie_str !=
'') {
2886 $curl_headers[] =
'Cookie: ' . $cookie_str;
2888 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2889 $this->
debug(
'set cURL HTTP headers');
2890 if ($this->request_method ==
"POST") {
2891 $this->setCurlOption(CURLOPT_POST, 1);
2892 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2893 $this->
debug(
'set cURL POST data');
2897 foreach ($this->ch_options as $key => $val) {
2898 $this->setCurlOption($key, $val);
2901 $this->
debug(
'set cURL payload');
2912 function getResponse(){
2913 $this->incoming_payload =
'';
2915 if ($this->io_method() ==
'socket') {
2918 while (!isset($lb)){
2921 if(feof($this->fp)) {
2922 $this->incoming_payload =
$data;
2923 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
2924 $this->
debug(
"received before EOF:\n" .
$data);
2925 $this->
setError(
'server failed to send headers');
2929 $tmp = fgets($this->fp, 256);
2930 $tmplen = strlen($tmp);
2931 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
2934 $this->incoming_payload =
$data;
2935 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
2936 $this->
debug(
"read before timeout: " .
$data);
2937 $this->
setError(
'socket read of headers timed out');
2942 $pos = strpos(
$data,
"\r\n\r\n");
2946 $pos = strpos(
$data,
"\n\n");
2952 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
2958 $this->incoming_payload .=
$data;
2959 $this->
debug(
'found end of headers after length ' . strlen(
$data));
2961 $header_data = trim(substr(
$data,0,$pos));
2962 $header_array = explode($lb,$header_data);
2963 $this->incoming_headers = array();
2964 $this->incoming_cookies = array();
2965 foreach($header_array as $header_line){
2966 $arr = explode(
':',$header_line, 2);
2967 if(count($arr) > 1){
2968 $header_name = strtolower(trim($arr[0]));
2969 $this->incoming_headers[$header_name] = trim($arr[1]);
2970 if ($header_name ==
'set-cookie') {
2972 $cookie = $this->parseCookie(trim($arr[1]));
2974 $this->incoming_cookies[] = $cookie;
2975 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
2977 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
2980 }
else if (isset($header_name)) {
2982 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
2987 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
2988 $content_length = 2147483647;
2990 $this->
debug(
"want to read chunked content");
2991 } elseif (isset($this->incoming_headers[
'content-length'])) {
2992 $content_length = $this->incoming_headers[
'content-length'];
2994 $this->
debug(
"want to read content of length $content_length");
2996 $content_length = 2147483647;
2998 $this->
debug(
"want to read content to EOF");
3003 $tmp = fgets($this->fp, 256);
3004 $tmplen = strlen($tmp);
3005 $this->
debug(
"read chunk line of $tmplen bytes");
3007 $this->incoming_payload =
$data;
3008 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3009 $this->
debug(
"read before timeout:\n" .
$data);
3010 $this->
setError(
'socket read of chunk length timed out');
3013 $content_length = hexdec(trim($tmp));
3014 $this->
debug(
"chunk length $content_length");
3017 while (($strlen < $content_length) && (!feof($this->fp))) {
3018 $readlen = min(8192, $content_length - $strlen);
3019 $tmp = fread($this->fp, $readlen);
3020 $tmplen = strlen($tmp);
3021 $this->
debug(
"read buffer of $tmplen bytes");
3022 if (($tmplen == 0) && (!feof($this->fp))) {
3023 $this->incoming_payload =
$data;
3024 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3025 $this->
debug(
"read before timeout:\n" .
$data);
3026 $this->
setError(
'socket read of body timed out');
3032 if ($chunked && ($content_length > 0)) {
3033 $tmp = fgets($this->fp, 256);
3034 $tmplen = strlen($tmp);
3035 $this->
debug(
"read chunk terminator of $tmplen bytes");
3037 $this->incoming_payload =
$data;
3038 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3039 $this->
debug(
"read before timeout:\n" .
$data);
3040 $this->
setError(
'socket read of chunk terminator timed out');
3044 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3045 if (feof($this->fp)) {
3046 $this->
debug(
'read to EOF');
3048 $this->
debug(
'read body of length ' . strlen(
$data));
3049 $this->incoming_payload .=
$data;
3050 $this->
debug(
'received a total of '.strlen($this->incoming_payload).
' bytes of data from server');
3054 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3055 (! $this->persistentConnection) || feof($this->fp)){
3058 $this->
debug(
'closed socket');
3062 if($this->incoming_payload ==
''){
3063 $this->
setError(
'no response from server');
3078 }
else if ($this->io_method() ==
'curl') {
3080 $this->
debug(
'send and receive with cURL');
3081 $this->incoming_payload = curl_exec($this->ch);
3082 $data = $this->incoming_payload;
3084 $cErr = curl_error($this->ch);
3086 $err =
'cURL ERROR: '.curl_errno($this->ch).
': '.$cErr.
'<br>';
3088 foreach(curl_getinfo($this->ch) as $k => $v){
3089 $err .=
"$k: $v<br>";
3093 curl_close($this->ch);
3101 $this->
debug(
'No cURL error, closing cURL');
3102 curl_close($this->ch);
3106 while ($this->isSkippableCurlHeader(
$data)) {
3107 $this->
debug(
"Found HTTP header to skip");
3108 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3110 } elseif($pos = strpos(
$data,
"\n\n") ) {
3118 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3119 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3121 } elseif($pos = strpos(
$data,
"\n\n") ) {
3128 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3130 } elseif( $pos = strpos(
$data,
"\n\n")) {
3133 $this->
debug(
'no proper separation of headers and document');
3134 $this->
setError(
'no proper separation of headers and document');
3137 $header_data = trim(substr(
$data,0,$pos));
3138 $header_array = explode($lb,$header_data);
3140 $this->
debug(
'found proper separation of headers and document');
3141 $this->
debug(
'cleaned data, stringlen: '.strlen(
$data));
3143 foreach ($header_array as $header_line) {
3144 $arr = explode(
':',$header_line,2);
3145 if(count($arr) > 1){
3146 $header_name = strtolower(trim($arr[0]));
3147 $this->incoming_headers[$header_name] = trim($arr[1]);
3148 if ($header_name ==
'set-cookie') {
3150 $cookie = $this->parseCookie(trim($arr[1]));
3152 $this->incoming_cookies[] = $cookie;
3153 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3155 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3158 }
else if (isset($header_name)) {
3160 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3165 $this->response_status_line = $header_array[0];
3166 $arr = explode(
' ', $this->response_status_line, 3);
3167 $http_version = $arr[0];
3168 $http_status = intval($arr[1]);
3169 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3172 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3173 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3174 $this->setURL($this->incoming_headers[
'location']);
3175 $this->tryagain =
true;
3180 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3181 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3182 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3183 $this->
debug(
'Server wants digest authentication');
3185 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3188 $digestElements = explode(
',', $digestString);
3189 foreach ($digestElements as $val) {
3190 $tempElement = explode(
'=', trim($val), 2);
3191 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3195 if (isset($digestRequest[
'nonce'])) {
3196 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3197 $this->tryagain =
true;
3201 $this->
debug(
'HTTP authentication failed');
3202 $this->
setError(
'HTTP authentication failed');
3207 ($http_status >= 300 && $http_status <= 307) ||
3208 ($http_status >= 400 && $http_status <= 417) ||
3209 ($http_status >= 501 && $http_status <= 505)
3211 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3216 if(isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
''){
3217 if(strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip'){
3219 if(function_exists(
'gzinflate')){
3223 $this->
debug(
'The gzinflate function exists');
3224 $datalen = strlen(
$data);
3225 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3226 if ($degzdata = @gzinflate(
$data)) {
3228 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3229 if (strlen(
$data) < $datalen) {
3231 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3232 if ($degzdata = @gzinflate(
$data)) {
3234 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3238 $this->
debug(
'Error using gzinflate to inflate the payload');
3239 $this->
setError(
'Error using gzinflate to inflate the payload');
3241 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3242 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3244 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3245 if (strlen(
$data) < $datalen) {
3247 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3248 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3250 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3254 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3255 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3261 $this->incoming_payload = $header_data.$lb.$lb.$data;
3263 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3264 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3267 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3268 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3271 $this->
debug(
'No Content-Encoding header');
3274 if(strlen(
$data) == 0){
3275 $this->
debug(
'no data after headers!');
3276 $this->
setError(
'no data present after HTTP headers');
3290 function setContentType($type, $charset =
false) {
3291 $this->setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3300 function usePersistentConnection(){
3301 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3304 $this->protocol_version =
'1.1';
3305 $this->persistentConnection =
true;
3306 $this->setHeader(
'Connection',
'Keep-Alive');
3320 function parseCookie($cookie_str) {
3321 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3322 $data = preg_split(
';', $cookie_str);
3323 $value_str =
$data[0];
3325 $cookie_param =
'domain=';
3326 $start = strpos($cookie_str, $cookie_param);
3328 $domain = substr($cookie_str, $start + strlen($cookie_param));
3329 $domain = substr($domain, 0, strpos($domain,
';'));
3334 $cookie_param =
'expires=';
3335 $start = strpos($cookie_str, $cookie_param);
3337 $expires = substr($cookie_str, $start + strlen($cookie_param));
3338 $expires = substr($expires, 0, strpos($expires,
';'));
3343 $cookie_param =
'path=';
3344 $start = strpos($cookie_str, $cookie_param);
3346 $path = substr($cookie_str, $start + strlen($cookie_param));
3347 $path = substr($path, 0, strpos($path,
';'));
3352 $cookie_param =
';secure;';
3353 if (strpos($cookie_str, $cookie_param) !== FALSE) {
3359 $sep_pos = strpos($value_str,
'=');
3362 $name = substr($value_str, 0, $sep_pos);
3363 $value = substr($value_str, $sep_pos + 1);
3364 $cookie= array(
'name' =>
$name,
3366 'domain' => $domain,
3368 'expires' => $expires,
3384 function getCookiesForRequest($cookies, $secure=
false) {
3386 if ((! is_null($cookies)) && (is_array($cookies))) {
3387 foreach ($cookies as $cookie) {
3388 if (! is_array($cookie)) {
3391 $this->
debug(
"check cookie for validity: ".$cookie[
'name'].
'='.$cookie[
'value']);
3392 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3393 if (strtotime($cookie[
'expires']) <= time()) {
3394 $this->
debug(
'cookie has expired');
3398 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3399 $domain = preg_quote($cookie[
'domain']);
3400 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3401 $this->
debug(
'cookie has different domain');
3405 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3406 $path = preg_quote($cookie[
'path']);
3407 if (! preg_match(
"'^$path.*'i", $this->path)) {
3408 $this->
debug(
'cookie is for a different path');
3412 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3413 $this->
debug(
'cookie is secure, transport is not');
3416 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3417 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3444 var $headers = array();
3456 var $requestHeaders =
'';
3462 var $requestHeader = NULL;
3474 var $requestSOAP =
'';
3480 var $methodURI =
'';
3486 var $methodname =
'';
3492 var $methodparams = array();
3498 var $SOAPAction =
'';
3504 var $xml_encoding =
'';
3510 var $decode_utf8 =
true;
3517 var $outgoing_headers = array();
3529 var $responseHeaders =
'';
3535 var $responseSOAP =
'';
3541 var $methodreturn =
false;
3547 var $methodreturnisliteralxml =
false;
3567 var $operations = array();
3579 var $externalWSDLURL =
false;
3585 var $debug_flag =
false;
3599 global $HTTP_SERVER_VARS;
3602 $this->
debug(
"_SERVER is defined:");
3604 } elseif (isset($HTTP_SERVER_VARS)) {
3605 $this->
debug(
"HTTP_SERVER_VARS is defined:");
3608 $this->
debug(
"Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3611 if (isset($debug)) {
3612 $this->
debug(
"In nusoap_server, set debug_flag=$debug based on global flag");
3613 $this->debug_flag = $debug;
3614 } elseif (isset(
$_SERVER[
'QUERY_STRING'])) {
3615 $qs = explode(
'&',
$_SERVER[
'QUERY_STRING']);
3616 foreach ($qs as $v) {
3617 if (substr($v, 0, 6) ==
'debug=') {
3618 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #1");
3619 $this->debug_flag = substr($v, 6);
3622 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3623 $qs = explode(
'&', $HTTP_SERVER_VARS[
'QUERY_STRING']);
3624 foreach ($qs as $v) {
3625 if (substr($v, 0, 6) ==
'debug=') {
3626 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #2");
3627 $this->debug_flag = substr($v, 6);
3634 $this->
debug(
"In nusoap_server, WSDL is specified");
3635 if (is_object($wsdl) && (get_class($wsdl) ==
'wsdl')) {
3636 $this->
wsdl = $wsdl;
3637 $this->externalWSDLURL = $this->
wsdl->
wsdl;
3638 $this->
debug(
'Use existing wsdl instance from ' . $this->externalWSDLURL);
3640 $this->
debug(
'Create wsdl from ' . $wsdl);
3642 $this->externalWSDLURL = $wsdl;
3647 die(
'WSDL ERROR: '.$err);
3658 function service(
$data){
3659 global $HTTP_SERVER_VARS;
3661 if (isset(
$_SERVER[
'QUERY_STRING'])) {
3663 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3664 $qs = $HTTP_SERVER_VARS[
'QUERY_STRING'];
3668 $this->
debug(
"In service, query string=$qs");
3670 if (preg_match(
'/wsdl/', $qs) ){
3671 $this->
debug(
"In service, this is a request for WSDL");
3672 if($this->externalWSDLURL){
3673 if (strpos($this->externalWSDLURL,
"://")!==
false) {
3674 header(
'Location: '.$this->externalWSDLURL);
3676 header(
"Content-Type: text/xml\r\n");
3677 $fp = fopen($this->externalWSDLURL,
'r');
3680 } elseif ($this->
wsdl) {
3681 header(
"Content-Type: text/xml; charset=ISO-8859-1\r\n");
3683 if ($this->debug_flag) {
3684 $this->
debug(
'wsdl:');
3689 header(
"Content-Type: text/html; charset=ISO-8859-1\r\n");
3690 print
"This service does not provide WSDL";
3693 $this->
debug(
"In service, there is no data, so return Web description");
3696 $this->
debug(
"In service, invoke the request");
3697 $this->parse_request(
$data);
3698 if (! $this->fault) {
3699 $this->invoke_method();
3701 if (! $this->fault) {
3702 $this->serialize_return();
3704 $this->send_response();
3720 function parse_http_headers() {
3721 global $HTTP_SERVER_VARS;
3723 $this->request =
'';
3724 $this->SOAPAction =
'';
3725 if(function_exists(
'getallheaders')){
3726 $this->
debug(
"In parse_http_headers, use getallheaders");
3727 $headers = getallheaders();
3728 foreach($headers as $k=>$v){
3729 $k = strtolower($k);
3730 $this->headers[$k] = $v;
3731 $this->request .=
"$k: $v\r\n";
3732 $this->
debug(
"$k: $v");
3735 if(isset($this->headers[
'soapaction'])){
3736 $this->SOAPAction = str_replace(
'"',
'',$this->headers[
'soapaction']);
3739 if(isset($this->headers[
'content-type']) && strpos($this->headers[
'content-type'],
'=')){
3740 $enc = str_replace(
'"',
'',substr(strstr($this->headers[
"content-type"],
'='),1));
3741 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
3742 $this->xml_encoding = strtoupper($enc);
3744 $this->xml_encoding =
'US-ASCII';
3748 $this->xml_encoding =
'ISO-8859-1';
3751 $this->
debug(
"In parse_http_headers, use _SERVER");
3753 if (substr($k, 0, 5) ==
'HTTP_') {
3754 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3756 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3758 if ($k ==
'soapaction') {
3761 $v = str_replace(
'"',
'', $v);
3762 $v = str_replace(
'\\',
'', $v);
3763 $this->SOAPAction = $v;
3764 }
else if ($k ==
'content-type') {
3766 if (strpos($v,
'=')) {
3767 $enc = substr(strstr($v,
'='), 1);
3768 $enc = str_replace(
'"',
'', $enc);
3769 $enc = str_replace(
'\\',
'', $enc);
3770 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3771 $this->xml_encoding = strtoupper($enc);
3773 $this->xml_encoding =
'US-ASCII';
3777 $this->xml_encoding =
'ISO-8859-1';
3780 $this->headers[$k] = $v;
3781 $this->request .=
"$k: $v\r\n";
3782 $this->
debug(
"$k: $v");
3784 } elseif (is_array($HTTP_SERVER_VARS)) {
3785 $this->
debug(
"In parse_http_headers, use HTTP_SERVER_VARS");
3786 foreach ($HTTP_SERVER_VARS as $k => $v) {
3787 if (substr($k, 0, 5) ==
'HTTP_') {
3788 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
3790 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k))); $k = strtolower($k);
3792 if ($k ==
'soapaction') {
3795 $v = str_replace(
'"',
'', $v);
3796 $v = str_replace(
'\\',
'', $v);
3797 $this->SOAPAction = $v;
3798 }
else if ($k ==
'content-type') {
3800 if (strpos($v,
'=')) {
3801 $enc = substr(strstr($v,
'='), 1);
3802 $enc = str_replace(
'"',
'', $enc);
3803 $enc = str_replace(
'\\',
'', $enc);
3804 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3805 $this->xml_encoding = strtoupper($enc);
3807 $this->xml_encoding =
'US-ASCII';
3811 $this->xml_encoding =
'ISO-8859-1';
3814 $this->headers[$k] = $v;
3815 $this->request .=
"$k: $v\r\n";
3816 $this->
debug(
"$k: $v");
3819 $this->
debug(
"In parse_http_headers, HTTP headers not accessible");
3820 $this->
setError(
"HTTP headers not accessible");
3846 function parse_request(
$data=
'') {
3847 $this->
debug(
'entering parse_request()');
3848 $this->parse_http_headers();
3849 $this->
debug(
'got character encoding: '.$this->xml_encoding);
3851 if (isset($this->headers[
'content-encoding']) && $this->headers[
'content-encoding'] !=
'') {
3852 $this->
debug(
'got content encoding: ' . $this->headers[
'content-encoding']);
3853 if ($this->headers[
'content-encoding'] ==
'deflate' || $this->headers[
'content-encoding'] ==
'gzip') {
3855 if (function_exists(
'gzuncompress')) {
3856 if ($this->headers[
'content-encoding'] ==
'deflate' && $degzdata = @gzuncompress(
$data)) {
3858 } elseif ($this->headers[
'content-encoding'] ==
'gzip' && $degzdata = gzinflate(substr(
$data, 10))) {
3861 $this->fault(
'SOAP-ENV:Client',
'Errors occurred when trying to decode the data');
3865 $this->fault(
'SOAP-ENV:Client',
'This Server does not support compressed data');
3870 $this->request .=
"\r\n".$data;
3871 $data = $this->parseRequest($this->headers,
$data);
3872 $this->requestSOAP =
$data;
3873 $this->
debug(
'leaving parse_request');
3893 function invoke_method() {
3894 $this->
debug(
'in invoke_method, methodname=' . $this->methodname .
' methodURI=' . $this->methodURI .
' SOAPAction=' . $this->SOAPAction);
3898 $this->
debug(
'in invoke_method, found WSDL operation=' . $this->methodname);
3902 $this->
debug(
'in invoke_method, found WSDL soapAction=' . $this->SOAPAction .
' for operation=' . $this->opData[
'name']);
3904 $this->methodname = $this->opData[
'name'];
3906 $this->
debug(
'in invoke_method, no WSDL for operation=' . $this->methodname);
3907 $this->fault(
'SOAP-ENV:Client',
"Operation '" . $this->methodname .
"' is not defined in the WSDL for this service");
3911 $this->
debug(
'in invoke_method, no WSDL to validate method');
3919 if (strpos($this->methodname,
'..') > 0) {
3921 }
else if (strpos($this->methodname,
'.') > 0) {
3927 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3928 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3930 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3931 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3932 $this->
debug(
"in invoke_method, class=$class method=$method delim=$delim");
3936 if ($class ==
'' && $this->
class !=
'')
3938 $class = $this->class;
3940 $method = $this->methodname;
3945 if (!function_exists($this->methodname)) {
3946 $this->
debug(
"in invoke_method, function '$this->methodname' not found!");
3947 $this->result =
'fault: method not found';
3948 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
3952 $method_to_compare = (substr(phpversion(), 0, 2) ==
'4.') ? strtolower($method) : $method;
3953 if (!in_array($method_to_compare, get_class_methods($class))) {
3954 $this->
debug(
"in invoke_method, method '$this->methodname' not found in class '$class'!");
3955 $this->result =
'fault: method not found';
3956 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
3963 if(! $this->verify_method($this->methodname,$this->methodparams)){
3965 $this->
debug(
'ERROR: request not verified against method signature');
3966 $this->result =
'fault: request failed validation against method signature';
3968 $this->fault(
'SOAP-ENV:Client',
"Operation '$this->methodname' not defined in service.");
3973 $this->
debug(
'in invoke_method, params:');
3975 $this->
debug(
"in invoke_method, calling '$this->methodname'");
3976 if (!function_exists(
'call_user_func_array')) {
3978 $this->
debug(
'in invoke_method, calling function using eval()');
3979 $funcCall =
"\$this->methodreturn = $this->methodname(";
3981 if ($delim ==
'..') {
3982 $this->
debug(
'in invoke_method, calling class method using eval()');
3983 $funcCall =
"\$this->methodreturn = ".$class.
"::".$method.
"(";
3985 $this->
debug(
'in invoke_method, calling instance method using eval()');
3987 $instname =
"\$inst_".time();
3988 $funcCall = $instname.
" = new ".$class.
"(); ";
3989 $funcCall .=
"\$this->methodreturn = ".$instname.
"->".$method.
"(";
3992 if ($this->methodparams) {
3993 foreach ($this->methodparams as
$param) {
3994 if (is_array($param) || is_object($param)) {
3995 $this->fault(
'SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
3998 $funcCall .=
"\"$param\",";
4000 $funcCall = substr($funcCall, 0, -1);
4003 $this->
debug(
'in invoke_method, function call: '.$funcCall);
4007 $this->
debug(
'in invoke_method, calling function using call_user_func_array()');
4008 $call_arg =
"$this->methodname";
4009 } elseif ($delim ==
'..') {
4010 $this->
debug(
'in invoke_method, calling class method using call_user_func_array()');
4011 $call_arg = array ($class, $method);
4013 $this->
debug(
'in invoke_method, calling instance method using call_user_func_array()');
4014 $instance =
new $class ();
4015 $call_arg = array(&$instance, $method);
4017 if (is_array($this->methodparams)) {
4018 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4020 $this->methodreturn = call_user_func_array($call_arg, array());
4023 $this->
debug(
'in invoke_method, methodreturn:');
4025 $this->
debug(
"in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
4039 function serialize_return() {
4040 $this->
debug(
'Entering serialize_return methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4042 if (isset($this->methodreturn) && ((get_class((
object)$this->methodreturn) ==
'soap_fault') || (get_class((
object)$this->methodreturn) ==
'nusoap_fault'))) {
4043 $this->
debug(
'got a fault object from method');
4044 $this->fault = $this->methodreturn;
4046 } elseif ($this->methodreturnisliteralxml) {
4047 $return_val = $this->methodreturn;
4050 $this->
debug(
'got a(n) '.gettype($this->methodreturn).
' from method');
4051 $this->
debug(
'serializing return value');
4053 if (
sizeof($this->opData[
'output'][
'parts']) > 1) {
4054 $this->
debug(
'more than one output part, so use the method return unchanged');
4055 $opParams = $this->methodreturn;
4056 } elseif (
sizeof($this->opData[
'output'][
'parts']) == 1) {
4057 $this->
debug(
'exactly one output part, so wrap the method return in a simple array');
4062 $opParams = array($this->methodreturn);
4068 $this->
debug(
'got wsdl error: '.$errstr);
4069 $this->fault(
'SOAP-ENV:Server',
'unable to serialize result');
4073 if (isset($this->methodreturn)) {
4074 $return_val = $this->
serialize_val($this->methodreturn,
'return');
4077 $this->
debug(
'in absence of WSDL, assume void return for backward compatibility');
4081 $this->
debug(
'return value:');
4084 $this->
debug(
'serializing response');
4086 $this->
debug(
'have WSDL for serialization: style is ' . $this->opData[
'style']);
4087 if ($this->opData[
'style'] ==
'rpc') {
4088 $this->
debug(
'style is rpc for serialization: use is ' . $this->opData[
'output'][
'use']);
4089 if ($this->opData[
'output'][
'use'] ==
'literal') {
4091 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4093 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4096 $this->
debug(
'style is not rpc for serialization: assume document');
4097 $payload = $return_val;
4100 $this->
debug(
'do not have WSDL for serialization: assume rpc/encoded');
4101 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4103 $this->result =
'successful';
4108 if (isset($opData[
'output'][
'encodingStyle'])) {
4109 $encodingStyle = $opData[
'output'][
'encodingStyle'];
4111 $encodingStyle =
'';
4114 $this->responseSOAP = $this->
serializeEnvelope($payload,$this->responseHeaders,$this->
wsdl->usedNamespaces,$this->opData[
'style'],$this->opData[
'output'][
'use'],$encodingStyle);
4116 $this->responseSOAP = $this->
serializeEnvelope($payload,$this->responseHeaders);
4118 $this->
debug(
"Leaving serialize_return");
4131 function send_response() {
4132 $this->
debug(
'Enter send_response');
4134 $payload = $this->fault->serialize();
4135 $this->outgoing_headers[] =
"HTTP/1.0 500 Internal Server Error";
4136 $this->outgoing_headers[] =
"Status: 500 Internal Server Error";
4138 $payload = $this->responseSOAP;
4146 if(isset($this->debug_flag) && $this->debug_flag){
4149 $this->outgoing_headers[] =
"Server: $this->title Server v$this->version";
4150 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
4151 $this->outgoing_headers[] =
"X-SOAP-Server: $this->title/$this->version (".$rev[1].
")";
4154 $payload = $this->getHTTPBody($payload);
4155 $type = $this->getHTTPContentType();
4156 $charset = $this->getHTTPContentTypeCharset();
4157 $this->outgoing_headers[] =
"Content-Type: $type" . ($charset ?
'; charset=' . $charset :
'');
4161 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers[
'accept-encoding'])) {
4162 if (strstr($this->headers[
'accept-encoding'],
'gzip')) {
4163 if (function_exists(
'gzencode')) {
4164 if (isset($this->debug_flag) && $this->debug_flag) {
4165 $payload .=
"<!-- Content being gzipped -->";
4167 $this->outgoing_headers[] =
"Content-Encoding: gzip";
4168 $payload = gzencode($payload);
4170 if (isset($this->debug_flag) && $this->debug_flag) {
4171 $payload .=
"<!-- Content will not be gzipped: no gzencode -->";
4174 } elseif (strstr($this->headers[
'accept-encoding'],
'deflate')) {
4178 if (function_exists(
'gzdeflate')) {
4179 if (isset($this->debug_flag) && $this->debug_flag) {
4180 $payload .=
"<!-- Content being deflated -->";
4182 $this->outgoing_headers[] =
"Content-Encoding: deflate";
4183 $payload = gzdeflate($payload);
4185 if (isset($this->debug_flag) && $this->debug_flag) {
4186 $payload .=
"<!-- Content will not be deflated: no gzcompress -->";
4192 $this->outgoing_headers[] =
"Content-Length: ".strlen($payload);
4193 reset($this->outgoing_headers);
4194 foreach($this->outgoing_headers as $hdr){
4195 header($hdr,
false);
4198 $this->response = join(
"\r\n",$this->outgoing_headers).
"\r\n\r\n".$payload;
4210 function verify_method($operation,$request){
4211 if(isset($this->
wsdl) && is_object($this->
wsdl)){
4215 } elseif(isset($this->operations[$operation])){
4229 function parseRequest($headers,
$data) {
4230 $this->
debug(
'Entering parseRequest() for data of length ' . strlen(
$data) .
' and type ' . $headers[
'content-type']);
4231 if (!strstr($headers[
'content-type'],
'text/xml')) {
4232 $this->
setError(
'Request not of type text/xml');
4235 if (strpos($headers[
'content-type'],
'=')) {
4236 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
4237 $this->
debug(
'Got response encoding: ' . $enc);
4238 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
4239 $this->xml_encoding = strtoupper($enc);
4241 $this->xml_encoding =
'US-ASCII';
4245 $this->xml_encoding =
'ISO-8859-1';
4247 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
4251 $this->
debug(
"parser debug: \n".$parser->getDebug());
4253 if($err = $parser->getError()){
4254 $this->result =
'fault: error in msg parsing: '.$err;
4255 $this->fault(
'SOAP-ENV:Client',
"error in msg parsing:\n".$err);
4259 $this->methodURI = $parser->root_struct_namespace;
4260 $this->methodname = $parser->root_struct_name;
4261 $this->
debug(
'methodname: '.$this->methodname.
' methodURI: '.$this->methodURI);
4262 $this->
debug(
'calling parser->get_soapbody()');
4263 $this->methodparams = $parser->get_soapbody();
4265 $this->requestHeaders = $parser->getHeaders();
4267 $this->requestHeader = $parser->get_soapheader();
4269 $this->document = $parser->document;
4280 function getHTTPBody($soapmsg) {
4292 function getHTTPContentType() {
4305 function getHTTPContentTypeCharset() {
4318 function add_to_map($methodname,
$in,
$out){
4319 $this->operations[$methodname] = array(
'name' => $methodname,
'in' =>
$in,
'out' =>
$out);
4336 function register(
$name,
$in=array(),
$out=array(),
$namespace=
false,$soapaction=
false,$style=
false,$use=
false,$documentation=
'',$encodingStyle=
''){
4337 global $HTTP_SERVER_VARS;
4339 if($this->externalWSDLURL){
4340 die(
'You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4343 die(
'You must specify a name when you register an operation');
4345 if (!is_array($in)) {
4346 die(
'You must provide an array for operation inputs');
4348 if (!is_array(
$out)) {
4349 die(
'You must provide an array for operation outputs');
4353 if(
false == $soapaction) {
4355 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4357 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4358 } elseif (isset($HTTP_SERVER_VARS)) {
4359 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4360 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4361 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4363 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4365 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4370 $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4372 if(
false == $style) {
4378 if ($use ==
'encoded' && $encodingStyle =
'') {
4379 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
4382 $this->operations[
$name] = array(
4387 'soapaction' => $soapaction,
4405 function fault($faultcode,$faultstring,$faultactor=
'',$faultdetail=
''){
4406 if ($faultdetail ==
'' && $this->debug_flag) {
4409 $this->fault =
new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
4424 function configureWSDL($serviceName,
$namespace =
false,$endpoint =
false,$style=
'rpc', $transport =
'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace =
false)
4426 global $HTTP_SERVER_VARS;
4429 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4430 $SERVER_PORT =
$_SERVER[
'SERVER_PORT'];
4432 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4433 } elseif (isset($HTTP_SERVER_VARS)) {
4434 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4435 $SERVER_PORT = $HTTP_SERVER_VARS[
'SERVER_PORT'];
4436 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4437 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4439 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4442 $colon = strpos($SERVER_NAME,
":");
4444 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4446 if ($SERVER_PORT == 80) {
4449 $SERVER_PORT =
':' . $SERVER_PORT;
4452 $namespace =
"http://$SERVER_NAME/soap/$serviceName";
4455 if(
false == $endpoint) {
4456 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4461 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4464 if(
false == $schemaTargetNamespace) {
4469 $this->
wsdl->serviceName = $serviceName;
4470 $this->
wsdl->endpoint = $endpoint;
4472 $this->
wsdl->namespaces[
'soap'] =
'http://schemas.xmlsoap.org/wsdl/soap/';
4473 $this->
wsdl->namespaces[
'wsdl'] =
'http://schemas.xmlsoap.org/wsdl/';
4475 $this->
wsdl->namespaces[
'types'] = $schemaTargetNamespace;
4478 if ($style ==
'document') {
4479 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo[
'elementFormDefault'] =
'qualified';
4481 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4482 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4483 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4484 $this->
wsdl->bindings[$serviceName.
'Binding'] = array(
4485 'name'=>$serviceName.
'Binding',
4487 'transport'=>$transport,
4488 'portType'=>$serviceName.
'PortType');
4489 $this->
wsdl->ports[$serviceName.
'Port'] = array(
4490 'binding'=>$serviceName.
'Binding',
4491 'location'=>$endpoint,
4492 'bindingType'=>
'http://schemas.xmlsoap.org/wsdl/soap/');
4519 var $schemas = array();
4521 var $message = array();
4522 var $complexTypes = array();
4524 var $currentMessage;
4525 var $currentOperation;
4526 var $portTypes = array();
4527 var $currentPortType;
4528 var $bindings = array();
4529 var $currentBinding;
4530 var $ports = array();
4532 var $opData = array();
4534 var $documentation =
false;
4537 var $import = array();
4542 var $depth_array = array();
4544 var $proxyhost =
'';
4545 var $proxyport =
'';
4546 var $proxyusername =
'';
4547 var $proxypassword =
'';
4549 var $response_timeout = 30;
4550 var $curl_options = array();
4551 var $use_curl =
false;
4556 var $certRequest = array();
4572 function __construct($wsdl =
'',$proxyhost=
false,$proxyport=
false,$proxyusername=
false,$proxypassword=
false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=
false){
4574 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4575 $this->proxyhost = $proxyhost;
4576 $this->proxyport = $proxyport;
4577 $this->proxyusername = $proxyusername;
4578 $this->proxypassword = $proxypassword;
4579 $this->timeout = $timeout;
4580 $this->response_timeout = $response_timeout;
4581 if (is_array($curl_options))
4582 $this->curl_options = $curl_options;
4583 $this->use_curl = $use_curl;
4584 $this->fetchWSDL($wsdl);
4592 function fetchWSDL($wsdl) {
4593 $this->
debug(
"parse and process WSDL path=$wsdl");
4594 $this->
wsdl = $wsdl;
4596 if ($this->
wsdl !=
"") {
4597 $this->parseWSDL($this->
wsdl);
4601 $imported_urls = array();
4603 while ($imported > 0) {
4606 foreach ($this->schemas as $ns => $list) {
4607 foreach ($list as $xs) {
4608 $wsdlparts = parse_url($this->
wsdl);
4609 foreach ($xs->imports as $ns2 => $list2) {
4610 for ($ii = 0; $ii < count($list2); $ii++) {
4611 if (! $list2[$ii][
'loaded']) {
4612 $this->schemas[$ns]->imports[$ns2][$ii][
'loaded'] =
true;
4613 $url = $list2[$ii][
'location'];
4615 $urlparts = parse_url($url);
4616 if (!isset($urlparts[
'host'])) {
4617 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' .$wsdlparts[
'port'] :
'') .
4618 substr($wsdlparts[
'path'],0,strrpos($wsdlparts[
'path'],
'/') + 1) .$urlparts[
'path'];
4620 if (! in_array($url, $imported_urls)) {
4621 $this->parseWSDL($url);
4623 $imported_urls[] =
$url;
4626 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4634 $wsdlparts = parse_url($this->
wsdl);
4635 foreach ($this->
import as $ns => $list) {
4636 for ($ii = 0; $ii < count($list); $ii++) {
4637 if (! $list[$ii][
'loaded']) {
4638 $this->
import[$ns][$ii][
'loaded'] =
true;
4639 $url = $list[$ii][
'location'];
4641 $urlparts = parse_url($url);
4642 if (!isset($urlparts[
'host'])) {
4643 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4644 substr($wsdlparts[
'path'],0,strrpos($wsdlparts[
'path'],
'/') + 1) .$urlparts[
'path'];
4646 if (! in_array($url, $imported_urls)) {
4647 $this->parseWSDL($url);
4649 $imported_urls[] =
$url;
4652 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4659 foreach($this->bindings as $binding => $bindingData) {
4660 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4661 foreach($bindingData[
'operations'] as $operation =>
$data) {
4662 $this->
debug(
'post-parse data gathering for ' . $operation);
4663 $this->bindings[$binding][
'operations'][$operation][
'input'] =
4664 isset($this->bindings[$binding][
'operations'][$operation][
'input']) ?
4665 array_merge($this->bindings[$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4666 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4667 $this->bindings[$binding][
'operations'][$operation][
'output'] =
4668 isset($this->bindings[$binding][
'operations'][$operation][
'output']) ?
4669 array_merge($this->bindings[$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4670 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4671 if(isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ])){
4672 $this->bindings[$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ];
4674 if(isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ])){
4675 $this->bindings[$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ];
4678 if (isset($bindingData[
'style']) && !isset($this->bindings[$binding][
'operations'][$operation][
'style'])) {
4679 $this->bindings[$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4681 $this->bindings[$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4682 $this->bindings[$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4683 $this->bindings[$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4695 function parseWSDL($wsdl =
'') {
4696 $this->
debug(
"parse WSDL at path=$wsdl");
4699 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4700 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4705 $wsdl_props = parse_url($wsdl);
4707 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4708 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4711 $tr->request_method =
'GET';
4712 $tr->useSOAPAction =
false;
4713 if($this->proxyhost && $this->proxyport){
4714 $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
4716 if ($this->authtype !=
'') {
4717 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4719 $tr->setEncoding(
'gzip, deflate');
4720 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4725 if($err = $tr->getError() ){
4726 $errstr =
'HTTP ERROR: '.$err;
4727 $this->
debug($errstr);
4733 $this->
debug(
"got WSDL URL");
4736 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4737 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4741 $this->
debug(
'getting WSDL file ' . $path);
4742 if ($fp = @fopen($path,
'r')) {
4744 while (
$data = fread($fp, 32768)) {
4745 $wsdl_string .=
$data;
4749 $errstr =
"Bad path to WSDL file $path";
4750 $this->
debug($errstr);
4755 $this->
debug(
'Parse WSDL');
4758 $this->parser = xml_parser_create();
4761 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4763 xml_set_object($this->parser, $this);
4765 xml_set_element_handler($this->parser,
'start_element',
'end_element');
4766 xml_set_character_data_handler($this->parser,
'character_data');
4768 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4771 'XML error parsing WSDL from %s on line %d: %s',
4773 xml_get_current_line_number($this->parser),
4774 xml_error_string(xml_get_error_code($this->parser))
4776 $this->
debug($errstr);
4777 $this->
debug(
"XML payload:\n" . $wsdl_string);
4782 xml_parser_free($this->parser);
4783 $this->
debug(
'Parsing WSDL done');
4799 function start_element($parser,
$name, $attrs)
4801 if ($this->status ==
'schema') {
4802 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4803 $this->
appendDebug($this->currentSchema->getDebug());
4804 $this->currentSchema->clearDebug();
4805 } elseif (preg_match(
'/schema$/',
$name)) {
4806 $this->
debug(
'Parsing WSDL schema');
4808 $this->status =
'schema';
4810 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4811 $this->
appendDebug($this->currentSchema->getDebug());
4812 $this->currentSchema->clearDebug();
4815 $pos = $this->position++;
4816 $depth = $this->depth++;
4818 $this->depth_array[$depth] = $pos;
4819 $this->message[$pos] = array(
'cdata' =>
'');
4821 if (count($attrs) > 0) {
4823 foreach($attrs as $k => $v) {
4824 if (preg_match(
'/^xmlns/',$k)) {
4825 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4826 $this->namespaces[$ns_prefix] = $v;
4828 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4830 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4831 $this->XMLSchemaVersion = $v;
4832 $this->namespaces[
'xsi'] = $v .
'-instance';
4837 foreach($attrs as $k => $v) {
4838 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4839 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4840 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4849 if (preg_match(
'/:/',
$name)) {
4851 $prefix = substr(
$name, 0, strpos(
$name,
':'));
4853 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4859 switch ($this->status) {
4861 if (
$name ==
'part') {
4862 if (isset($attrs[
'type'])) {
4863 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4864 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4866 if (isset($attrs[
'element'])) {
4867 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4868 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4875 $this->currentPortOperation = $attrs[
'name'];
4876 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
4877 if (isset($attrs[
'parameterOrder'])) {
4878 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
4881 case 'documentation':
4882 $this->documentation =
true;
4886 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
4887 $this->portTypes[$this->currentPortType][$this->currentPortOperation][
$name][
'message'] = $m;
4895 if (isset($attrs[
'style'])) {
4896 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
4898 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4901 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
4904 if (isset($attrs[
'soapAction'])) {
4905 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
4907 if (isset($attrs[
'style'])) {
4908 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
4910 if (isset($attrs[
'name'])) {
4911 $this->currentOperation = $attrs[
'name'];
4912 $this->
debug(
"current binding operation: $this->currentOperation");
4913 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
4914 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
4915 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
4919 $this->opStatus =
'input';
4922 $this->opStatus =
'output';
4925 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
4926 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
4928 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
4936 $this->currentPort = $attrs[
'name'];
4937 $this->
debug(
'current port: ' . $this->currentPort);
4938 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
4942 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
4943 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
4944 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
4945 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
4953 if (isset($attrs[
'location'])) {
4954 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
4955 $this->
debug(
'parsing import ' . $attrs[
'namespace'].
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]).
')');
4957 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
4959 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $attrs[
'namespace'];
4961 $this->
debug(
'parsing import ' . $attrs[
'namespace'].
' - [no location] (' . count($this->
import[$attrs[
'namespace']]).
')');
4969 $this->status =
'message';
4970 $this->messages[$attrs[
'name']] = array();
4971 $this->currentMessage = $attrs[
'name'];
4974 $this->status =
'portType';
4975 $this->portTypes[$attrs[
'name']] = array();
4976 $this->currentPortType = $attrs[
'name'];
4979 if (isset($attrs[
'name'])) {
4981 if (strpos($attrs[
'name'],
':')) {
4982 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
4984 $this->currentBinding = $attrs[
'name'];
4986 $this->status =
'binding';
4987 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
4988 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
4992 $this->serviceName = $attrs[
'name'];
4993 $this->status =
'service';
4994 $this->
debug(
'current service: ' . $this->serviceName);
4997 foreach ($attrs as
$name => $value) {
4998 $this->wsdl_info[
$name] = $value;
5012 function end_element($parser,
$name){
5014 if ( preg_match(
'/schema$/',
$name)) {
5016 $this->
appendDebug($this->currentSchema->getDebug());
5017 $this->currentSchema->clearDebug();
5018 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5019 $this->
debug(
'Parsing WSDL schema done');
5021 if ($this->status ==
'schema') {
5022 $this->currentSchema->schemaEndElement($parser,
$name);
5028 if ($this->documentation) {
5031 $this->documentation =
false;
5042 function character_data($parser,
$data)
5044 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5045 if (isset($this->message[$pos][
'cdata'])) {
5046 $this->message[$pos][
'cdata'] .=
$data;
5048 if ($this->documentation) {
5049 $this->documentation .=
$data;
5062 function setCredentials($username, $password, $authtype =
'basic', $certRequest = array()) {
5063 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5065 $this->username = $username;
5067 $this->authtype = $authtype;
5068 $this->certRequest = $certRequest;
5071 function getBindingData($binding)
5073 if (is_array($this->bindings[$binding])) {
5074 return $this->bindings[$binding];
5085 function getOperations($bindingType =
'soap') {
5087 if ($bindingType ==
'soap') {
5088 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5089 } elseif ($bindingType ==
'soap12') {
5090 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5093 foreach($this->ports as $port => $portData) {
5095 if ($portData[
'bindingType'] == $bindingType) {
5100 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5101 $ops = array_merge ($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5116 function getOperationData($operation, $bindingType =
'soap')
5118 if ($bindingType ==
'soap') {
5119 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5120 } elseif ($bindingType ==
'soap12') {
5121 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5124 foreach($this->ports as $port => $portData) {
5126 if ($portData[
'bindingType'] == $bindingType) {
5129 foreach(array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5131 if ($operation == $bOperation) {
5132 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5148 function getOperationDataForSoapAction($soapAction, $bindingType =
'soap') {
5149 if ($bindingType ==
'soap') {
5150 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5151 } elseif ($bindingType ==
'soap12') {
5152 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5155 foreach($this->ports as $port => $portData) {
5157 if ($portData[
'bindingType'] == $bindingType) {
5159 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5160 if ($opData[
'soapAction'] == $soapAction) {
5186 function getTypeDef($type, $ns) {
5187 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5188 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5189 $ns = $this->namespaces[
'tns'];
5190 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5192 if (!isset($this->schemas[$ns])) {
5193 foreach ($this->schemas as $ns0 => $schema0) {
5194 if (strcasecmp($ns, $ns0) == 0) {
5195 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5201 if (isset($this->schemas[$ns])) {
5202 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5203 for (
$i = 0;
$i < count($this->schemas[$ns]);
$i++) {
5204 $xs = &$this->schemas[$ns][
$i];
5205 $t = $xs->getTypeDef($type);
5209 if (!isset($t[
'phpType'])) {
5211 $uqType = substr($t[
'type'], strrpos($t[
'type'],
':') + 1);
5212 $ns = substr($t[
'type'], 0, strrpos($t[
'type'],
':'));
5213 $etype = $this->getTypeDef($uqType, $ns);
5215 $this->
debug(
"found type for [element] $type:");
5217 if (isset($etype[
'phpType'])) {
5218 $t[
'phpType'] = $etype[
'phpType'];
5220 if (isset($etype[
'elements'])) {
5221 $t[
'elements'] = $etype[
'elements'];
5223 if (isset($etype[
'attrs'])) {
5224 $t[
'attrs'] = $etype[
'attrs'];
5232 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5242 function webDescription(){
5243 global $HTTP_SERVER_VARS;
5247 } elseif (isset($HTTP_SERVER_VARS)) {
5248 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5250 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5253 $PHP_SELF = filter_var($PHP_SELF, FILTER_SANITIZE_STRING);
5257 <html><head><title>NuSOAP: '.$this->serviceName.
'</title> 5258 <style type="text/css"> 5259 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5260 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5261 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5262 ul { margin-top: 10px; margin-left: 20px; } 5263 li { list-style-type: none; margin-top: 10px; color: #000000; } 5265 margin-left: 0px; padding-bottom: 2em; } 5267 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5268 margin-top: 10px; margin-left: 0px; color: #000000; 5269 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5271 font-family: arial; font-size: 26px; color: #ffffff; 5272 background-color: #999999; width: 105%; margin-left: 0px; 5273 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5275 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5276 font-family: arial; overflow: hidden; width: 600; 5277 padding: 20px; font-size: 10px; background-color: #999999; 5278 layer-background-color:#FFFFFF; } 5279 a,a:active { color: charcoal; font-weight: bold; } 5280 a:visited { color: #666666; font-weight: bold; } 5281 a:hover { color: cc3300; font-weight: bold; } 5283 <script language="JavaScript" type="text/javascript"> 5285 // POP-UP CAPTIONS... 5286 function lib_bwcheck(){ //Browsercheck (needed) 5287 this.ver=navigator.appVersion 5288 this.agent=navigator.userAgent 5289 this.dom=document.getElementById?1:0 5290 this.opera5=this.agent.indexOf("Opera 5")>-1 5291 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5292 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5293 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5294 this.ie=this.ie4||this.ie5||this.ie6 5295 this.mac=this.agent.indexOf("Mac")>-1 5296 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5297 this.ns4=(document.layers && !this.dom)?1:0; 5298 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5301 var bw = new lib_bwcheck() 5302 //Makes crossbrowser object. 5303 function makeObj(obj){ 5304 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5305 if(!this.evnt) return false 5306 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5307 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5308 this.writeIt=b_writeIt; 5311 // A unit of measure that will be added when setting the position of a layer. 5312 //var px = bw.ns4||window.opera?"":"px"; 5313 function b_writeIt(text){ 5314 if (bw.ns4){this.wref.write(text);this.wref.close()} 5315 else this.wref.innerHTML = text 5317 //Shows the messages 5319 function popup(divid){ 5320 if(oDesc = new makeObj(divid)){ 5321 oDesc.css.visibility = "visible" 5324 function popout(){ // Hides message 5325 if(oDesc) oDesc.css.visibility = "hidden" 5333 <div class=title>'.$this->serviceName.
'</div> 5335 <p>View the <a href="'.$PHP_SELF.
'?wsdl">WSDL</a> for the service. 5336 Click on an operation name to view it's details.</p> 5338 foreach($this->getOperations() as $op =>
$data){
5340 if (isset(
$data[
'endpoint'])) {
5341 $data[
'endpoint'] = filter_var(
$data[
'endpoint'], FILTER_SANITIZE_STRING);
5344 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5346 $b .=
"<div id='$op' class='hidden'> 5347 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5348 foreach(
$data as $donnie => $marie){
5349 if($donnie ==
'input' || $donnie ==
'output'){
5350 $b .=
"<font color='white'>".ucfirst($donnie).
':</font><br>';
5351 foreach($marie as $captain => $tenille){
5352 if($captain ==
'parts'){
5353 $b .=
" $captain:<br>";
5355 foreach($tenille as $joanie => $chachi){
5356 $b .=
" $joanie: $chachi<br>";
5360 $b .=
" $captain: $tenille<br>";
5364 $b .=
"<font color='white'>".ucfirst($donnie).
":</font> $marie<br>";
5372 </div></body></html>';
5385 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5386 $xml .=
"\n<definitions";
5387 foreach($this->namespaces as $k => $v) {
5388 $xml .=
" xmlns:$k=\"$v\"";
5391 if (isset($this->namespaces[
'wsdl'])) {
5392 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5394 if (isset($this->namespaces[
'tns'])) {
5395 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5399 if (
sizeof($this->
import) > 0) {
5400 foreach($this->
import as $ns => $list) {
5401 foreach ($list as $ii) {
5402 if ($ii[
'location'] !=
'') {
5403 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5405 $xml .=
'<import namespace="' . $ns .
'" />';
5411 if (count($this->schemas)>=1) {
5412 $xml .=
"\n<types>\n";
5413 foreach ($this->schemas as $ns => $list) {
5414 foreach ($list as $xs) {
5415 $xml .= $xs->serializeSchema();
5421 if (count($this->messages) >= 1) {
5422 foreach($this->messages as $msgName => $msgParts) {
5423 $xml .=
"\n<message name=\"" . $msgName .
'">';
5424 if(is_array($msgParts)){
5425 foreach($msgParts as $partName => $partType) {
5427 if (strpos($partType,
':')) {
5429 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5431 $typePrefix =
'xsd';
5433 foreach($this->typemap as $ns => $types) {
5434 if (isset($types[$partType])) {
5438 if (!isset($typePrefix)) {
5439 die(
"$partType has no namespace!");
5444 $typeDef = $this->getTypeDef($localPart, $ns);
5445 if ($typeDef[
'typeClass'] ==
'element') {
5446 $elementortype =
'element';
5447 if (substr($localPart, -1) ==
'^') {
5448 $localPart = substr($localPart, 0, -1);
5451 $elementortype =
'type';
5453 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5456 $xml .=
'</message>';
5460 if (count($this->bindings) >= 1) {
5463 foreach($this->bindings as $bindingName => $attrs) {
5464 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5465 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5466 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5467 foreach($attrs[
'operations'] as $opName => $opParts) {
5468 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5469 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="'. $opParts[
'style'] .
'"/>';
5470 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5471 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5475 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5476 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5477 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5481 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5482 $binding_xml .=
"\n" .
' </operation>';
5483 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5484 if (isset($opParts[
'parameterOrder'])) {
5485 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5487 $portType_xml .=
'>';
5488 if(isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5489 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5491 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5492 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5493 $portType_xml .=
"\n" .
' </operation>';
5495 $portType_xml .=
"\n" .
'</portType>';
5496 $binding_xml .=
"\n" .
'</binding>';
5498 $xml .= $portType_xml . $binding_xml;
5501 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5502 $has_client = isset(
$_GET[
'client_id']);
5503 if (count($this->ports) >= 1) {
5504 foreach($this->ports as $pName => $attrs) {
5505 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5506 $address = $attrs[
'location'] . ($debug || $has_client ?
"?" :
"")
5507 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5508 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5509 $xml .=
"\n" .
' <soap:address location="' . $address.
'"/>';
5510 $xml .=
"\n" .
' </port>';
5514 $xml .=
"\n" .
'</service>';
5515 return $xml .
"\n</definitions>";
5527 function parametersMatchWrapped($type, &$parameters) {
5528 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5532 if (strpos($type,
':')) {
5533 $uqType = substr($type, strrpos($type,
':') + 1);
5534 $ns = substr($type, 0, strrpos($type,
':'));
5535 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5538 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5543 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5549 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5550 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5553 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5555 if (substr($uqType, -1) ==
'^') {
5556 $uqType = substr($uqType, 0, -1);
5558 $phpType = $typeDef[
'phpType'];
5559 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5560 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5563 if ($phpType !=
'struct') {
5564 $this->
debug(
"in parametersMatchWrapped: not a struct");
5569 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5573 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5574 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5577 foreach ($typeDef[
'elements'] as
$name => $attrs) {
5579 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5580 $parameters[
$name] = $parameters[$elements];
5581 unset($parameters[$elements]);
5583 } elseif (isset($parameters[
$name])) {
5584 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5587 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5592 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5593 if ($matches == 0) {
5601 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5602 return count($parameters) == 0;
5620 function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap') {
5621 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5624 if ($direction !=
'input' && $direction !=
'output') {
5625 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5626 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5629 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5630 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5631 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5634 $this->
debug(
'in serializeRPCParameters: opData:');
5638 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5639 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5640 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5641 $enc_style = $encodingStyle;
5646 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5647 $parts = &$opData[$direction][
'parts'];
5648 $part_count =
sizeof($parts);
5649 $style = $opData[
'style'];
5650 $use = $opData[$direction][
'use'];
5651 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5652 if (is_array($parameters)) {
5654 $parameter_count = count($parameters);
5655 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5657 if ($style ==
'document' && $use ==
'literal' && $part_count == 1 && isset($parts[
'parameters'])) {
5658 $this->
debug(
'check whether the caller has wrapped the parameters');
5659 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5660 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5661 if ($this->parametersMatchWrapped($parts[
'parameters'], $parameters)) {
5662 $this->
debug(
'wrap the parameters for the caller');
5663 $parameters = array(
'parameters' => $parameters);
5664 $parameter_count = 1;
5668 foreach ($parts as
$name => $type) {
5669 $this->
debug(
"serializing part $name of type $type");
5671 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5672 $encodingStyle = $opData[$direction][
'encodingStyle'];
5673 $enc_style = $encodingStyle;
5679 if ($parametersArrayType ==
'arraySimple') {
5680 $p = array_shift($parameters);
5681 $this->
debug(
'calling serializeType w/indexed param');
5682 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5683 } elseif (isset($parameters[
$name])) {
5684 $this->
debug(
'calling serializeType w/named param');
5685 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5688 $this->
debug(
'calling serializeType w/null param');
5689 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5693 $this->
debug(
'no parameters passed.');
5696 $this->
debug(
"serializeRPCParameters returning: $xml");
5714 function serializeParameters($operation, $direction, $parameters)
5716 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5719 if ($direction !=
'input' && $direction !=
'output') {
5720 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5721 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5724 if (!$opData = $this->getOperationData($operation)) {
5725 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5726 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5729 $this->
debug(
'opData:');
5733 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5734 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5735 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5736 $enc_style = $encodingStyle;
5741 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5743 $use = $opData[$direction][
'use'];
5744 $this->
debug(
"use=$use");
5745 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5746 if (is_array($parameters)) {
5748 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5749 foreach($opData[$direction][
'parts'] as
$name => $type) {
5750 $this->
debug(
'serializing part "'.
$name.
'" of type "'.$type.
'"');
5752 if(isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5753 $encodingStyle = $opData[$direction][
'encodingStyle'];
5754 $enc_style = $encodingStyle;
5760 if ($parametersArrayType ==
'arraySimple') {
5761 $p = array_shift($parameters);
5762 $this->
debug(
'calling serializeType w/indexed param');
5763 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5764 } elseif (isset($parameters[
$name])) {
5765 $this->
debug(
'calling serializeType w/named param');
5766 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5769 $this->
debug(
'calling serializeType w/null param');
5770 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5774 $this->
debug(
'no parameters passed.');
5777 $this->
debug(
"serializeParameters returning: $xml");
5793 function serializeType(
$name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5795 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5797 if($use ==
'encoded' && $encodingStyle) {
5798 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5802 if (is_object($value) && get_class($value) ==
'soapval') {
5803 if ($value->type_ns) {
5804 $type = $value->type_ns .
':' . $value->type;
5806 $this->
debug(
"in serializeType: soapval overrides type to $type");
5807 } elseif ($value->type) {
5808 $type = $value->type;
5810 $this->
debug(
"in serializeType: soapval overrides type to $type");
5813 $this->
debug(
"in serializeType: soapval does not override type");
5815 $attrs = $value->attributes;
5816 $value = $value->value;
5817 $this->
debug(
"in serializeType: soapval overrides value to $value");
5819 if (!is_array($value)) {
5820 $value[
'!'] = $value;
5822 foreach ($attrs as
$n => $v) {
5823 $value[
'!' .
$n] = $v;
5825 $this->
debug(
"in serializeType: soapval provides attributes");
5832 if (strpos($type,
':')) {
5833 $uqType = substr($type, strrpos($type,
':') + 1);
5834 $ns = substr($type, 0, strrpos($type,
':'));
5835 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5838 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5841 if($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/'){
5842 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5843 if ($unqualified && $use ==
'literal') {
5844 $elementNS =
" xmlns=\"\"";
5848 if (is_null($value)) {
5849 if ($use ==
'literal') {
5851 $xml =
"<$name$elementNS/>";
5854 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5856 $this->
debug(
"in serializeType: returning: $xml");
5859 if ($uqType ==
'Array') {
5863 if ($uqType ==
'boolean') {
5864 if ((is_string($value) && $value ==
'false') || (! $value)) {
5870 if ($uqType ==
'string' && gettype($value) ==
'string') {
5873 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5874 $value = sprintf(
"%.0lf", $value);
5879 if (!$this->getTypeDef($uqType, $ns)) {
5880 if ($use ==
'literal') {
5882 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
5884 $xml =
"<$name$elementNS>$value</$name>";
5887 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
5889 $this->
debug(
"in serializeType: returning: $xml");
5892 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5893 }
else if ($ns ==
'http://xml.apache.org/xml-soap') {
5894 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
5895 if ($uqType ==
'Map') {
5898 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
5899 $tt_prefix =
'ns' . rand(1000, 9999);
5900 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
5905 foreach($value as $k => $v) {
5906 $this->
debug(
"serializing map element: key $k, value $v");
5907 $contents .=
'<item>';
5908 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false,$use);
5909 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false,$use);
5910 $contents .=
'</item>';
5912 if ($use ==
'literal') {
5914 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
5916 $xml =
"<$name>$contents</$name>";
5919 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
5921 $this->
debug(
"in serializeType: returning: $xml");
5924 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
5929 $this->
debug(
"in serializeType: No namespace for type $type");
5933 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5934 $this->
setError(
"$type ($uqType) is not a supported type.");
5935 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
5938 $this->
debug(
"in serializeType: found typeDef");
5940 if (substr($uqType, -1) ==
'^') {
5941 $uqType = substr($uqType, 0, -1);
5944 $phpType = $typeDef[
'phpType'];
5945 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'') );
5947 if ($phpType ==
'struct') {
5948 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
5949 $elementName = $uqType;
5950 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5951 $elementNS =
" xmlns=\"$ns\"";
5953 $elementNS =
" xmlns=\"\"";
5956 $elementName =
$name;
5958 $elementNS =
" xmlns=\"\"";
5963 if (is_null($value)) {
5964 if ($use ==
'literal') {
5966 $xml =
"<$elementName$elementNS/>";
5968 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5970 $this->
debug(
"in serializeType: returning: $xml");
5973 if (is_object($value)) {
5974 $value = get_object_vars($value);
5976 if (is_array($value)) {
5977 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5978 if ($use ==
'literal') {
5980 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
5982 $xml =
"<$elementName$elementNS$elementAttrs>";
5985 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
5988 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5989 $xml .=
"</$elementName>";
5991 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
5992 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
5995 } elseif ($phpType ==
'array') {
5996 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5997 $elementNS =
" xmlns=\"$ns\"";
6000 $elementNS =
" xmlns=\"\"";
6005 if (is_null($value)) {
6006 if ($use ==
'literal') {
6008 $xml =
"<$name$elementNS/>";
6010 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6019 $this->
debug(
"in serializeType: returning: $xml");
6022 if (isset($typeDef[
'multidimensional'])) {
6024 foreach($value as $v) {
6025 $cols =
',' .
sizeof($v);
6026 $nv = array_merge($nv, $v);
6032 if (is_array($value) &&
sizeof($value) >= 1) {
6033 $rows =
sizeof($value);
6035 foreach($value as $k => $v) {
6036 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6038 if (!in_array($typeDef[
'arrayType'],$this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6039 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6041 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6050 if ($use ==
'literal') {
6051 $xml =
"<$name$elementNS>" 6055 $xml =
"<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/').
':Array" '.
6058 .$this->getPrefixFromNamespace($this->
getPrefix($typeDef[
'arrayType']))
6059 .
":".$this->
getLocalPart($typeDef[
'arrayType']).
"[$rows$cols]\">" 6063 } elseif ($phpType ==
'scalar') {
6064 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6065 $elementNS =
" xmlns=\"$ns\"";
6068 $elementNS =
" xmlns=\"\"";
6073 if ($use ==
'literal') {
6075 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6077 $xml =
"<$name$elementNS>$value</$name>";
6080 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6083 $this->
debug(
"in serializeType: returning: $xml");
6097 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6099 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6100 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6101 if (is_array($value)) {
6103 } elseif (is_object($value)) {
6104 $xvalue = get_object_vars($value);
6106 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6109 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6110 if (isset($xvalue[
'!' . $aName])) {
6111 $xname =
'!' . $aName;
6112 $this->
debug(
"value provided for attribute $aName with key $xname");
6113 } elseif (isset($xvalue[$aName])) {
6115 $this->
debug(
"value provided for attribute $aName with key $xname");
6116 } elseif (isset($attrs[
'default'])) {
6117 $xname =
'!' . $aName;
6118 $xvalue[$xname] = $attrs[
'default'];
6119 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6122 $this->
debug(
"no value provided for attribute $aName");
6125 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6129 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6131 if (isset($typeDef[
'extensionBase'])) {
6132 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6133 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6137 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6138 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6139 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6141 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6159 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false) {
6161 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6162 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6163 if (is_array($value)) {
6165 } elseif (is_object($value)) {
6166 $xvalue = get_object_vars($value);
6168 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6172 if (count($typeDef[
'elements']) != count($xvalue)){
6175 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6176 if (!isset($xvalue[$eName])) {
6177 if (isset($attrs[
'default'])) {
6178 $xvalue[$eName] = $attrs[
'default'];
6179 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6183 if (isset($optionals)
6184 && (!isset($xvalue[$eName]))
6185 && ( (!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6187 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6188 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6191 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6194 if (isset($xvalue[$eName])) {
6195 $v = $xvalue[$eName];
6199 if (isset($attrs[
'form'])) {
6200 $unqualified = ($attrs[
'form'] ==
'unqualified');
6202 $unqualified =
false;
6204 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6206 foreach ($vv as $k => $v) {
6207 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6209 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6212 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6213 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6217 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6219 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6222 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6223 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6229 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6231 if (isset($typeDef[
'extensionBase'])) {
6232 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6233 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6237 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6238 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6239 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6241 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6261 function addComplexType(
$name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',$elements=array(),$attrs=array(),$arrayType=
'') {
6262 if (count($elements) > 0) {
6263 $eElements = array();
6264 foreach($elements as
$n =>
$e){
6267 foreach (
$e as $k => $v) {
6268 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6269 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6272 $eElements[
$n] = $ee;
6274 $elements = $eElements;
6277 if (count($attrs) > 0) {
6278 foreach($attrs as
$n =>
$a){
6280 foreach (
$a as $k => $v) {
6281 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6282 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6290 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6291 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6293 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6294 $this->schemas[$typens][0]->addComplexType(
$name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6308 function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array()) {
6309 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6311 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6312 $this->schemas[$typens][0]->addSimpleType(
$name, $restrictionBase, $typeClass, $phpType, $enumeration);
6322 function addElement($attrs) {
6323 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6324 $this->schemas[$typens][0]->addElement($attrs);
6341 function addOperation(
$name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false, $style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
''){
6342 if ($use ==
'encoded' && $encodingStyle ==
'') {
6343 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6346 if ($style ==
'document') {
6347 $elements = array();
6348 foreach ($in as
$n => $t) {
6349 $elements[
$n] = array(
'name' =>
$n,
'type' => $t);
6351 $this->addComplexType(
$name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6352 $this->addElement(array(
'name' =>
$name,
'type' =>
$name .
'RequestType'));
6353 $in = array(
'parameters' =>
'tns:' .
$name .
'^');
6355 $elements = array();
6356 foreach (
$out as
$n => $t) {
6357 $elements[
$n] = array(
'name' =>
$n,
'type' => $t);
6359 $this->addComplexType(
$name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6360 $this->addElement(array(
'name' =>
$name .
'Response',
'type' =>
$name .
'ResponseType',
'form' =>
'qualified'));
6361 $out = array(
'parameters' =>
'tns:' .
$name .
'Response' .
'^');
6365 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][
$name] =
6368 'binding' => $this->serviceName .
'Binding',
6369 'endpoint' => $this->endpoint,
6370 'soapAction' => $soapaction,
6375 'encodingStyle' => $encodingStyle,
6376 'message' =>
$name .
'Request',
6381 'encodingStyle' => $encodingStyle,
6382 'message' =>
$name .
'Response',
6385 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6386 'documentation' => $documentation);
6391 foreach($in as $pName => $pType)
6393 if(strpos($pType,
':')) {
6396 $this->messages[
$name.
'Request'][$pName] = $pType;
6399 $this->messages[
$name.
'Request']=
'0';
6403 foreach(
$out as $pName => $pType)
6405 if(strpos($pType,
':')) {
6408 $this->messages[
$name.
'Response'][$pName] = $pType;
6411 $this->messages[
$name.
'Response']=
'0';
6432 var $xml_encoding =
'';
6434 var $root_struct =
'';
6435 var $root_struct_name =
'';
6436 var $root_struct_namespace =
'';
6437 var $root_header =
'';
6443 var $default_namespace =
'';
6445 var $message = array();
6448 var $fault_code =
'';
6449 var $fault_str =
'';
6450 var $fault_detail =
'';
6451 var $depth_array = array();
6452 var $debug_flag =
true;
6453 var $soapresponse = NULL;
6454 var $soapheader = NULL;
6455 var $responseHeaders =
'';
6456 var $body_position = 0;
6461 var $multirefs = array();
6463 var $decode_utf8 =
true;
6474 function __construct($xml,$encoding=
'UTF-8',$method=
'',$decode_utf8=
true){
6477 $this->xml_encoding = $encoding;
6478 $this->method = $method;
6479 $this->decode_utf8 = $decode_utf8;
6484 $pos_xml = strpos($xml,
'<?xml');
6485 if ($pos_xml !== FALSE) {
6486 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6487 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6488 $xml_encoding =
$res[1];
6489 if (strtoupper($xml_encoding) != $encoding) {
6490 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6492 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6498 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6501 $this->
debug(
'No encoding specified in XML declaration');
6504 $this->
debug(
'No XML declaration');
6506 $this->
debug(
'Entering nusoap_parser(), length='.strlen($xml).
', encoding='.$encoding);
6508 $this->parser = xml_parser_create($this->xml_encoding);
6511 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6512 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6514 xml_set_object($this->parser, $this);
6516 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6517 xml_set_character_data_handler($this->parser,
'character_data');
6520 if(!xml_parse($this->parser,$xml,
true)){
6522 $err = sprintf(
'XML error parsing SOAP payload on line %d: %s',
6523 xml_get_current_line_number($this->parser),
6524 xml_error_string(xml_get_error_code($this->parser)));
6526 $this->
debug(
"XML payload:\n" . $xml);
6529 $this->
debug(
'parsed successfully, found root struct: '.$this->root_struct.
' of name '.$this->root_struct_name);
6531 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6533 if($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])){
6534 $this->soapheader = $this->message[$this->root_header][
'result'];
6537 if(
sizeof($this->multirefs) > 0){
6538 foreach($this->multirefs as $id => $hrefs){
6539 $this->
debug(
'resolving multirefs for id: '.$id);
6540 $idVal = $this->buildVal($this->ids[$id]);
6541 if (is_array($idVal) && isset($idVal[
'!id'])) {
6542 unset($idVal[
'!id']);
6544 foreach($hrefs as $refPos => $ref){
6545 $this->
debug(
'resolving href at pos '.$refPos);
6546 $this->multirefs[$id][$refPos] = $idVal;
6551 xml_parser_free($this->parser);
6553 $this->
debug(
'xml was empty, didn\'t parse!');
6554 $this->
setError(
'xml was empty, didn\'t parse!');
6566 function start_element($parser,
$name, $attrs) {
6569 $pos = $this->position++;
6571 $this->message[$pos] = array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6574 $this->message[$pos][
'depth'] = $this->depth++;
6578 $this->message[$this->parent][
'children'] .=
'|'.$pos;
6581 $this->message[$pos][
'parent'] = $this->parent;
6583 $this->parent = $pos;
6585 $this->depth_array[$this->depth] = $pos;
6587 if(strpos(
$name,
':')){
6594 if(
$name ==
'Envelope'){
6595 $this->status =
'envelope';
6596 } elseif(
$name ==
'Header' && $this->status =
'envelope'){
6597 $this->root_header = $pos;
6598 $this->status =
'header';
6599 } elseif(
$name ==
'Body' && $this->status =
'envelope'){
6600 $this->status =
'body';
6601 $this->body_position = $pos;
6603 } elseif($this->status ==
'body' && $pos == ($this->body_position+1)){
6604 $this->status =
'method';
6605 $this->root_struct_name =
$name;
6606 $this->root_struct = $pos;
6607 $this->message[$pos][
'type'] =
'struct';
6608 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6611 $this->message[$pos][
'status'] = $this->status;
6613 $this->message[$pos][
'name'] = htmlspecialchars(
$name);
6615 $this->message[$pos][
'attrs'] = $attrs;
6619 foreach($attrs as $key => $value){
6623 if($key_prefix ==
'xmlns'){
6624 if(preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6625 $this->XMLSchemaVersion = $value;
6627 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion.
'-instance';
6629 $this->namespaces[$key_localpart] = $value;
6631 if(
$name == $this->root_struct_name){
6632 $this->methodNamespace = $value;
6635 } elseif($key_localpart ==
'type'){
6636 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6639 $value_prefix = $this->
getPrefix($value);
6641 $this->message[$pos][
'type'] = $value_localpart;
6642 $this->message[$pos][
'typePrefix'] = $value_prefix;
6643 if(isset($this->namespaces[$value_prefix])){
6644 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6645 }
else if(isset($attrs[
'xmlns:'.$value_prefix])) {
6646 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:'.$value_prefix];
6650 } elseif($key_localpart ==
'arrayType'){
6651 $this->message[$pos][
'type'] =
'array';
6660 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6661 if(preg_match($expr,$value,$regs)){
6662 $this->message[$pos][
'typePrefix'] = $regs[1];
6663 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6664 if (isset($this->namespaces[$regs[1]])) {
6665 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6666 }
else if (isset($attrs[
'xmlns:'.$regs[1]])) {
6667 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:'.$regs[1]];
6669 $this->message[$pos][
'arrayType'] = $regs[2];
6670 $this->message[$pos][
'arraySize'] = $regs[3];
6671 $this->message[$pos][
'arrayCols'] = $regs[4];
6674 } elseif ($key_localpart ==
'nil'){
6675 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6677 } elseif ($key !=
'href' && $key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6678 $this->message[$pos][
'xattrs'][
'!' . $key] = $value;
6681 if ($key ==
'xmlns') {
6682 $this->default_namespace = $value;
6686 $this->ids[$value] = $pos;
6689 if($key_localpart ==
'root' && $value == 1){
6690 $this->status =
'method';
6691 $this->root_struct_name =
$name;
6692 $this->root_struct = $pos;
6693 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6696 $attstr .=
" $key=\"$value\"";
6700 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6701 $this->default_namespace = $this->namespaces[$prefix];
6703 $this->message[$pos][
'namespace'] = $this->default_namespace;
6705 if($this->status ==
'header'){
6706 if ($this->root_header != $pos) {
6707 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6709 } elseif($this->root_struct_name !=
''){
6710 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6721 function end_element($parser,
$name) {
6723 $pos = $this->depth_array[$this->depth--];
6726 if(strpos(
$name,
':')){
6734 if(isset($this->body_position) && $pos > $this->body_position){
6736 if(isset($this->message[$pos][
'attrs'][
'href'])){
6738 $id = substr($this->message[$pos][
'attrs'][
'href'],1);
6740 $this->multirefs[$id][$pos] =
'placeholder';
6742 $this->message[$pos][
'result'] =& $this->multirefs[$id][$pos];
6744 } elseif($this->message[$pos][
'children'] !=
''){
6746 if(!isset($this->message[$pos][
'result'])){
6747 $this->message[$pos][
'result'] = $this->buildVal($pos);
6750 } elseif (isset($this->message[$pos][
'xattrs'])) {
6751 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6752 $this->message[$pos][
'xattrs'][
'!'] = null;
6753 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6754 if (isset($this->message[$pos][
'type'])) {
6755 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
6757 $parent = $this->message[$pos][
'parent'];
6758 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6759 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6761 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6765 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6769 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6770 $this->message[$pos][
'xattrs'][
'!'] = null;
6771 } elseif (isset($this->message[$pos][
'type'])) {
6772 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
6774 $parent = $this->message[$pos][
'parent'];
6775 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6776 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6778 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6796 if($this->status ==
'header'){
6797 if ($this->root_header != $pos) {
6798 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6800 } elseif($pos >= $this->root_struct){
6801 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6804 if($pos == $this->root_struct){
6805 $this->status =
'body';
6806 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6807 } elseif(
$name ==
'Body'){
6808 $this->status =
'envelope';
6809 } elseif(
$name ==
'Header'){
6810 $this->status =
'envelope';
6811 } elseif(
$name ==
'Envelope'){
6815 $this->parent = $this->message[$pos][
'parent'];
6825 function character_data($parser,
$data){
6826 $pos = $this->depth_array[$this->depth];
6827 if ($this->xml_encoding==
'UTF-8'){
6831 if($this->decode_utf8){
6835 $this->message[$pos][
'cdata'] .=
$data;
6837 if($this->status ==
'header'){
6838 $this->responseHeaders .=
$data;
6840 $this->document .=
$data;
6851 function get_response(){
6852 return $this->soapresponse;
6861 function get_soapbody(){
6862 return $this->soapresponse;
6871 function get_soapheader(){
6872 return $this->soapheader;
6881 function getHeaders(){
6882 return $this->responseHeaders;
6894 function decodeSimple($value, $type, $typens) {
6896 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
6897 return (
string) $value;
6899 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
6900 return (
int) $value;
6902 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
6903 return (
double) $value;
6905 if ($type ==
'boolean') {
6906 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
6909 return (
boolean) $value;
6911 if ($type ==
'base64' || $type ==
'base64Binary') {
6912 $this->
debug(
'Decode base64 value');
6913 return base64_decode($value);
6916 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 6917 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 6918 || $type ==
'unsignedInt' 6919 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
6920 return (
int) $value;
6923 if ($type ==
'array') {
6927 return (
string) $value;
6938 function buildVal($pos){
6939 if(!isset($this->message[$pos][
'type'])){
6940 $this->message[$pos][
'type'] =
'';
6942 $this->
debug(
'in buildVal() for '.$this->message[$pos][
'name'].
"(pos $pos) of type ".$this->message[$pos][
'type']);
6944 if($this->message[$pos][
'children'] !=
''){
6945 $this->
debug(
'in buildVal, there are children');
6946 $children = explode(
'|',$this->message[$pos][
'children']);
6947 array_shift($children);
6949 if(isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
''){
6952 foreach($children as $child_pos){
6953 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
6954 $params[$r][] = $this->message[$child_pos][
'result'];
6956 if(
$c == $this->message[$pos][
'arrayCols']){
6962 } elseif($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array'){
6963 $this->
debug(
'in buildVal, adding array '.$this->message[$pos][
'name']);
6964 foreach($children as $child_pos){
6965 $params[] = &$this->message[$child_pos][
'result'];
6968 } elseif($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap'){
6969 $this->
debug(
'in buildVal, Java Map '.$this->message[$pos][
'name']);
6970 foreach($children as $child_pos){
6971 $kv = explode(
"|",$this->message[$child_pos][
'children']);
6972 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
6978 $this->
debug(
'in buildVal, adding Java Vector or generic compound type '.$this->message[$pos][
'name']);
6979 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
6985 foreach($children as $child_pos){
6987 $params[] = &$this->message[$child_pos][
'result'];
6989 if (isset($params[$this->message[$child_pos][
'name']])) {
6991 if ((!is_array($params[$this->message[$child_pos][
'name']])) || (!isset($params[$this->message[$child_pos][
'name']][0]))) {
6992 $params[$this->message[$child_pos][
'name']] = array($params[$this->message[$child_pos][
'name']]);
6994 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
6996 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
7001 if (isset($this->message[$pos][
'xattrs'])) {
7002 $this->
debug(
'in buildVal, handling attributes');
7003 foreach ($this->message[$pos][
'xattrs'] as
$n => $v) {
7008 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7009 $this->
debug(
'in buildVal, handling simpleContent');
7010 if (isset($this->message[$pos][
'type'])) {
7011 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7013 $parent = $this->message[$pos][
'parent'];
7014 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7015 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7017 $params[
'!'] = $this->message[$pos][
'cdata'];
7021 $ret = is_array($params) ? $params : array();
7022 $this->
debug(
'in buildVal, return:');
7026 $this->
debug(
'in buildVal, no children, building scalar');
7027 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7028 if (isset($this->message[$pos][
'type'])) {
7029 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7030 $this->
debug(
"in buildVal, return: $ret");
7033 $parent = $this->message[$pos][
'parent'];
7034 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7035 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7036 $this->
debug(
"in buildVal, return: $ret");
7039 $ret = $this->message[$pos][
'cdata'];
7040 $this->
debug(
"in buildVal, return: $ret");
7081 var $certRequest = array();
7082 var $requestHeaders =
false;
7083 var $responseHeaders =
'';
7084 var $responseHeader = NULL;
7087 var $forceEndpoint =
'';
7088 var $proxyhost =
'';
7089 var $proxyport =
'';
7090 var $proxyusername =
'';
7091 var $proxypassword =
'';
7092 var $xml_encoding =
'';
7093 var $http_encoding =
false;
7095 var $response_timeout = 30;
7096 var $endpointType =
'';
7097 var $persistentConnection =
false;
7098 var $defaultRpcParams =
false;
7101 var $responseData =
'';
7102 var $cookies = array();
7103 var $decode_utf8 =
true;
7104 var $operations = array();
7105 var $curl_options = array();
7106 var $bindingType =
'';
7107 var $use_curl =
false;
7147 function __construct($endpoint,$wsdl =
false,$proxyhost =
false,$proxyport =
false,$proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30){
7149 $this->endpoint = $endpoint;
7150 $this->proxyhost = $proxyhost;
7151 $this->proxyport = $proxyport;
7152 $this->proxyusername = $proxyusername;
7153 $this->proxypassword = $proxypassword;
7154 $this->timeout = $timeout;
7155 $this->response_timeout = $response_timeout;
7157 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7162 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7163 $this->
wsdl = $endpoint;
7164 $this->endpoint = $this->
wsdl->
wsdl;
7165 $this->wsdlFile = $this->endpoint;
7166 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7169 $this->wsdlFile = $this->endpoint;
7171 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7173 $this->endpointType =
'wsdl';
7175 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7176 $this->endpointType =
'soap';
7205 function call($operation,$params=array(),
$namespace=
'http://tempuri.org',$soapAction=
'',$headers=
false,$rpcParams=null,$style=
'rpc',$use=
'encoded'){
7206 $this->operation = $operation;
7207 $this->fault =
false;
7209 $this->request =
'';
7210 $this->response =
'';
7211 $this->responseData =
'';
7212 $this->faultstring =
'';
7213 $this->faultcode =
'';
7214 $this->opData = array();
7216 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7220 $this->requestHeaders = $headers;
7222 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7228 if($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)){
7230 $this->opData = $opData;
7231 $this->
debug(
"found operation");
7233 if (isset($opData[
'soapAction'])) {
7234 $soapAction = $opData[
'soapAction'];
7236 if (! $this->forceEndpoint) {
7237 $this->endpoint = $opData[
'endpoint'];
7239 $this->endpoint = $this->forceEndpoint;
7241 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7242 $style = $opData[
'style'];
7243 $use = $opData[
'input'][
'use'];
7246 $nsPrefix =
'ns' . rand(1000, 9999);
7251 if (is_string($params)) {
7252 $this->
debug(
"serializing param string for WSDL operation $operation");
7254 } elseif (is_array($params)) {
7255 $this->
debug(
"serializing param array for WSDL operation $operation");
7258 $this->
debug(
'params must be array or string');
7259 $this->
setError(
'params must be array or string');
7263 if (isset($opData[
'input'][
'encodingStyle'])) {
7264 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7266 $encodingStyle =
'';
7271 $this->
debug(
'got wsdl error: '.$errstr);
7272 $this->
setError(
'wsdl error: '.$errstr);
7275 } elseif($this->endpointType ==
'wsdl') {
7279 $this->
setError(
'operation '.$operation.
' not present.');
7280 $this->
debug(
"operation '$operation' not present.");
7285 $nsPrefix =
'ns' . rand(1000, 9999);
7288 if (is_string($params)) {
7289 $this->
debug(
"serializing param string for operation $operation");
7291 } elseif (is_array($params)) {
7292 $this->
debug(
"serializing param array for operation $operation");
7293 foreach($params as $k => $v){
7294 $payload .= $this->
serialize_val($v,$k,
false,
false,
false,
false,$use);
7297 $this->
debug(
'params must be array or string');
7298 $this->
setError(
'params must be array or string');
7302 if ($use ==
'encoded') {
7303 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7305 $encodingStyle =
'';
7309 if ($style ==
'rpc') {
7310 if ($use ==
'literal') {
7311 $this->
debug(
"wrapping RPC request with literal method element");
7314 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7316 "</$nsPrefix:$operation>";
7318 $payload =
"<$operation>" . $payload .
"</$operation>";
7321 $this->
debug(
"wrapping RPC request with encoded method element");
7323 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7325 "</$nsPrefix:$operation>";
7327 $payload =
"<$operation>" .
7335 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7336 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7338 $return = $this->
send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7340 $this->
debug(
'Error: '.$errstr);
7343 $this->
return = $return;
7344 $this->
debug(
'sent message successfully and got a(n) '.gettype($return));
7348 if(is_array($return) && isset($return[
'faultcode'])){
7349 $this->
debug(
'got fault');
7350 $this->
setError($return[
'faultcode'].
': '.$return[
'faultstring']);
7351 $this->fault =
true;
7352 foreach($return as $k => $v){
7354 $this->
debug(
"$k = $v<br>");
7357 } elseif ($style ==
'document') {
7363 if(is_array($return)){
7366 if(
sizeof($return) > 1){
7370 $return = array_shift($return);
7371 $this->
debug(
'return shifted value: ');
7387 function checkWSDL() {
7390 $this->
debug(
'checkWSDL');
7393 $this->
debug(
'got wsdl error: '.$errstr);
7394 $this->
setError(
'wsdl error: '.$errstr);
7396 $this->bindingType =
'soap';
7397 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7399 $this->bindingType =
'soap12';
7400 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7401 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7403 $this->
debug(
'getOperations returned false');
7404 $this->
setError(
'no operations defined in the WSDL document!');
7413 function loadWSDL() {
7414 $this->
debug(
'instantiating wsdl class with doc: '.$this->wsdlFile);
7415 $this->
wsdl =
new wsdl(
'',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7416 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7428 function getOperationData($operation){
7429 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7434 if(isset($this->operations[$operation])){
7435 return $this->operations[$operation];
7437 $this->
debug(
"No data for operation: $operation");
7454 function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30) {
7455 $this->checkCookies();
7459 case preg_match(
'/^http/',$this->endpoint):
7460 $this->
debug(
'transporting via HTTP');
7461 if($this->persistentConnection ==
true && is_object($this->persistentConnection)){
7462 $http =& $this->persistentConnection;
7465 if ($this->persistentConnection) {
7466 $http->usePersistentConnection();
7469 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7470 $http->setSOAPAction($soapaction);
7471 if($this->proxyhost && $this->proxyport){
7472 $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7474 if($this->authtype !=
'') {
7475 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7477 if($this->http_encoding !=
''){
7478 $http->setEncoding($this->http_encoding);
7480 $this->
debug(
'sending message, length='.strlen($msg));
7481 if(preg_match(
'/^http:/',$this->endpoint)){
7483 $this->responseData =
$http->send($msg,$timeout,$response_timeout,$this->cookies);
7484 } elseif(preg_match(
'/^https/',$this->endpoint)){
7491 $this->responseData =
$http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7493 $this->
setError(
'no http/s in endpoint url');
7495 $this->request =
$http->outgoing_payload;
7496 $this->response =
$http->incoming_payload;
7498 $this->UpdateCookies(
$http->incoming_cookies);
7501 if ($this->persistentConnection) {
7502 $http->clearDebug();
7503 if (!is_object($this->persistentConnection)) {
7504 $this->persistentConnection =
$http;
7508 if($err =
$http->getError()){
7509 $this->
setError(
'HTTP Error: '.$err);
7514 $this->
debug(
'got response, length='. strlen($this->responseData).
' type='.
$http->incoming_headers[
'content-type']);
7515 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7519 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7533 function parseResponse($headers,
$data) {
7534 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7536 if (!strstr($headers[
'content-type'],
'text/xml')) {
7537 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7540 if (strpos($headers[
'content-type'],
'=')) {
7541 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7542 $this->
debug(
'Got response encoding: ' . $enc);
7543 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7544 $this->xml_encoding = strtoupper($enc);
7546 $this->xml_encoding =
'US-ASCII';
7550 $this->xml_encoding =
'ISO-8859-1';
7552 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7553 $parser =
new nusoap_parser(
$data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7557 if($errstr = $parser->getError()){
7564 $this->responseHeaders = $parser->getHeaders();
7566 $this->responseHeader = $parser->get_soapheader();
7568 $return = $parser->get_soapbody();
7570 $this->document = $parser->document;
7585 function setCurlOption($option, $value) {
7586 $this->
debug(
"setCurlOption option=$option, value=");
7588 $this->curl_options[$option] = $value;
7597 function setEndpoint($endpoint) {
7598 $this->
debug(
"setEndpoint(\"$endpoint\")");
7599 $this->forceEndpoint = $endpoint;
7608 function setHeaders($headers){
7609 $this->
debug(
"setHeaders headers=");
7611 $this->requestHeaders = $headers;
7620 function getHeaders(){
7621 return $this->responseHeaders;
7630 function getHeader(){
7631 return $this->responseHeader;
7643 function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'') {
7644 $this->proxyhost = $proxyhost;
7645 $this->proxyport = $proxyport;
7646 $this->proxyusername = $proxyusername;
7647 $this->proxypassword = $proxypassword;
7659 function setCredentials($username, $password, $authtype =
'basic', $certRequest = array()) {
7660 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7662 $this->username = $username;
7664 $this->authtype = $authtype;
7665 $this->certRequest = $certRequest;
7674 function setHTTPEncoding($enc=
'gzip, deflate'){
7675 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7676 $this->http_encoding = $enc;
7685 function setUseCURL($use) {
7686 $this->
debug(
"setUseCURL($use)");
7687 $this->use_curl = $use;
7695 function useHTTPPersistentConnection(){
7696 $this->
debug(
"useHTTPPersistentConnection");
7697 $this->persistentConnection =
true;
7711 function getDefaultRpcParams() {
7712 return $this->defaultRpcParams;
7726 function setDefaultRpcParams($rpcParams) {
7727 $this->defaultRpcParams = $rpcParams;
7737 function getProxy() {
7739 $evalStr = $this->_getProxyClassCode($r);
7742 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7748 eval(
"\$proxy = new nusoap_proxy_$r('');");
7750 $proxy->endpointType =
'wsdl';
7751 $proxy->wsdlFile = $this->wsdlFile;
7752 $proxy->wsdl = $this->wsdl;
7753 $proxy->operations = $this->operations;
7754 $proxy->defaultRpcParams = $this->defaultRpcParams;
7757 $proxy->username = $this->username;
7759 $proxy->authtype = $this->authtype;
7760 $proxy->certRequest = $this->certRequest;
7761 $proxy->requestHeaders = $this->requestHeaders;
7762 $proxy->endpoint = $this->endpoint;
7763 $proxy->forceEndpoint = $this->forceEndpoint;
7764 $proxy->proxyhost = $this->proxyhost;
7765 $proxy->proxyport = $this->proxyport;
7766 $proxy->proxyusername = $this->proxyusername;
7767 $proxy->proxypassword = $this->proxypassword;
7768 $proxy->http_encoding = $this->http_encoding;
7769 $proxy->timeout = $this->timeout;
7770 $proxy->response_timeout = $this->response_timeout;
7771 $proxy->persistentConnection = &$this->persistentConnection;
7772 $proxy->decode_utf8 = $this->decode_utf8;
7773 $proxy->curl_options = $this->curl_options;
7774 $proxy->bindingType = $this->bindingType;
7775 $proxy->use_curl = $this->use_curl;
7785 function _getProxyClassCode($r) {
7786 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7788 if ($this->endpointType !=
'wsdl') {
7789 $evalStr =
'A proxy can only be created for a WSDL client';
7791 $evalStr =
"echo \"$evalStr\";";
7794 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7797 return "echo \"" . $this->
getError() .
"\";";
7801 foreach ($this->operations as $operation => $opData) {
7802 if ($operation !=
'') {
7804 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7806 $paramArrayStr =
'';
7807 $paramCommentStr =
'';
7808 foreach ($opData[
'input'][
'parts'] as
$name => $type) {
7809 $paramStr .=
"\$$name, ";
7810 $paramArrayStr .=
"'$name' => \$$name, ";
7811 $paramCommentStr .=
"$type \$$name, ";
7813 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7814 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7815 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7818 $paramArrayStr =
'';
7819 $paramCommentStr =
'void';
7821 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7822 $evalStr .=
"// $paramCommentStr 7823 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7824 \$params = array($paramArrayStr); 7825 return \$this->call('$operation', \$params, '".$opData[
'namespace'].
"', '".(isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'').
"'); 7829 unset($paramCommentStr);
7832 $evalStr =
'class nusoap_proxy_'.$r.
' extends nusoap_client { 7844 function getProxyClassCode() {
7846 return $this->_getProxyClassCode($r);
7856 function getHTTPBody($soapmsg) {
7868 function getHTTPContentType() {
7881 function getHTTPContentTypeCharset() {
7891 function decodeUTF8($bool){
7892 $this->decode_utf8 = $bool;
7904 function setCookie(
$name, $value) {
7905 if (strlen(
$name) == 0) {
7908 $this->cookies[] = array(
'name' =>
$name,
'value' => $value);
7918 function getCookies() {
7919 return $this->cookies;
7928 function checkCookies() {
7929 if (
sizeof($this->cookies) == 0) {
7932 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
7933 $curr_cookies = $this->cookies;
7934 $this->cookies = array();
7935 foreach ($curr_cookies as $cookie) {
7936 if (! is_array($cookie)) {
7937 $this->
debug(
'Remove cookie that is not an array');
7940 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
7941 if (strtotime($cookie[
'expires']) > time()) {
7942 $this->cookies[] = $cookie;
7944 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
7947 $this->cookies[] = $cookie;
7950 $this->
debug(
'checkCookie: '.
sizeof($this->cookies).
' cookies left in array');
7961 function UpdateCookies($cookies) {
7962 if (
sizeof($this->cookies) == 0) {
7964 if (
sizeof($cookies) > 0) {
7965 $this->
debug(
'Setting new cookie(s)');
7966 $this->cookies = $cookies;
7970 if (
sizeof($cookies) == 0) {
7975 foreach ($cookies as $newCookie) {
7976 if (!is_array($newCookie)) {
7979 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
7982 $newName = $newCookie[
'name'];
7985 for (
$i = 0;
$i < count($this->cookies);
$i++) {
7986 $cookie = $this->cookies[
$i];
7987 if (!is_array($cookie)) {
7990 if (!isset($cookie[
'name'])) {
7993 if ($newName != $cookie[
'name']) {
7996 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
7997 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
7998 if ($newDomain != $domain) {
8001 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
8002 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
8003 if ($newPath != $path) {
8006 $this->cookies[
$i] = $newCookie;
8008 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8012 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8013 $this->cookies[] = $newCookie;
8020 if (!extension_loaded(
'soap')) {
if($err=$client->getError()) $namespace
appendDebug($string)
adds debug data to the instance debug string without formatting
soap_server allows the user to create a SOAP server that is capable of receiving messages and returni...
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded')
serialize message
setError($str)
sets error string
Contains information for a SOAP fault.
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
& getDebug()
gets the current debug data for this instance
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
parses a WSDL file, allows access to it's data, other utility methods
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
soap_fault class, allows for creation of faults mainly used for returning faults from deployed functi...
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
serialize()
serialize the parsed wsdl
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='')
register a service with the server
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed ...
parses an XML Schema, allows access to it's data, other utility methods no validation...
for creating serializable abstractions of native PHP types NOTE: this is only really used when WSDL i...
getError()
returns error string if present
debug($string)
adds debug data to the class level debug string
soap_parser class parses SOAP XML messages into native PHP values
foreach($_POST as $key=> $value) $res
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
expandQname($qname)
expands a qualified name
parses an XML Schema, allows access to it's data, other utility methods.
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
webDescription()
prints html description of services
[nu]soapclient higher level class for easy usage.
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded')
serializes PHP values in accordance w/ section 5.
wsdl($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
getOperations($bindingType='soap')
returns an assoc array of operation names => operation data
if(php_sapi_name() !='cli') $in
serialize()
serialize a fault
__construct(Container $dic, ilPlugin $plugin)
expandEntities($val)
expands entities, e.g.
serializeRPCParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace returns false if no namespace registered with the given pref...
nusoap_parser class parses SOAP XML messages into native PHP values
getOperationData($operation, $bindingType='soap')
returns an associative array of data necessary for calling an operation
clearDebug()
clears the current debug data for this instance
fetchWSDL($wsdl)
fetches the WSDL document and parses it
catch(ilCmiXapiException $e) send($response)