For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
972 $start = gettimeofday();
975 $stop = gettimeofday();
976 $timePassed = 1000000 * ($stop[
'sec'] - $start[
'sec'])
977 + $stop[
'usec'] - $start[
'usec'];
978 }
while ($timePassed < $usec);
1046 foreach ($this->namespaces as $k => $v) {
1047 $ns_string .=
"\n xmlns:$k=\"$v\"";
1050 '<?xml version="1.0" encoding="' . $this->soap_defencoding .
'"?>' .
1051 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string .
">\n" .
1053 '<SOAP-ENV:Fault>' .
1058 '</SOAP-ENV:Fault>' .
1059 '</SOAP-ENV:Body>' .
1060 '</SOAP-ENV:Envelope>';
1088 public $schema =
'';
1091 public $enclosingNamespaces;
1093 public $schemaInfo = array();
1094 public $schemaTargetNamespace =
'';
1096 public $attributes = array();
1097 public $complexTypes = array();
1098 public $complexTypeStack = array();
1099 public $currentComplexType =
null;
1100 public $elements = array();
1101 public $elementStack = array();
1102 public $currentElement =
null;
1103 public $simpleTypes = array();
1104 public $simpleTypeStack = array();
1105 public $currentSimpleType =
null;
1107 public $imports = array();
1110 public $position = 0;
1112 public $depth_array = array();
1114 public $defaultNamespace = array();
1127 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
1129 $this->schema = $schema;
1134 $this->namespaces = array_merge($this->namespaces,
$namespaces);
1137 if ($schema !=
'') {
1138 $this->
debug(
'initial schema file: ' . $schema);
1139 $this->parseFile($schema,
'schema');
1144 $this->
debug(
'initial xml file: ' . $xml);
1145 $this->parseFile($xml,
'xml');
1157 public function parseFile($xml, $type)
1161 $xmlStr = @join(
"", @file($xml));
1162 if ($xmlStr ==
"") {
1163 $msg =
'Error reading XML from ' . $xml;
1168 $this->
debug(
"parsing $xml");
1169 $this->parseString($xmlStr, $type);
1170 $this->
debug(
"done parsing $xml");
1184 public function parseString($xml, $type)
1189 $this->parser = xml_parser_create();
1191 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1194 if ($type ==
"schema") {
1195 xml_set_element_handler($this->parser, $this->schemaStartElement(...), $this->schemaEndElement(...));
1196 xml_set_character_data_handler($this->parser, $this->schemaCharacterData(...));
1197 } elseif ($type ==
"xml") {
1198 xml_set_element_handler($this->parser, $this->xmlStartElement(...), $this->xmlEndElement(...));
1199 xml_set_character_data_handler($this->parser, $this->xmlCharacterData(...));
1203 if (!xml_parse($this->parser, $xml,
true)) {
1206 'XML error parsing XML schema on line %d: %s',
1207 xml_get_current_line_number($this->parser),
1208 xml_error_string(xml_get_error_code($this->parser))
1210 $this->
debug($errstr);
1211 $this->
debug(
"XML payload:\n" . $xml);
1215 xml_parser_free($this->parser);
1217 $this->
debug(
'no xml passed to parseString()!!');
1218 $this->
setError(
'no xml passed to parseString()!!');
1229 public function CreateTypeName($ename)
1232 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1233 $scope .= $this->complexTypeStack[$i] .
'_';
1235 return $scope . $ename .
'_ContainedType';
1246 public function schemaStartElement($parser, $name, $attrs)
1250 $pos = $this->position++;
1251 $depth = $this->depth++;
1253 $this->depth_array[$depth] = $pos;
1254 $this->message[$pos] = array(
'cdata' =>
'');
1256 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1258 $this->defaultNamespace[$pos] =
false;
1262 if ($prefix = $this->
getPrefix($name)) {
1270 if (count($attrs) > 0) {
1271 foreach ($attrs as $k => $v) {
1273 if (preg_match(
'/^xmlns/', $k)) {
1276 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
1278 $this->namespaces[$ns_prefix] = $v;
1280 $this->defaultNamespace[$pos] = $v;
1282 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
1285 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
1286 $this->XMLSchemaVersion = $v;
1287 $this->namespaces[
'xsi'] = $v .
'-instance';
1291 foreach ($attrs as $k => $v) {
1293 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1294 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1308 $this->complexTypes[$this->currentComplexType][
'compositor'] = $name;
1315 $this->xdebug(
"parsing attribute:");
1317 if (!isset($attrs[
'form'])) {
1318 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1320 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1321 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1322 if (!strpos($v,
':')) {
1324 if ($this->defaultNamespace[$pos]) {
1326 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1330 if (isset($attrs[
'name'])) {
1331 $this->attributes[$attrs[
'name']] = $attrs;
1332 $aname = $attrs[
'name'];
1333 } elseif (isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
1334 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1335 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1339 } elseif (isset($attrs[
'ref'])) {
1340 $aname = $attrs[
'ref'];
1341 $this->attributes[$attrs[
'ref']] = $attrs;
1344 if ($this->currentComplexType) {
1345 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1348 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType') {
1349 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1351 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1352 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1356 if (strpos($v,
'[,]')) {
1357 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1359 $v = substr($v, 0, strpos($v,
'['));
1360 if (!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
1361 $v = $this->XMLSchemaVersion .
':' . $v;
1363 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1366 case 'complexContent':
1369 array_push($this->complexTypeStack, $this->currentComplexType);
1370 if (isset($attrs[
'name'])) {
1373 $this->xdebug(
'processing named complexType ' . $attrs[
'name']);
1375 $this->currentComplexType = $attrs[
'name'];
1376 $this->complexTypes[$this->currentComplexType] = $attrs;
1377 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1385 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1386 $this->xdebug(
'complexType is unusual array');
1387 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1389 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1392 $name = $this->CreateTypeName($this->currentElement);
1393 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' . $name);
1394 $this->currentComplexType = $name;
1396 $this->complexTypes[$this->currentComplexType] = $attrs;
1397 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1405 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1406 $this->xdebug(
'complexType is unusual array');
1407 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1409 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1414 array_push($this->elementStack, $this->currentElement);
1415 if (!isset($attrs[
'form'])) {
1416 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1418 if (isset($attrs[
'type'])) {
1419 $this->xdebug(
"processing typed element " . $attrs[
'name'] .
" of type " . $attrs[
'type']);
1420 if (! $this->
getPrefix($attrs[
'type'])) {
1421 if ($this->defaultNamespace[$pos]) {
1422 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1423 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1433 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1434 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1435 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1437 $this->currentElement = $attrs[
'name'];
1438 $ename = $attrs[
'name'];
1439 } elseif (isset($attrs[
'ref'])) {
1440 $this->xdebug(
"processing element as ref to " . $attrs[
'ref']);
1441 $this->currentElement =
"ref to " . $attrs[
'ref'];
1444 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1445 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' . $type);
1446 $this->currentElement = $attrs[
'name'];
1447 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $type;
1448 $ename = $attrs[
'name'];
1450 if (isset($ename) && $this->currentComplexType) {
1451 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1452 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1453 } elseif (!isset($attrs[
'ref'])) {
1454 $this->xdebug(
"add element $ename to elements array");
1455 $this->elements[ $attrs[
'name'] ] = $attrs;
1456 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1460 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1461 if ($this->currentSimpleType) {
1462 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1463 } elseif ($this->currentComplexType) {
1464 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1468 $this->xdebug(
'extension ' . $attrs[
'base']);
1469 if ($this->currentComplexType) {
1470 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1474 if (isset($attrs[
'schemaLocation'])) {
1476 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1479 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1481 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $attrs[
'namespace'];
1488 $this->xdebug(
'restriction ' . $attrs[
'base']);
1489 if ($this->currentSimpleType) {
1490 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1491 } elseif ($this->currentComplexType) {
1492 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1493 if (strstr($attrs[
'base'],
':') ==
':Array') {
1494 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1499 $this->schemaInfo = $attrs;
1501 if (isset($attrs[
'targetNamespace'])) {
1502 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1504 if (!isset($attrs[
'elementFormDefault'])) {
1505 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1507 if (!isset($attrs[
'attributeFormDefault'])) {
1508 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1511 case 'simpleContent':
1514 array_push($this->simpleTypeStack, $this->currentSimpleType);
1515 if (isset($attrs[
'name'])) {
1516 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1517 $this->currentSimpleType = $attrs[
'name'];
1518 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1519 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1520 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1522 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1523 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' . $name);
1524 $this->currentSimpleType = $name;
1526 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1527 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1544 public function schemaEndElement($parser, $name)
1549 if (isset($this->depth_array[$this->depth])) {
1550 $pos = $this->depth_array[$this->depth];
1553 if ($prefix = $this->
getPrefix($name)) {
1560 if ($name ==
'complexType') {
1561 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1562 $this->currentComplexType = array_pop($this->complexTypeStack);
1565 if ($name ==
'element') {
1566 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1567 $this->currentElement = array_pop($this->elementStack);
1569 if ($name ==
'simpleType') {
1570 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1571 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1582 public function schemaCharacterData($parser,
$data)
1584 $pos = $this->depth_array[$this->depth - 1];
1585 $this->message[$pos][
'cdata'] .=
$data;
1593 public function serializeSchema()
1598 if (
sizeof($this->imports) > 0) {
1599 foreach ($this->imports as $ns => $list) {
1600 foreach ($list as $ii) {
1601 if ($ii[
'location'] !=
'') {
1602 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1604 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1610 foreach ($this->complexTypes as $typeName => $attrs) {
1613 if (isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)) {
1614 foreach ($attrs[
'elements'] as $element => $eParts) {
1615 if (isset($eParts[
'ref'])) {
1616 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1618 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1619 foreach ($eParts as $aName => $aValue) {
1621 if ($aName !=
'name' && $aName !=
'type') {
1622 $contentStr .=
" $aName=\"$aValue\"";
1625 $contentStr .=
"/>\n";
1629 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1630 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n" . $contentStr .
" </$schemaPrefix:$attrs[compositor]>\n";
1634 if (isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)) {
1635 foreach ($attrs[
'attrs'] as $attr => $aParts) {
1636 $contentStr .=
" <$schemaPrefix:attribute";
1637 foreach ($aParts as
$a => $v) {
1638 if (
$a ==
'ref' ||
$a ==
'type') {
1639 $contentStr .=
" $a=\"" . $this->contractQName($v) .
'"';
1640 } elseif (
$a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1641 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1642 $contentStr .=
' wsdl:arrayType="' . $this->contractQName($v) .
'"';
1644 $contentStr .=
" $a=\"$v\"";
1647 $contentStr .=
"/>\n";
1651 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
'') {
1652 $contentStr =
" <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs[
'restrictionBase']) .
"\">\n" . $contentStr .
" </$schemaPrefix:restriction>\n";
1654 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)) {
1655 $contentStr =
" <$schemaPrefix:complexContent>\n" . $contentStr .
" </$schemaPrefix:complexContent>\n";
1659 if ($contentStr !=
'') {
1660 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr .
" </$schemaPrefix:complexType>\n";
1662 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1664 $xml .= $contentStr;
1667 if (isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
1668 foreach ($this->simpleTypes as $typeName => $eParts) {
1669 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts[
'type']) .
"\">\n";
1670 if (isset($eParts[
'enumeration'])) {
1671 foreach ($eParts[
'enumeration'] as
$e) {
1672 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1675 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1679 if (isset($this->elements) && count($this->elements) > 0) {
1680 foreach ($this->elements as $element => $eParts) {
1681 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"/>\n";
1685 if (isset($this->attributes) && count($this->attributes) > 0) {
1686 foreach ($this->attributes as $attr => $aParts) {
1687 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts[
'type']) .
"\"\n/>";
1692 foreach ($this->schemaInfo as $k => $v) {
1693 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1694 $attr .=
" $k=\"$v\"";
1697 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1698 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1699 $el .=
" xmlns:$nsp=\"$ns\"";
1701 $xml = $el .
">\n" . $xml .
"</$schemaPrefix:schema>\n";
1711 public function xdebug($string)
1713 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> ' . $string);
1728 public function getPHPType($type, $ns)
1730 if (isset($this->typemap[$ns][$type])) {
1732 return $this->typemap[$ns][$type];
1733 } elseif (isset($this->complexTypes[$type])) {
1735 return $this->complexTypes[$type][
'phpType'];
1762 public function getTypeDef($type)
1765 if (substr($type, -1) ==
'^') {
1767 $type = substr($type, 0, -1);
1772 if ((! $is_element) && isset($this->complexTypes[$type])) {
1773 $this->xdebug(
"in getTypeDef, found complexType $type");
1774 return $this->complexTypes[$type];
1775 } elseif ((! $is_element) && isset($this->simpleTypes[$type])) {
1776 $this->xdebug(
"in getTypeDef, found simpleType $type");
1777 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1780 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1781 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1782 $etype = $this->getTypeDef($uqType);
1784 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1785 $this->xdebug($this->
varDump($etype));
1786 if (isset($etype[
'phpType'])) {
1787 $this->simpleTypes[$type][
'phpType'] = $etype[
'phpType'];
1789 if (isset($etype[
'elements'])) {
1790 $this->simpleTypes[$type][
'elements'] = $etype[
'elements'];
1794 return $this->simpleTypes[$type];
1795 } elseif (isset($this->elements[$type])) {
1796 $this->xdebug(
"in getTypeDef, found element $type");
1797 if (!isset($this->elements[$type][
'phpType'])) {
1799 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1800 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1801 $etype = $this->getTypeDef($uqType);
1803 $this->xdebug(
"in getTypeDef, found type for element $type:");
1804 $this->xdebug($this->
varDump($etype));
1805 if (isset($etype[
'phpType'])) {
1806 $this->elements[$type][
'phpType'] = $etype[
'phpType'];
1808 if (isset($etype[
'elements'])) {
1809 $this->elements[$type][
'elements'] = $etype[
'elements'];
1811 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1812 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1813 $this->elements[$type][
'phpType'] =
'scalar';
1816 return $this->elements[$type];
1817 } elseif (isset($this->attributes[$type])) {
1818 $this->xdebug(
"in getTypeDef, found attribute $type");
1819 return $this->attributes[$type];
1820 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1821 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1822 $typeDef[
'typeClass'] =
'simpleType';
1823 $typeDef[
'phpType'] =
'scalar';
1824 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1827 $this->xdebug(
"in getTypeDef, did not find $type");
1839 public function serializeTypeDef($type)
1842 if ($typeDef = $this->getTypeDef($type)) {
1843 $str .=
'<' . $type;
1844 if (is_array($typeDef[
'attrs'])) {
1845 foreach ($typeDef[
'attrs'] as $attName =>
$data) {
1846 $str .=
" $attName=\"{type = " .
$data[
'type'] .
"}\"";
1849 $str .=
" xmlns=\"" . $this->schema[
'targetNamespace'] .
"\"";
1850 if (count($typeDef[
'elements']) > 0) {
1852 foreach ($typeDef[
'elements'] as $element => $eData) {
1853 $str .= $this->serializeTypeDef($element);
1856 } elseif ($typeDef[
'typeClass'] ==
'element') {
1857 $str .=
"></$type>";
1876 public function typeToForm($name, $type)
1879 if ($typeDef = $this->getTypeDef($type)) {
1881 if ($typeDef[
'phpType'] ==
'struct') {
1882 $buffer .=
'<table>';
1883 foreach ($typeDef[
'elements'] as $child => $childDef) {
1885 <tr><td align='right'>$childDef[name] (type: " . $this->
getLocalPart($childDef[
'type']) .
"):</td> 1886 <td><input type='text' name='parameters[" . $name .
"][$childDef[name]]'></td></tr>";
1888 $buffer .=
'</table>';
1890 } elseif ($typeDef[
'phpType'] ==
'array') {
1891 $buffer .=
'<table>';
1892 for ($i = 0;$i < 3; $i++) {
1894 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1895 <td><input type='text' name='parameters[" . $name .
"][]'></td></tr>";
1897 $buffer .=
'</table>';
1900 $buffer .=
"<input type='text' name='parameters[$name]'>";
1903 $buffer .=
"<input type='text' name='parameters[$name]'>";
1949 public function addComplexType($name, $typeClass =
'complexType', $phpType =
'array', $compositor =
'', $restrictionBase =
'', $elements = array(), $attrs = array(), $arrayType =
'')
1951 $this->complexTypes[$name] = array(
1953 'typeClass' => $typeClass,
1954 'phpType' => $phpType,
1955 'compositor' => $compositor,
1956 'restrictionBase' => $restrictionBase,
1957 'elements' => $elements,
1959 'arrayType' => $arrayType
1962 $this->xdebug(
"addComplexType $name:");
1978 public function addSimpleType($name, $restrictionBase =
'', $typeClass =
'simpleType', $phpType =
'scalar', $enumeration = array())
1980 $this->simpleTypes[$name] = array(
1982 'typeClass' => $typeClass,
1983 'phpType' => $phpType,
1984 'type' => $restrictionBase,
1985 'enumeration' => $enumeration
1988 $this->xdebug(
"addSimpleType $name:");
1999 public 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']);
2090 public function __construct($name =
'soapval', $type =
false, $value = -1, $element_ns =
false, $type_ns =
false, $attributes =
false)
2093 $this->name = $name;
2094 $this->type = $type;
2095 $this->value = $value;
2096 $this->element_ns = $element_ns;
2097 $this->type_ns = $type_ns;
2098 $this->attributes = $attributes;
2108 public function serialize($use =
'encoded')
2110 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2119 public function decode()
2121 return $this->value;
2146 public $digest_uri =
'';
2147 public $scheme =
'';
2151 public $request_method =
'POST';
2152 public $protocol_version =
'1.0';
2153 public $encoding =
'';
2154 public $outgoing_headers = array();
2155 public $incoming_headers = array();
2156 public $incoming_cookies = array();
2157 public $outgoing_payload =
'';
2158 public $incoming_payload =
'';
2159 public $response_status_line;
2160 public $useSOAPAction =
true;
2161 public $persistentConnection =
false;
2163 public $ch_options = array();
2164 public $use_curl =
false;
2165 public $proxy =
null;
2166 public $username =
'';
2167 public $password =
'';
2168 public $authtype =
'';
2169 public $digestRequest = array();
2170 public $certRequest = array();
2190 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2192 $this->setURL(
$url);
2193 if (is_array($curl_options)) {
2194 $this->ch_options = $curl_options;
2196 $this->use_curl = $use_curl;
2197 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2199 $this->setHeader(
'User-Agent', $this->title .
'/' . $this->version .
' (' . ($rev[1] ??
'1.1') .
')');
2209 public function setCurlOption($option, $value)
2211 $this->
debug(
"setCurlOption option=$option, value=");
2213 curl_setopt($this->ch, $option, $value);
2223 public function setHeader($name, $value)
2225 $this->outgoing_headers[$name] = $value;
2226 $this->
debug(
"set header $name: $value");
2235 public function unsetHeader($name)
2237 if (isset($this->outgoing_headers[$name])) {
2238 $this->
debug(
"unset header $name");
2239 unset($this->outgoing_headers[$name]);
2249 public function setURL(
$url)
2253 $u = parse_url(
$url);
2254 foreach ($u as $k => $v) {
2255 $this->
debug(
"parsed URL $k = $v");
2260 if (isset($u[
'query']) && $u[
'query'] !=
'') {
2261 $this->path .=
'?' . $u[
'query'];
2265 if (!isset($u[
'port'])) {
2266 if ($u[
'scheme'] ==
'https') {
2274 $this->digest_uri = $this->uri;
2277 if (!isset($u[
'port'])) {
2278 $this->setHeader(
'Host', $this->host);
2280 $this->setHeader(
'Host', $this->host .
':' . $this->port);
2283 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2284 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2294 public function io_method()
2296 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm')) {
2299 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm')) {
2313 public function connect($connection_timeout = 0, $response_timeout = 30)
2327 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2328 if ($this->io_method() ==
'socket') {
2329 if (!is_array($this->proxy)) {
2330 $host = $this->host;
2331 $port = $this->port;
2333 $host = $this->proxy[
'host'];
2334 $port = $this->proxy[
'port'];
2338 if ($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
2339 if (!feof($this->fp)) {
2340 $this->
debug(
'Re-use persistent connection');
2344 $this->
debug(
'Closed persistent connection at EOF');
2348 if ($this->scheme ==
'ssl') {
2349 $host =
'ssl://' . $host;
2351 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2354 if ($connection_timeout > 0) {
2355 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2357 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
2362 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2366 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2374 $this->
debug(
'set response timeout to ' . $response_timeout);
2375 socket_set_timeout($this->fp, $response_timeout);
2377 $this->
debug(
'socket connected');
2379 } elseif ($this->io_method() ==
'curl') {
2380 if (!extension_loaded(
'curl')) {
2382 $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.');
2386 if (defined(
'CURLOPT_CONNECTIONTIMEOUT')) {
2387 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2389 $CURLOPT_CONNECTIONTIMEOUT = 78;
2391 if (defined(
'CURLOPT_HTTPAUTH')) {
2392 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2394 $CURLOPT_HTTPAUTH = 107;
2396 if (defined(
'CURLOPT_PROXYAUTH')) {
2397 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2399 $CURLOPT_PROXYAUTH = 111;
2401 if (defined(
'CURLAUTH_BASIC')) {
2402 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2404 $CURLAUTH_BASIC = 1;
2406 if (defined(
'CURLAUTH_DIGEST')) {
2407 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2409 $CURLAUTH_DIGEST = 2;
2411 if (defined(
'CURLAUTH_NTLM')) {
2412 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2417 $this->
debug(
'connect using cURL');
2419 $this->ch = curl_init();
2421 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2424 $this->setCurlOption(CURLOPT_URL, $hostURL);
2426 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2427 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2428 $this->
debug(
'safe_mode = ');
2430 $this->
debug(
'open_basedir = ');
2433 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2436 $this->setCurlOption(CURLOPT_HEADER, 1);
2438 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2445 if ($this->persistentConnection) {
2451 $this->persistentConnection =
false;
2452 $this->setHeader(
'Connection',
'close');
2455 if ($connection_timeout != 0) {
2456 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2458 if ($response_timeout != 0) {
2459 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2462 if ($this->scheme ==
'https') {
2463 $this->
debug(
'set cURL SSL verify options');
2468 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2469 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2472 if ($this->authtype ==
'certificate') {
2473 $this->
debug(
'set cURL certificate options');
2474 if (isset($this->certRequest[
'cainfofile'])) {
2475 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2477 if (isset($this->certRequest[
'verifypeer'])) {
2478 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2480 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2482 if (isset($this->certRequest[
'verifyhost'])) {
2483 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2485 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2487 if (isset($this->certRequest[
'sslcertfile'])) {
2488 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2490 if (isset($this->certRequest[
'sslkeyfile'])) {
2491 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2493 if (isset($this->certRequest[
'passphrase'])) {
2494 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2496 if (isset($this->certRequest[
'certpassword'])) {
2497 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2501 if ($this->authtype && ($this->authtype !=
'certificate')) {
2502 if ($this->username) {
2503 $this->
debug(
'set cURL username/password');
2504 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2506 if ($this->authtype ==
'basic') {
2507 $this->
debug(
'set cURL for Basic authentication');
2508 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2510 if ($this->authtype ==
'digest') {
2511 $this->
debug(
'set cURL for digest authentication');
2512 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2514 if ($this->authtype ==
'ntlm') {
2515 $this->
debug(
'set cURL for NTLM authentication');
2516 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2519 if (is_array($this->proxy)) {
2520 $this->
debug(
'set cURL proxy options');
2521 if ($this->proxy[
'port'] !=
'') {
2522 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'] .
':' . $this->proxy[
'port']);
2524 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2526 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2527 $this->
debug(
'set cURL proxy authentication options');
2528 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'] .
':' . $this->proxy[
'password']);
2529 if ($this->proxy[
'authtype'] ==
'basic') {
2530 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2532 if ($this->proxy[
'authtype'] ==
'ntlm') {
2533 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2537 $this->
debug(
'cURL connection set up');
2540 $this->
setError(
'Unknown scheme ' . $this->scheme);
2541 $this->
debug(
'Unknown scheme ' . $this->scheme);
2556 public function send(
$data, $timeout = 0, $response_timeout = 30, $cookies =
null)
2558 $this->
debug(
'entered send() with data of length: ' . strlen(
$data));
2560 $this->tryagain =
true;
2562 while ($this->tryagain) {
2563 $this->tryagain =
false;
2566 if (!$this->connect($timeout, $response_timeout)) {
2571 if (!$this->sendRequest(
$data, $cookies)) {
2576 $respdata = $this->getResponse();
2578 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2581 $this->
debug(
'end of send()');
2597 public function sendHTTPS(
$data, $timeout = 0, $response_timeout = 30, $cookies =
null)
2599 return $this->
send(
$data, $timeout, $response_timeout, $cookies);
2612 public function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array())
2614 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2616 $this->
debug(
"certRequest=");
2619 if ($authtype ==
'basic') {
2620 $this->setHeader(
'Authorization',
'Basic ' . base64_encode(str_replace(
':',
'', $username) .
':' . $password));
2621 } elseif ($authtype ==
'digest') {
2622 if (isset($digestRequest[
'nonce'])) {
2623 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2628 $A1 = $username .
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2634 $A2 = $this->request_method .
':' . $this->digest_uri;
2650 $unhashedDigest =
'';
2651 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2653 if ($digestRequest[
'qop'] !=
'') {
2654 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2656 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2659 $hashedDigest = md5($unhashedDigest);
2662 if (isset($digestRequest[
'opaque'])) {
2663 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2666 $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 .
'"');
2668 } elseif ($authtype ==
'certificate') {
2669 $this->certRequest = $certRequest;
2670 $this->
debug(
'Authorization header not set for certificate');
2671 } elseif ($authtype ==
'ntlm') {
2673 $this->
debug(
'Authorization header not set for ntlm');
2675 $this->username = $username;
2676 $this->password = $password;
2677 $this->authtype = $authtype;
2678 $this->digestRequest = $digestRequest;
2687 public function setSOAPAction($soapaction)
2689 $this->setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2698 public function setEncoding($enc =
'gzip, deflate')
2700 if (function_exists(
'gzdeflate')) {
2701 $this->protocol_version =
'1.1';
2702 $this->setHeader(
'Accept-Encoding', $enc);
2703 if (!isset($this->outgoing_headers[
'Connection'])) {
2704 $this->setHeader(
'Connection',
'close');
2705 $this->persistentConnection =
false;
2707 #set_magic_quotes_runtime(0); 2709 $this->encoding = $enc;
2723 public function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic')
2726 $this->proxy = array(
2727 'host' => $proxyhost,
2728 'port' => $proxyport,
2729 'username' => $proxyusername,
2730 'password' => $proxypassword,
2731 'authtype' => $proxyauthtype
2733 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2734 $this->setHeader(
'Proxy-Authorization',
' Basic ' . base64_encode($proxyusername .
':' . $proxypassword));
2737 $this->
debug(
'remove proxy');
2739 unsetHeader(
'Proxy-Authorization');
2752 public function isSkippableCurlHeader(&
$data)
2754 $skipHeaders = array(
'HTTP/1.1 100',
2761 'HTTP/1.0 200 Connection established');
2762 foreach ($skipHeaders as $hd) {
2763 $prefix = substr(
$data, 0, strlen($hd));
2764 if ($prefix == $hd) {
2782 public function decodeChunked($buffer, $lb)
2790 $chunkend = strpos($buffer, $lb);
2791 if ($chunkend ==
false) {
2792 $this->
debug(
'no linebreak found in decodeChunked');
2795 $temp = substr($buffer, 0, $chunkend);
2796 $chunk_size = hexdec(trim($temp));
2797 $chunkstart = $chunkend + strlen($lb);
2799 while ($chunk_size > 0) {
2800 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2801 $chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
2804 if ($chunkend ==
false) {
2805 $chunk = substr($buffer, $chunkstart);
2808 $length += strlen($chunk);
2813 $chunk = substr($buffer, $chunkstart, $chunkend - $chunkstart);
2817 $length += strlen($chunk);
2819 $chunkstart = $chunkend + strlen($lb);
2821 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2822 if ($chunkend ==
false) {
2825 $temp = substr($buffer, $chunkstart, $chunkend - $chunkstart);
2826 $chunk_size = hexdec(trim($temp));
2827 $chunkstart = $chunkend;
2840 public function buildPayload(
$data, $cookie_str =
'')
2847 $this->setHeader(
'Content-Length', strlen(
$data));
2855 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2856 $this->
debug(
"HTTP request: $req");
2857 $this->outgoing_payload =
"$req\r\n";
2860 foreach ($this->outgoing_headers as $k => $v) {
2861 $hdr = $k .
': ' . $v;
2862 $this->
debug(
"HTTP header: $hdr");
2863 $this->outgoing_payload .=
"$hdr\r\n";
2867 if ($cookie_str !=
'') {
2868 $hdr =
'Cookie: ' . $cookie_str;
2869 $this->
debug(
"HTTP header: $hdr");
2870 $this->outgoing_payload .=
"$hdr\r\n";
2874 $this->outgoing_payload .=
"\r\n";
2877 $this->outgoing_payload .=
$data;
2888 public function sendRequest(
$data, $cookies =
null)
2891 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2894 $this->buildPayload(
$data, $cookie_str);
2896 if ($this->io_method() ==
'socket') {
2898 if (!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2899 $this->
setError(
'couldn\'t write message data to socket');
2900 $this->
debug(
'couldn\'t write message data to socket');
2903 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2905 } elseif ($this->io_method() ==
'curl') {
2911 $curl_headers = array();
2912 foreach ($this->outgoing_headers as $k => $v) {
2913 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2914 $this->
debug(
"Skip cURL header $k: $v");
2916 $curl_headers[] =
"$k: $v";
2919 if ($cookie_str !=
'') {
2920 $curl_headers[] =
'Cookie: ' . $cookie_str;
2922 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2923 $this->
debug(
'set cURL HTTP headers');
2924 if ($this->request_method ==
"POST") {
2925 $this->setCurlOption(CURLOPT_POST, 1);
2926 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2927 $this->
debug(
'set cURL POST data');
2931 foreach ($this->ch_options as $key => $val) {
2932 $this->setCurlOption($key, $val);
2935 $this->
debug(
'set cURL payload');
2946 public function getResponse()
2948 $this->incoming_payload =
'';
2950 if ($this->io_method() ==
'socket') {
2953 while (!isset($lb)) {
2955 if (feof($this->fp)) {
2956 $this->incoming_payload =
$data;
2957 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
2958 $this->
debug(
"received before EOF:\n" .
$data);
2959 $this->
setError(
'server failed to send headers');
2963 $tmp = fgets($this->fp, 256);
2964 $tmplen = strlen($tmp);
2965 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
2968 $this->incoming_payload =
$data;
2969 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
2970 $this->
debug(
"read before timeout: " .
$data);
2971 $this->
setError(
'socket read of headers timed out');
2976 $pos = strpos(
$data,
"\r\n\r\n");
2980 $pos = strpos(
$data,
"\n\n");
2986 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
2992 $this->incoming_payload .=
$data;
2993 $this->
debug(
'found end of headers after length ' . strlen(
$data));
2995 $header_data = trim(substr(
$data, 0, $pos));
2996 $header_array = explode($lb, $header_data);
2997 $this->incoming_headers = array();
2998 $this->incoming_cookies = array();
2999 foreach ($header_array as $header_line) {
3000 $arr = explode(
':', $header_line, 2);
3001 if (count($arr) > 1) {
3002 $header_name = strtolower(trim($arr[0]));
3003 $this->incoming_headers[$header_name] = trim($arr[1]);
3004 if ($header_name ==
'set-cookie') {
3006 $cookie = $this->parseCookie(trim($arr[1]));
3008 $this->incoming_cookies[] = $cookie;
3009 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3011 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3014 } elseif (isset($header_name)) {
3016 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3021 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
3022 $content_length = 2147483647;
3024 $this->
debug(
"want to read chunked content");
3025 } elseif (isset($this->incoming_headers[
'content-length'])) {
3026 $content_length = $this->incoming_headers[
'content-length'];
3028 $this->
debug(
"want to read content of length $content_length");
3030 $content_length = 2147483647;
3032 $this->
debug(
"want to read content to EOF");
3037 $tmp = fgets($this->fp, 256);
3038 $tmplen = strlen($tmp);
3039 $this->
debug(
"read chunk line of $tmplen bytes");
3041 $this->incoming_payload =
$data;
3042 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3043 $this->
debug(
"read before timeout:\n" .
$data);
3044 $this->
setError(
'socket read of chunk length timed out');
3047 $content_length = hexdec(trim($tmp));
3048 $this->
debug(
"chunk length $content_length");
3051 while (($strlen < $content_length) && (!feof($this->fp))) {
3052 $readlen = min(8192, $content_length - $strlen);
3053 $tmp = fread($this->fp, $readlen);
3054 $tmplen = strlen($tmp);
3055 $this->
debug(
"read buffer of $tmplen bytes");
3056 if (($tmplen == 0) && (!feof($this->fp))) {
3057 $this->incoming_payload =
$data;
3058 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3059 $this->
debug(
"read before timeout:\n" .
$data);
3060 $this->
setError(
'socket read of body timed out');
3066 if ($chunked && ($content_length > 0)) {
3067 $tmp = fgets($this->fp, 256);
3068 $tmplen = strlen($tmp);
3069 $this->
debug(
"read chunk terminator of $tmplen bytes");
3071 $this->incoming_payload =
$data;
3072 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3073 $this->
debug(
"read before timeout:\n" .
$data);
3074 $this->
setError(
'socket read of chunk terminator timed out');
3078 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3079 if (feof($this->fp)) {
3080 $this->
debug(
'read to EOF');
3082 $this->
debug(
'read body of length ' . strlen(
$data));
3083 $this->incoming_payload .=
$data;
3084 $this->
debug(
'received a total of ' . strlen($this->incoming_payload) .
' bytes of data from server');
3088 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3089 (! $this->persistentConnection) || feof($this->fp)) {
3092 $this->
debug(
'closed socket');
3096 if ($this->incoming_payload ==
'') {
3097 $this->
setError(
'no response from server');
3111 } elseif ($this->io_method() ==
'curl') {
3113 $this->
debug(
'send and receive with cURL');
3114 $this->incoming_payload = curl_exec($this->ch);
3115 $data = $this->incoming_payload;
3117 $cErr = curl_error($this->ch);
3119 $err =
'cURL ERROR: ' . curl_errno($this->ch) .
': ' . $cErr .
'<br>';
3121 foreach (curl_getinfo($this->ch) as $k => $v) {
3122 $err .=
"$k: $v<br>";
3126 curl_close($this->ch);
3134 $this->
debug(
'No cURL error, closing cURL');
3135 curl_close($this->ch);
3139 while ($this->isSkippableCurlHeader(
$data)) {
3140 $this->
debug(
"Found HTTP header to skip");
3141 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3143 } elseif ($pos = strpos(
$data,
"\n\n")) {
3151 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3152 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3154 } elseif ($pos = strpos(
$data,
"\n\n")) {
3161 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3163 } elseif ($pos = strpos(
$data,
"\n\n")) {
3166 $this->
debug(
'no proper separation of headers and document');
3167 $this->
setError(
'no proper separation of headers and document');
3170 $header_data = trim(substr(
$data, 0, $pos));
3171 $header_array = explode($lb, $header_data);
3173 $this->
debug(
'found proper separation of headers and document');
3174 $this->
debug(
'cleaned data, stringlen: ' . strlen(
$data));
3176 foreach ($header_array as $header_line) {
3177 $arr = explode(
':', $header_line, 2);
3178 if (count($arr) > 1) {
3179 $header_name = strtolower(trim($arr[0]));
3180 $this->incoming_headers[$header_name] = trim($arr[1]);
3181 if ($header_name ==
'set-cookie') {
3183 $cookie = $this->parseCookie(trim($arr[1]));
3185 $this->incoming_cookies[] = $cookie;
3186 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3188 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3191 } elseif (isset($header_name)) {
3193 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3198 $this->response_status_line = $header_array[0];
3199 $arr = explode(
' ', $this->response_status_line, 3);
3200 $http_version = $arr[0];
3201 $http_status = intval($arr[1]);
3202 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3205 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3206 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3207 $this->setURL($this->incoming_headers[
'location']);
3208 $this->tryagain =
true;
3213 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3214 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3215 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3216 $this->
debug(
'Server wants digest authentication');
3218 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3221 $digestElements = explode(
',', $digestString);
3222 foreach ($digestElements as $val) {
3223 $tempElement = explode(
'=', trim($val), 2);
3224 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3228 if (isset($digestRequest[
'nonce'])) {
3229 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3230 $this->tryagain =
true;
3234 $this->
debug(
'HTTP authentication failed');
3235 $this->
setError(
'HTTP authentication failed');
3240 ($http_status >= 300 && $http_status <= 307) ||
3241 ($http_status >= 400 && $http_status <= 417) ||
3242 ($http_status >= 501 && $http_status <= 505)
3244 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3249 if (isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
'') {
3250 if (strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip') {
3252 if (function_exists(
'gzinflate')) {
3256 $this->
debug(
'The gzinflate function exists');
3257 $datalen = strlen(
$data);
3258 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3259 if ($degzdata = @gzinflate(
$data)) {
3261 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3262 if (strlen(
$data) < $datalen) {
3264 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3265 if ($degzdata = @gzinflate(
$data)) {
3267 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3271 $this->
debug(
'Error using gzinflate to inflate the payload');
3272 $this->
setError(
'Error using gzinflate to inflate the payload');
3274 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3275 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3277 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3278 if (strlen(
$data) < $datalen) {
3280 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3281 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3283 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3287 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3288 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3294 $this->incoming_payload = $header_data . $lb . $lb .
$data;
3296 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3297 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3300 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3301 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3304 $this->
debug(
'No Content-Encoding header');
3307 if (strlen(
$data) == 0) {
3308 $this->
debug(
'no data after headers!');
3309 $this->
setError(
'no data present after HTTP headers');
3323 public function setContentType($type, $charset =
false)
3325 $this->setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3334 public function usePersistentConnection()
3336 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3339 $this->protocol_version =
'1.1';
3340 $this->persistentConnection =
true;
3341 $this->setHeader(
'Connection',
'Keep-Alive');
3355 public function parseCookie($cookie_str)
3357 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3360 $data = explode(
';', $cookie_str);
3361 $value_str =
$data[0];
3363 $cookie_param =
'domain=';
3364 $start = strpos($cookie_str, $cookie_param);
3366 $domain = substr($cookie_str, $start + strlen($cookie_param));
3367 $domain = substr($domain, 0, strpos($domain,
';'));
3372 $cookie_param =
'expires=';
3373 $start = strpos($cookie_str, $cookie_param);
3375 $expires = substr($cookie_str, $start + strlen($cookie_param));
3376 $expires = substr($expires, 0, strpos($expires,
';'));
3381 $cookie_param =
'path=';
3382 $start = strpos($cookie_str, $cookie_param);
3384 $path = substr($cookie_str, $start + strlen($cookie_param));
3390 $cookie_param =
';secure;';
3391 if (strpos($cookie_str, $cookie_param) !==
false) {
3397 $sep_pos = strpos($value_str,
'=');
3400 $name = substr($value_str, 0, $sep_pos);
3401 $value = substr($value_str, $sep_pos + 1);
3402 $cookie = array(
'name' => $name,
3404 'domain' => $domain,
3406 'expires' => $expires,
3422 public function getCookiesForRequest($cookies, $secure =
false)
3425 if ((! is_null($cookies)) && (is_array($cookies))) {
3426 foreach ($cookies as $cookie) {
3427 if (! is_array($cookie)) {
3430 $this->
debug(
"check cookie for validity: " . $cookie[
'name'] .
'=' . $cookie[
'value']);
3431 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3432 if (strtotime($cookie[
'expires']) <= time()) {
3433 $this->
debug(
'cookie has expired');
3437 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3438 $domain = preg_quote($cookie[
'domain']);
3439 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3440 $this->
debug(
'cookie has different domain');
3444 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3445 $path = preg_quote($cookie[
'path']);
3446 if (! preg_match(
"'^$path.*'i", $this->path)) {
3447 $this->
debug(
'cookie is for a different path');
3451 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3452 $this->
debug(
'cookie is secure, transport is not');
3455 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3456 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3485 public $headers = array();
3491 public $request =
'';
3497 public $requestHeaders =
'';
3503 public $requestHeader =
null;
3509 public $document =
'';
3515 public $requestSOAP =
'';
3521 public $methodURI =
'';
3527 public $methodname =
'';
3533 public $methodparams = array();
3539 public $SOAPAction =
'';
3545 public $xml_encoding =
'';
3551 public $decode_utf8 =
true;
3559 public $outgoing_headers = array();
3571 public $responseHeaders =
'';
3577 public $responseSOAP =
'';
3583 public $methodreturn =
false;
3589 public $methodreturnisliteralxml =
false;
3595 public $fault =
false;
3601 public $result =
'successful';
3609 public $operations = array();
3615 public $wsdl =
false;
3621 public $externalWSDLURL =
false;
3627 public $debug_flag =
false;
3642 global $HTTP_SERVER_VARS;
3645 $this->
debug(
"_SERVER is defined:");
3647 } elseif (isset($HTTP_SERVER_VARS)) {
3648 $this->
debug(
"HTTP_SERVER_VARS is defined:");
3651 $this->
debug(
"Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3654 if (isset($debug)) {
3655 $this->
debug(
"In nusoap_server, set debug_flag=$debug based on global flag");
3656 $this->debug_flag = $debug;
3657 } elseif (isset(
$_SERVER[
'QUERY_STRING'])) {
3658 $qs = explode(
'&',
$_SERVER[
'QUERY_STRING']);
3659 foreach ($qs as $v) {
3660 if (substr($v, 0, 6) ==
'debug=') {
3661 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #1");
3662 $this->debug_flag = substr($v, 6);
3665 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3666 $qs = explode(
'&', $HTTP_SERVER_VARS[
'QUERY_STRING']);
3667 foreach ($qs as $v) {
3668 if (substr($v, 0, 6) ==
'debug=') {
3669 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #2");
3670 $this->debug_flag = substr($v, 6);
3677 $this->
debug(
"In nusoap_server, WSDL is specified");
3678 if (is_object($wsdl) && (get_class($wsdl) ==
'wsdl')) {
3679 $this->
wsdl = $wsdl;
3680 $this->externalWSDLURL = $this->
wsdl->wsdl;
3681 $this->
debug(
'Use existing wsdl instance from ' . $this->externalWSDLURL);
3683 $this->
debug(
'Create wsdl from ' . $wsdl);
3685 $this->externalWSDLURL = $wsdl;
3690 die(
'WSDL ERROR: ' . $err);
3701 public function service(
$data)
3703 global $HTTP_SERVER_VARS;
3705 if (isset(
$_SERVER[
'QUERY_STRING'])) {
3707 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3708 $qs = $HTTP_SERVER_VARS[
'QUERY_STRING'];
3712 $this->
debug(
"In service, query string=$qs");
3714 if (preg_match(
'/wsdl/', $qs)) {
3715 $this->
debug(
"In service, this is a request for WSDL");
3716 if ($this->externalWSDLURL) {
3717 if (strpos($this->externalWSDLURL,
"://") !==
false) {
3718 header(
'Location: ' . $this->externalWSDLURL);
3720 header(
"Content-Type: text/xml\r\n");
3721 $fp = fopen($this->externalWSDLURL,
'r');
3724 } elseif ($this->
wsdl) {
3725 header(
"Content-Type: text/xml; charset=ISO-8859-1\r\n");
3727 if ($this->debug_flag) {
3728 $this->
debug(
'wsdl:');
3733 header(
"Content-Type: text/html; charset=ISO-8859-1\r\n");
3734 print
"This service does not provide WSDL";
3737 $this->
debug(
"In service, there is no data, so return Web description");
3740 $this->
debug(
"In service, invoke the request");
3741 $this->parse_request(
$data);
3742 if (! $this->fault) {
3743 $this->invoke_method();
3745 if (! $this->fault) {
3746 $this->serialize_return();
3748 $this->send_response();
3764 public function parse_http_headers()
3766 global $HTTP_SERVER_VARS;
3768 $this->request =
'';
3769 $this->SOAPAction =
'';
3770 if (function_exists(
'getallheaders')) {
3771 $this->
debug(
"In parse_http_headers, use getallheaders");
3772 $headers = getallheaders();
3773 foreach ($headers as $k => $v) {
3774 $k = strtolower($k);
3775 $this->headers[$k] = $v;
3776 $this->request .=
"$k: $v\r\n";
3777 $this->
debug(
"$k: $v");
3780 if (isset($this->headers[
'soapaction'])) {
3781 $this->SOAPAction = str_replace(
'"',
'', $this->headers[
'soapaction']);
3784 if (isset($this->headers[
'content-type']) && strpos($this->headers[
'content-type'],
'=')) {
3785 $enc = str_replace(
'"',
'', substr(strstr($this->headers[
"content-type"],
'='), 1));
3786 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3787 $this->xml_encoding = strtoupper($enc);
3789 $this->xml_encoding =
'US-ASCII';
3793 $this->xml_encoding =
'ISO-8859-1';
3796 $this->
debug(
"In parse_http_headers, use _SERVER");
3798 if (substr($k, 0, 5) ==
'HTTP_') {
3799 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3801 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3803 if ($k ==
'soapaction') {
3806 $v = str_replace(
'"',
'', $v);
3807 $v = str_replace(
'\\',
'', $v);
3808 $this->SOAPAction = $v;
3809 } elseif ($k ==
'content-type') {
3811 if (strpos($v,
'=')) {
3812 $enc = substr(strstr($v,
'='), 1);
3813 $enc = str_replace(
'"',
'', $enc);
3814 $enc = str_replace(
'\\',
'', $enc);
3815 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3816 $this->xml_encoding = strtoupper($enc);
3818 $this->xml_encoding =
'US-ASCII';
3822 $this->xml_encoding =
'ISO-8859-1';
3825 $this->headers[$k] = $v;
3826 $this->request .=
"$k: $v\r\n";
3827 $this->
debug(
"$k: $v");
3829 } elseif (is_array($HTTP_SERVER_VARS)) {
3830 $this->
debug(
"In parse_http_headers, use HTTP_SERVER_VARS");
3831 foreach ($HTTP_SERVER_VARS as $k => $v) {
3832 if (substr($k, 0, 5) ==
'HTTP_') {
3833 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3834 $k = strtolower(substr($k, 5));
3836 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3837 $k = strtolower($k);
3839 if ($k ==
'soapaction') {
3842 $v = str_replace(
'"',
'', $v);
3843 $v = str_replace(
'\\',
'', $v);
3844 $this->SOAPAction = $v;
3845 } elseif ($k ==
'content-type') {
3847 if (strpos($v,
'=')) {
3848 $enc = substr(strstr($v,
'='), 1);
3849 $enc = str_replace(
'"',
'', $enc);
3850 $enc = str_replace(
'\\',
'', $enc);
3851 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3852 $this->xml_encoding = strtoupper($enc);
3854 $this->xml_encoding =
'US-ASCII';
3858 $this->xml_encoding =
'ISO-8859-1';
3861 $this->headers[$k] = $v;
3862 $this->request .=
"$k: $v\r\n";
3863 $this->
debug(
"$k: $v");
3866 $this->
debug(
"In parse_http_headers, HTTP headers not accessible");
3867 $this->
setError(
"HTTP headers not accessible");
3893 public function parse_request(
$data =
'')
3895 $this->
debug(
'entering parse_request()');
3896 $this->parse_http_headers();
3897 $this->
debug(
'got character encoding: ' . $this->xml_encoding);
3899 if (isset($this->headers[
'content-encoding']) && $this->headers[
'content-encoding'] !=
'') {
3900 $this->
debug(
'got content encoding: ' . $this->headers[
'content-encoding']);
3901 if ($this->headers[
'content-encoding'] ==
'deflate' || $this->headers[
'content-encoding'] ==
'gzip') {
3903 if (function_exists(
'gzuncompress')) {
3904 if ($this->headers[
'content-encoding'] ==
'deflate' && $degzdata = @gzuncompress(
$data)) {
3906 } elseif ($this->headers[
'content-encoding'] ==
'gzip' && $degzdata = gzinflate(substr(
$data, 10))) {
3909 $this->fault(
'SOAP-ENV:Client',
'Errors occurred when trying to decode the data');
3913 $this->fault(
'SOAP-ENV:Client',
'This Server does not support compressed data');
3918 $this->request .=
"\r\n" .
$data;
3919 $data = $this->parseRequest($this->headers,
$data);
3920 $this->requestSOAP =
$data;
3921 $this->
debug(
'leaving parse_request');
3941 public function invoke_method()
3943 $this->
debug(
'in invoke_method, methodname=' . $this->methodname .
' methodURI=' . $this->methodURI .
' SOAPAction=' . $this->SOAPAction);
3947 $this->
debug(
'in invoke_method, found WSDL operation=' . $this->methodname);
3951 $this->
debug(
'in invoke_method, found WSDL soapAction=' . $this->SOAPAction .
' for operation=' . $this->opData[
'name']);
3953 $this->methodname = $this->opData[
'name'];
3955 $this->
debug(
'in invoke_method, no WSDL for operation=' . $this->methodname);
3956 $this->fault(
'SOAP-ENV:Client',
"Operation '" . $this->methodname .
"' is not defined in the WSDL for this service");
3960 $this->
debug(
'in invoke_method, no WSDL to validate method');
3968 if (strpos($this->methodname,
'..') > 0) {
3970 } elseif (strpos($this->methodname,
'.') > 0) {
3976 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3977 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3979 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3980 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3981 $this->
debug(
"in invoke_method, class=$class method=$method delim=$delim");
3985 if ($class ==
'' && $this->
class !=
'') {
3986 $class = $this->class;
3988 $method = $this->methodname;
3993 if (!function_exists($this->methodname)) {
3994 $this->
debug(
"in invoke_method, function '$this->methodname' not found!");
3995 $this->result =
'fault: method not found';
3996 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4000 $method_to_compare = (substr(phpversion(), 0, 2) ==
'4.') ? strtolower($method) : $method;
4001 if (!in_array($method_to_compare, get_class_methods($class))) {
4002 $this->
debug(
"in invoke_method, method '$this->methodname' not found in class '$class'!");
4003 $this->result =
'fault: method not found';
4004 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4011 if (! $this->verify_method($this->methodname, $this->methodparams)) {
4013 $this->
debug(
'ERROR: request not verified against method signature');
4014 $this->result =
'fault: request failed validation against method signature';
4016 $this->fault(
'SOAP-ENV:Client',
"Operation '$this->methodname' not defined in service.");
4021 $this->
debug(
'in invoke_method, params:');
4023 $this->
debug(
"in invoke_method, calling '$this->methodname'");
4024 if (!function_exists(
'call_user_func_array')) {
4026 $this->
debug(
'in invoke_method, calling function using eval()');
4027 $funcCall =
"\$this->methodreturn = $this->methodname(";
4029 if ($delim ==
'..') {
4030 $this->
debug(
'in invoke_method, calling class method using eval()');
4031 $funcCall =
"\$this->methodreturn = " . $class .
"::" . $method .
"(";
4033 $this->
debug(
'in invoke_method, calling instance method using eval()');
4035 $instname =
"\$inst_" . time();
4036 $funcCall = $instname .
" = new " . $class .
"(); ";
4037 $funcCall .=
"\$this->methodreturn = " . $instname .
"->" . $method .
"(";
4040 if ($this->methodparams) {
4041 foreach ($this->methodparams as
$param) {
4042 if (is_array($param) || is_object($param)) {
4043 $this->fault(
'SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
4046 $funcCall .=
"\"$param\",";
4048 $funcCall = substr($funcCall, 0, -1);
4051 $this->
debug(
'in invoke_method, function call: ' . $funcCall);
4055 $this->
debug(
'in invoke_method, calling function using call_user_func_array()');
4056 $call_arg =
"$this->methodname";
4057 } elseif ($delim ==
'..') {
4058 $this->
debug(
'in invoke_method, calling class method using call_user_func_array()');
4059 $call_arg = array($class, $method);
4061 $this->
debug(
'in invoke_method, calling instance method using call_user_func_array()');
4062 $instance =
new $class();
4063 $call_arg = array(&$instance, $method);
4065 if (is_array($this->methodparams)) {
4066 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4068 $this->methodreturn = call_user_func_array($call_arg, array());
4071 $this->
debug(
'in invoke_method, methodreturn:');
4073 $this->
debug(
"in invoke_method, called method $this->methodname, received data of type " . gettype($this->methodreturn));
4087 public function serialize_return()
4089 $this->
debug(
'Entering serialize_return methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4091 if (isset($this->methodreturn) && ((get_class((
object) $this->methodreturn) ==
'soap_fault') || (get_class((
object) $this->methodreturn) ==
'nusoap_fault'))) {
4092 $this->
debug(
'got a fault object from method');
4093 $this->fault = $this->methodreturn;
4095 } elseif ($this->methodreturnisliteralxml) {
4096 $return_val = $this->methodreturn;
4099 $this->
debug(
'got a(n) ' . gettype($this->methodreturn) .
' from method');
4100 $this->
debug(
'serializing return value');
4102 if (
sizeof($this->opData[
'output'][
'parts']) > 1) {
4103 $this->
debug(
'more than one output part, so use the method return unchanged');
4104 $opParams = $this->methodreturn;
4105 } elseif (
sizeof($this->opData[
'output'][
'parts']) == 1) {
4106 $this->
debug(
'exactly one output part, so wrap the method return in a simple array');
4111 $opParams = array($this->methodreturn);
4117 $this->
debug(
'got wsdl error: ' . $errstr);
4118 $this->fault(
'SOAP-ENV:Server',
'unable to serialize result');
4122 if (isset($this->methodreturn)) {
4123 $return_val = $this->
serialize_val($this->methodreturn,
'return');
4126 $this->
debug(
'in absence of WSDL, assume void return for backward compatibility');
4130 $this->
debug(
'return value:');
4133 $this->
debug(
'serializing response');
4135 $this->
debug(
'have WSDL for serialization: style is ' . $this->opData[
'style']);
4136 if ($this->opData[
'style'] ==
'rpc') {
4137 $this->
debug(
'style is rpc for serialization: use is ' . $this->opData[
'output'][
'use']);
4138 if ($this->opData[
'output'][
'use'] ==
'literal') {
4140 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4142 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4145 $this->
debug(
'style is not rpc for serialization: assume document');
4149 $this->
debug(
'do not have WSDL for serialization: assume rpc/encoded');
4150 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4152 $this->result =
'successful';
4157 if (isset($opData[
'output'][
'encodingStyle'])) {
4158 $encodingStyle = $opData[
'output'][
'encodingStyle'];
4160 $encodingStyle =
'';
4163 $this->responseSOAP = $this->
serializeEnvelope(
$payload, $this->responseHeaders, $this->
wsdl->usedNamespaces, $this->opData[
'style'], $this->opData[
'output'][
'use'], $encodingStyle);
4167 $this->
debug(
"Leaving serialize_return");
4180 public function send_response()
4182 $this->
debug(
'Enter send_response');
4184 $payload = $this->fault->serialize();
4185 $this->outgoing_headers[] =
"HTTP/1.0 500 Internal Server Error";
4186 $this->outgoing_headers[] =
"Status: 500 Internal Server Error";
4196 if (isset($this->debug_flag) && $this->debug_flag) {
4199 $this->outgoing_headers[] =
"Server: $this->title Server v$this->version";
4200 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
4201 $this->outgoing_headers[] =
"X-SOAP-Server: $this->title/$this->version (" . $rev[1] .
")";
4205 $type = $this->getHTTPContentType();
4206 $charset = $this->getHTTPContentTypeCharset();
4207 $this->outgoing_headers[] =
"Content-Type: $type" . ($charset ?
'; charset=' . $charset :
'');
4211 if (strlen(
$payload) > 1024 && isset($this->headers) && isset($this->headers[
'accept-encoding'])) {
4212 if (strstr($this->headers[
'accept-encoding'],
'gzip')) {
4213 if (function_exists(
'gzencode')) {
4214 if (isset($this->debug_flag) && $this->debug_flag) {
4215 $payload .=
"<!-- Content being gzipped -->";
4217 $this->outgoing_headers[] =
"Content-Encoding: gzip";
4220 if (isset($this->debug_flag) && $this->debug_flag) {
4221 $payload .=
"<!-- Content will not be gzipped: no gzencode -->";
4224 } elseif (strstr($this->headers[
'accept-encoding'],
'deflate')) {
4228 if (function_exists(
'gzdeflate')) {
4229 if (isset($this->debug_flag) && $this->debug_flag) {
4230 $payload .=
"<!-- Content being deflated -->";
4232 $this->outgoing_headers[] =
"Content-Encoding: deflate";
4235 if (isset($this->debug_flag) && $this->debug_flag) {
4236 $payload .=
"<!-- Content will not be deflated: no gzcompress -->";
4242 $this->outgoing_headers[] =
"Content-Length: " . strlen(
$payload);
4243 reset($this->outgoing_headers);
4244 foreach ($this->outgoing_headers as $hdr) {
4248 $this->response = join(
"\r\n", $this->outgoing_headers) .
"\r\n\r\n" .
$payload;
4260 public function verify_method($operation, $request)
4262 if (isset($this->
wsdl) && is_object($this->
wsdl)) {
4266 } elseif (isset($this->operations[$operation])) {
4280 public function parseRequest($headers,
$data)
4282 $this->
debug(
'Entering parseRequest() for data of length ' . strlen(
$data) .
' and type ' . $headers[
'content-type']);
4283 if (!strstr($headers[
'content-type'],
'text/xml')) {
4284 $this->
setError(
'Request not of type text/xml');
4287 if (strpos($headers[
'content-type'],
'=')) {
4288 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
4289 $this->
debug(
'Got response encoding: ' . $enc);
4290 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
4291 $this->xml_encoding = strtoupper($enc);
4293 $this->xml_encoding =
'US-ASCII';
4297 $this->xml_encoding =
'ISO-8859-1';
4299 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
4303 $this->
debug(
"parser debug: \n" . $parser->getDebug());
4305 if ($err = $parser->getError()) {
4306 $this->result =
'fault: error in msg parsing: ' . $err;
4307 $this->fault(
'SOAP-ENV:Client',
"error in msg parsing:\n" . $err);
4311 $this->methodURI = $parser->root_struct_namespace;
4312 $this->methodname = $parser->root_struct_name;
4313 $this->
debug(
'methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4314 $this->
debug(
'calling parser->get_soapbody()');
4315 $this->methodparams = $parser->get_soapbody();
4317 $this->requestHeaders = $parser->getHeaders();
4319 $this->requestHeader = $parser->get_soapheader();
4321 $this->document = $parser->document;
4332 public function getHTTPBody($soapmsg)
4345 public function getHTTPContentType()
4359 public function getHTTPContentTypeCharset()
4373 public function add_to_map($methodname, $in,
$out)
4375 $this->operations[$methodname] = array(
'name' => $methodname,
'in' => $in,
'out' =>
$out);
4392 public function register($name, $in = array(),
$out = array(),
$namespace =
false, $soapaction =
false, $style =
false, $use =
false, $documentation =
'', $encodingStyle =
'')
4394 global $HTTP_SERVER_VARS;
4396 if ($this->externalWSDLURL) {
4397 die(
'You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4400 die(
'You must specify a name when you register an operation');
4402 if (!is_array($in)) {
4403 die(
'You must provide an array for operation inputs');
4405 if (!is_array(
$out)) {
4406 die(
'You must provide an array for operation outputs');
4410 if (
false == $soapaction) {
4412 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4414 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4415 } elseif (isset($HTTP_SERVER_VARS)) {
4416 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4417 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4418 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4420 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4422 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4427 $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4429 if (
false == $style) {
4432 if (
false == $use) {
4435 if ($use ==
'encoded' && $encodingStyle =
'') {
4436 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
4439 $this->operations[$name] = array(
4444 'soapaction' => $soapaction,
4482 public function configureWSDL(
$serviceName,
$namespace =
false, $endpoint =
false, $style =
'rpc', $transport =
'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace =
false)
4484 global $HTTP_SERVER_VARS;
4487 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4488 $SERVER_PORT =
$_SERVER[
'SERVER_PORT'];
4490 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4491 } elseif (isset($HTTP_SERVER_VARS)) {
4492 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4493 $SERVER_PORT = $HTTP_SERVER_VARS[
'SERVER_PORT'];
4494 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4495 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4497 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4500 $colon = strpos($SERVER_NAME,
":");
4502 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4504 if ($SERVER_PORT == 80) {
4507 $SERVER_PORT =
':' . $SERVER_PORT;
4510 $namespace =
"http://$SERVER_NAME/soap/$serviceName";
4513 if (
false == $endpoint) {
4514 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4519 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4522 if (
false == $schemaTargetNamespace) {
4528 $this->
wsdl->endpoint = $endpoint;
4530 $this->
wsdl->namespaces[
'soap'] =
'http://schemas.xmlsoap.org/wsdl/soap/';
4531 $this->
wsdl->namespaces[
'wsdl'] =
'http://schemas.xmlsoap.org/wsdl/';
4533 $this->
wsdl->namespaces[
'types'] = $schemaTargetNamespace;
4536 if ($style ==
'document') {
4537 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo[
'elementFormDefault'] =
'qualified';
4539 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4540 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4541 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4545 'transport' => $transport,
4549 'location' => $endpoint,
4550 'bindingType' =>
'http://schemas.xmlsoap.org/wsdl/soap/');
4555 $port = $this->
wsdl->ports[$serviceName .
'Port'] ?? [
4556 'binding' => $serviceName .
'Binding',
4558 'bindingType' =>
'http://schemas.xmlsoap.org/wsdl/soap/' 4561 $port[
'location'] = is_array($port[
'location']) ? array_merge($port[
'location'], [$url]) : [$port[
'location'], $url];
4563 $this->
wsdl->ports[$serviceName .
'Port'] = $port;
4592 public $currentPortOperation;
4595 public $schemas = array();
4596 public $currentSchema;
4598 public $complexTypes = array();
4600 public $currentMessage;
4601 public $currentOperation;
4602 public $portTypes = array();
4603 public $currentPortType;
4604 public $bindings = array();
4605 public $currentBinding;
4606 public $ports = array();
4607 public $currentPort;
4608 public $opData = array();
4609 public $status =
'';
4610 public $documentation =
false;
4611 public $endpoint =
'';
4613 public $import = array();
4616 public $position = 0;
4618 public $depth_array = array();
4620 public $proxyhost =
'';
4621 public $proxyport =
'';
4622 public $proxyusername =
'';
4623 public $proxypassword =
'';
4624 public $timeout = 0;
4625 public $response_timeout = 30;
4626 public $curl_options = array();
4627 public $use_curl =
false;
4629 public $username =
'';
4630 public $password =
'';
4631 public $authtype =
'';
4632 public $certRequest = array();
4648 public function __construct($wsdl =
'', $proxyhost =
false, $proxyport =
false, $proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30, $curl_options =
null, $use_curl =
false)
4651 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4652 $this->proxyhost = $proxyhost;
4653 $this->proxyport = $proxyport;
4654 $this->proxyusername = $proxyusername;
4655 $this->proxypassword = $proxypassword;
4656 $this->timeout = $timeout;
4657 $this->response_timeout = $response_timeout;
4658 if (is_array($curl_options)) {
4659 $this->curl_options = $curl_options;
4661 $this->use_curl = $use_curl;
4662 $this->fetchWSDL($wsdl);
4670 public function fetchWSDL($wsdl)
4672 $this->
debug(
"parse and process WSDL path=$wsdl");
4673 $this->
wsdl = $wsdl;
4675 if ($this->
wsdl !=
"") {
4676 $this->parseWSDL($this->
wsdl);
4680 $imported_urls = array();
4682 while ($imported > 0) {
4685 foreach ($this->schemas as $ns => $list) {
4686 foreach ($list as $xs) {
4687 $wsdlparts = parse_url($this->
wsdl);
4688 foreach ($xs->imports as $ns2 => $list2) {
4689 for ($ii = 0; $ii < count($list2); $ii++) {
4690 if (! $list2[$ii][
'loaded']) {
4691 $this->schemas[$ns]->imports[$ns2][$ii][
'loaded'] =
true;
4692 $url = $list2[$ii][
'location'];
4694 $urlparts = parse_url(
$url);
4695 if (!isset($urlparts[
'host'])) {
4696 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4697 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4699 if (! in_array(
$url, $imported_urls)) {
4700 $this->parseWSDL(
$url);
4702 $imported_urls[] =
$url;
4705 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4713 $wsdlparts = parse_url($this->
wsdl);
4714 foreach ($this->
import as $ns => $list) {
4715 for ($ii = 0; $ii < count($list); $ii++) {
4716 if (! $list[$ii][
'loaded']) {
4717 $this->
import[$ns][$ii][
'loaded'] =
true;
4718 $url = $list[$ii][
'location'];
4720 $urlparts = parse_url(
$url);
4721 if (!isset($urlparts[
'host'])) {
4722 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4723 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4725 if (! in_array(
$url, $imported_urls)) {
4726 $this->parseWSDL(
$url);
4728 $imported_urls[] =
$url;
4731 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4738 foreach ($this->bindings as $binding => $bindingData) {
4739 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4740 foreach ($bindingData[
'operations'] as $operation =>
$data) {
4741 $this->
debug(
'post-parse data gathering for ' . $operation);
4742 $this->bindings[$binding][
'operations'][$operation][
'input'] =
4743 isset($this->bindings[$binding][
'operations'][$operation][
'input']) ?
4744 array_merge($this->bindings[$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4745 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4746 $this->bindings[$binding][
'operations'][$operation][
'output'] =
4747 isset($this->bindings[$binding][
'operations'][$operation][
'output']) ?
4748 array_merge($this->bindings[$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4749 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4750 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ])) {
4751 $this->bindings[$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ];
4753 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ])) {
4754 $this->bindings[$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ];
4757 if (isset($bindingData[
'style']) && !isset($this->bindings[$binding][
'operations'][$operation][
'style'])) {
4758 $this->bindings[$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4760 $this->bindings[$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4761 $this->bindings[$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4762 $this->bindings[$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4774 public function parseWSDL($wsdl =
'')
4776 $this->
debug(
"parse WSDL at path=$wsdl");
4779 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4780 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4785 $wsdl_props = parse_url($wsdl);
4787 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4788 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4791 $tr->request_method =
'GET';
4792 $tr->useSOAPAction =
false;
4793 if ($this->proxyhost && $this->proxyport) {
4794 $tr->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
4796 if ($this->authtype !=
'') {
4797 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4799 $tr->setEncoding(
'gzip, deflate');
4800 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4805 if ($err = $tr->getError()) {
4806 $errstr =
'HTTP ERROR: ' . $err;
4807 $this->
debug($errstr);
4813 $this->
debug(
"got WSDL URL");
4816 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4817 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4822 if ($fp = @fopen(
$path,
'r')) {
4824 while (
$data = fread($fp, 32768)) {
4825 $wsdl_string .=
$data;
4829 $errstr =
"Bad path to WSDL file $path";
4830 $this->
debug($errstr);
4835 $this->
debug(
'Parse WSDL');
4838 $this->parser = xml_parser_create();
4841 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4844 xml_set_element_handler($this->parser, $this->start_element(...), $this->end_element(...));
4845 xml_set_character_data_handler($this->parser, $this->character_data(...));
4847 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4850 'XML error parsing WSDL from %s on line %d: %s',
4852 xml_get_current_line_number($this->parser),
4853 xml_error_string(xml_get_error_code($this->parser))
4855 $this->
debug($errstr);
4856 $this->
debug(
"XML payload:\n" . $wsdl_string);
4861 xml_parser_free($this->parser);
4862 $this->
debug(
'Parsing WSDL done');
4878 public function start_element($parser, $name, $attrs)
4880 if ($this->status ==
'schema') {
4881 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4882 $this->
appendDebug($this->currentSchema->getDebug());
4883 $this->currentSchema->clearDebug();
4884 } elseif (preg_match(
'/schema$/', $name)) {
4885 $this->
debug(
'Parsing WSDL schema');
4887 $this->status =
'schema';
4889 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4890 $this->
appendDebug($this->currentSchema->getDebug());
4891 $this->currentSchema->clearDebug();
4894 $pos = $this->position++;
4895 $depth = $this->depth++;
4897 $this->depth_array[$depth] = $pos;
4898 $this->message[$pos] = array(
'cdata' =>
'');
4900 if (count($attrs) > 0) {
4902 foreach ($attrs as $k => $v) {
4903 if (preg_match(
'/^xmlns/', $k)) {
4904 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4905 $this->namespaces[$ns_prefix] = $v;
4907 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4909 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4910 $this->XMLSchemaVersion = $v;
4911 $this->namespaces[
'xsi'] = $v .
'-instance';
4916 foreach ($attrs as $k => $v) {
4917 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4918 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4919 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4928 if (preg_match(
'/:/', $name)) {
4930 $prefix = substr($name, 0, strpos($name,
':'));
4932 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4934 $name = substr(strstr($name,
':'), 1);
4938 switch ($this->status) {
4940 if ($name ==
'part') {
4941 if (isset($attrs[
'type'])) {
4942 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4943 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4945 if (isset($attrs[
'element'])) {
4946 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4947 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4954 $this->currentPortOperation = $attrs[
'name'];
4955 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
4956 if (isset($attrs[
'parameterOrder'])) {
4957 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
4960 case 'documentation':
4961 $this->documentation =
true;
4965 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
4966 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name][
'message'] = $m;
4974 if (isset($attrs[
'style'])) {
4975 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
4977 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4980 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
4983 if (isset($attrs[
'soapAction'])) {
4984 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
4986 if (isset($attrs[
'style'])) {
4987 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
4989 if (isset($attrs[
'name'])) {
4990 $this->currentOperation = $attrs[
'name'];
4991 $this->
debug(
"current binding operation: $this->currentOperation");
4992 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
4993 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
4994 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
4998 $this->opStatus =
'input';
5001 $this->opStatus =
'output';
5004 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
5005 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
5007 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
5015 $this->currentPort = $attrs[
'name'];
5016 $this->
debug(
'current port: ' . $this->currentPort);
5017 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
5021 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
5022 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
5023 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
5024 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
5032 if (isset($attrs[
'location'])) {
5033 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
5034 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]) .
')');
5036 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
5038 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $attrs[
'namespace'];
5040 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - [no location] (' . count($this->
import[$attrs[
'namespace']]) .
')');
5048 $this->status =
'message';
5049 $this->messages[$attrs[
'name']] = array();
5050 $this->currentMessage = $attrs[
'name'];
5053 $this->status =
'portType';
5054 $this->portTypes[$attrs[
'name']] = array();
5055 $this->currentPortType = $attrs[
'name'];
5058 if (isset($attrs[
'name'])) {
5060 if (strpos($attrs[
'name'],
':')) {
5061 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
5063 $this->currentBinding = $attrs[
'name'];
5065 $this->status =
'binding';
5066 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
5067 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
5071 $this->serviceName = $attrs[
'name'];
5072 $this->status =
'service';
5073 $this->
debug(
'current service: ' . $this->serviceName);
5076 foreach ($attrs as $name => $value) {
5077 $this->wsdl_info[$name] = $value;
5091 public function end_element($parser, $name)
5094 if ( preg_match(
'/schema$/', $name)) {
5096 $this->
appendDebug($this->currentSchema->getDebug());
5097 $this->currentSchema->clearDebug();
5098 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5099 $this->
debug(
'Parsing WSDL schema done');
5101 if ($this->status ==
'schema') {
5102 $this->currentSchema->schemaEndElement($parser, $name);
5108 if ($this->documentation) {
5111 $this->documentation =
false;
5122 public function character_data($parser,
$data)
5124 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5125 if (isset($this->message[$pos][
'cdata'])) {
5126 $this->message[$pos][
'cdata'] .=
$data;
5128 if ($this->documentation) {
5129 $this->documentation .=
$data;
5142 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
5144 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5146 $this->username = $username;
5147 $this->password = $password;
5148 $this->authtype = $authtype;
5149 $this->certRequest = $certRequest;
5152 public function getBindingData($binding)
5154 if (is_array($this->bindings[$binding])) {
5155 return $this->bindings[$binding];
5166 public function getOperations($bindingType =
'soap')
5169 if ($bindingType ==
'soap') {
5170 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5171 } elseif ($bindingType ==
'soap12') {
5172 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5175 foreach ($this->ports as $port => $portData) {
5177 if ($portData[
'bindingType'] == $bindingType) {
5182 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5183 $ops = array_merge($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5198 public function getOperationData($operation, $bindingType =
'soap')
5200 if ($bindingType ==
'soap') {
5201 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5202 } elseif ($bindingType ==
'soap12') {
5203 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5206 foreach ($this->ports as $port => $portData) {
5208 if ($portData[
'bindingType'] == $bindingType) {
5211 foreach (array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5213 if ($operation == $bOperation) {
5214 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5230 public function getOperationDataForSoapAction($soapAction, $bindingType =
'soap')
5232 if ($bindingType ==
'soap') {
5233 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5234 } elseif ($bindingType ==
'soap12') {
5235 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5238 foreach ($this->ports as $port => $portData) {
5240 if ($portData[
'bindingType'] == $bindingType) {
5242 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5243 if ($opData[
'soapAction'] == $soapAction) {
5269 public function getTypeDef($type, $ns)
5271 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5272 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5273 $ns = $this->namespaces[
'tns'];
5274 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5276 if (!isset($this->schemas[$ns])) {
5277 foreach ($this->schemas as $ns0 => $schema0) {
5278 if (strcasecmp($ns, $ns0) == 0) {
5279 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5285 if (isset($this->schemas[$ns])) {
5286 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5287 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5288 $xs = &$this->schemas[$ns][$i];
5289 $t = $xs->getTypeDef($type);
5293 if (!isset($t[
'phpType'])) {
5295 $uqType = substr($t[
'type'], strrpos($t[
'type'],
':') + 1);
5296 $ns = substr($t[
'type'], 0, strrpos($t[
'type'],
':'));
5297 $etype = $this->getTypeDef($uqType, $ns);
5299 $this->
debug(
"found type for [element] $type:");
5301 if (isset($etype[
'phpType'])) {
5302 $t[
'phpType'] = $etype[
'phpType'];
5304 if (isset($etype[
'elements'])) {
5305 $t[
'elements'] = $etype[
'elements'];
5307 if (isset($etype[
'attrs'])) {
5308 $t[
'attrs'] = $etype[
'attrs'];
5316 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5326 public function webDescription()
5328 global $HTTP_SERVER_VARS;
5332 } elseif (isset($HTTP_SERVER_VARS)) {
5333 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5335 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5338 $PHP_SELF = htmlspecialchars($PHP_SELF, ENT_QUOTES | ENT_HTML5,
'UTF-8');
5342 <html><head><title>NuSOAP: ' . $this->serviceName .
'</title> 5343 <style type="text/css"> 5344 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5345 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5346 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5347 ul { margin-top: 10px; margin-left: 20px; } 5348 li { list-style-type: none; margin-top: 10px; color: #000000; } 5350 margin-left: 0px; padding-bottom: 2em; } 5352 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5353 margin-top: 10px; margin-left: 0px; color: #000000; 5354 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5356 font-family: arial; font-size: 26px; color: #ffffff; 5357 background-color: #999999; width: 105%; margin-left: 0px; 5358 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5360 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5361 font-family: arial; overflow: hidden; width: 600; 5362 padding: 20px; font-size: 10px; background-color: #999999; 5363 layer-background-color:#FFFFFF; } 5364 a,a:active { color: charcoal; font-weight: bold; } 5365 a:visited { color: #666666; font-weight: bold; } 5366 a:hover { color: cc3300; font-weight: bold; } 5368 <script language="JavaScript" type="text/javascript"> 5370 // POP-UP CAPTIONS... 5371 function lib_bwcheck(){ //Browsercheck (needed) 5372 this.ver=navigator.appVersion 5373 this.agent=navigator.userAgent 5374 this.dom=document.getElementById?1:0 5375 this.opera5=this.agent.indexOf("Opera 5")>-1 5376 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5377 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5378 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5379 this.ie=this.ie4||this.ie5||this.ie6 5380 this.mac=this.agent.indexOf("Mac")>-1 5381 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5382 this.ns4=(document.layers && !this.dom)?1:0; 5383 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5386 var bw = new lib_bwcheck() 5387 //Makes crossbrowser object. 5388 function makeObj(obj){ 5389 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5390 if(!this.evnt) return false 5391 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5392 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5393 this.writeIt=b_writeIt; 5396 // A unit of measure that will be added when setting the position of a layer. 5397 //var px = bw.ns4||window.opera?"":"px"; 5398 function b_writeIt(text){ 5399 if (bw.ns4){this.wref.write(text);this.wref.close()} 5400 else this.wref.innerHTML = text 5402 //Shows the messages 5404 function popup(divid){ 5405 if(oDesc = new makeObj(divid)){ 5406 oDesc.css.visibility = "visible" 5409 function popout(){ // Hides message 5410 if(oDesc) oDesc.css.visibility = "hidden" 5418 <div class=title>' . $this->serviceName .
'</div> 5420 <p>View the <a href="' . $PHP_SELF .
'?wsdl">WSDL</a> for the service. 5421 Click on an operation name to view it's details.</p> 5423 foreach ($this->getOperations() as $op =>
$data) {
5425 if (isset(
$data[
'endpoint'])) {
5426 $data[
'endpoint'] = htmlspecialchars(
$data[
'endpoint'], ENT_QUOTES | ENT_HTML5,
'UTF-8');
5429 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5431 $b .=
"<div id='$op' class='hidden'> 5432 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5433 foreach (
$data as $donnie => $marie) {
5434 if ($donnie ==
'input' || $donnie ==
'output') {
5435 $b .=
"<font color='white'>" . ucfirst($donnie) .
':</font><br>';
5436 foreach ($marie as $captain => $tenille) {
5437 if ($captain ==
'parts') {
5438 $b .=
" $captain:<br>";
5440 foreach ($tenille as $joanie => $chachi) {
5441 $b .=
" $joanie: $chachi<br>";
5445 $b .=
" $captain: $tenille<br>";
5449 $b .=
"<font color='white'>" . ucfirst($donnie) .
":</font> $marie<br>";
5457 </div></body></html>';
5470 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5471 $xml .=
"\n<definitions";
5472 foreach ($this->namespaces as $k => $v) {
5473 $xml .=
" xmlns:$k=\"$v\"";
5476 if (isset($this->namespaces[
'wsdl'])) {
5477 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5479 if (isset($this->namespaces[
'tns'])) {
5480 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5484 if (
sizeof($this->
import) > 0) {
5485 foreach ($this->
import as $ns => $list) {
5486 foreach ($list as $ii) {
5487 if ($ii[
'location'] !=
'') {
5488 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5490 $xml .=
'<import namespace="' . $ns .
'" />';
5496 if (count($this->schemas) >= 1) {
5497 $xml .=
"\n<types>\n";
5498 foreach ($this->schemas as $ns => $list) {
5499 foreach ($list as $xs) {
5500 $xml .= $xs->serializeSchema();
5506 if (count($this->messages) >= 1) {
5507 foreach ($this->messages as $msgName => $msgParts) {
5508 $xml .=
"\n<message name=\"" . $msgName .
'">';
5509 if (is_array($msgParts)) {
5510 foreach ($msgParts as $partName => $partType) {
5512 if (strpos($partType,
':')) {
5514 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5516 $typePrefix =
'xsd';
5518 foreach ($this->typemap as $ns => $types) {
5519 if (isset($types[$partType])) {
5523 if (!isset($typePrefix)) {
5524 die(
"$partType has no namespace!");
5529 $typeDef = $this->getTypeDef($localPart, $ns);
5530 if (($typeDef[
'typeClass'] ??
'') ==
'element') {
5531 $elementortype =
'element';
5532 if (substr($localPart, -1) ==
'^') {
5533 $localPart = substr($localPart, 0, -1);
5536 $elementortype =
'type';
5538 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5541 $xml .=
'</message>';
5545 if (count($this->bindings) >= 1) {
5548 foreach ($this->bindings as $bindingName => $attrs) {
5549 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5550 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5551 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5552 foreach ($attrs[
'operations'] as $opName => $opParts) {
5553 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5554 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="' . $opParts[
'style'] .
'"/>';
5555 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5556 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5560 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5561 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5562 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5566 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5567 $binding_xml .=
"\n" .
' </operation>';
5568 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5569 if (isset($opParts[
'parameterOrder'])) {
5570 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5572 $portType_xml .=
'>';
5573 if (isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5574 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5576 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5577 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5578 $portType_xml .=
"\n" .
' </operation>';
5580 $portType_xml .=
"\n" .
'</portType>';
5581 $binding_xml .=
"\n" .
'</binding>';
5583 $xml .= $portType_xml . $binding_xml;
5586 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5587 $has_client = isset(
$_GET[
'client_id']);
5588 if (count($this->ports) >= 1) {
5589 foreach ($this->ports as $pName => $attrs) {
5590 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5591 $locations = $attrs[
'location'];
5592 $locations = is_array($locations) ? $locations : [$locations];
5594 $address = $location . ($debug || $has_client ?
"?" :
"")
5595 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5596 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5597 $xml .=
"\n" .
' <soap:address location="' . $address .
'"/>';
5599 $xml .=
"\n" .
' </port>';
5603 $xml .=
"\n" .
'</service>';
5604 return $xml .
"\n</definitions>";
5616 public function parametersMatchWrapped($type, &$parameters)
5618 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5622 if (strpos($type,
':')) {
5623 $uqType = substr($type, strrpos($type,
':') + 1);
5624 $ns = substr($type, 0, strrpos($type,
':'));
5625 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5628 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5633 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5639 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5640 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5643 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5645 if (substr($uqType, -1) ==
'^') {
5646 $uqType = substr($uqType, 0, -1);
5648 $phpType = $typeDef[
'phpType'];
5649 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5650 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5653 if ($phpType !=
'struct') {
5654 $this->
debug(
"in parametersMatchWrapped: not a struct");
5659 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5663 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5664 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5667 foreach ($typeDef[
'elements'] as $name => $attrs) {
5669 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5670 $parameters[$name] = $parameters[$elements];
5671 unset($parameters[$elements]);
5673 } elseif (isset($parameters[$name])) {
5674 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5677 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5682 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5683 if ($matches == 0) {
5691 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5692 return count($parameters) == 0;
5710 public function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap')
5712 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5715 if ($direction !=
'input' && $direction !=
'output') {
5716 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5717 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5720 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5721 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5722 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5725 $this->
debug(
'in serializeRPCParameters: opData:');
5729 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5730 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5731 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5732 $enc_style = $encodingStyle;
5737 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5738 $parts = &$opData[$direction][
'parts'];
5739 $part_count =
sizeof(
$parts);
5740 $style = $opData[
'style'];
5741 $use = $opData[$direction][
'use'];
5742 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5743 if (is_array($parameters)) {
5745 $parameter_count = count($parameters);
5746 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5748 if ($style ==
'document' && $use ==
'literal' && $part_count == 1 && isset(
$parts[
'parameters'])) {
5749 $this->
debug(
'check whether the caller has wrapped the parameters');
5750 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5751 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5752 if ($this->parametersMatchWrapped(
$parts[
'parameters'], $parameters)) {
5753 $this->
debug(
'wrap the parameters for the caller');
5754 $parameters = array(
'parameters' => $parameters);
5755 $parameter_count = 1;
5759 foreach (
$parts as $name => $type) {
5760 $this->
debug(
"serializing part $name of type $type");
5762 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5763 $encodingStyle = $opData[$direction][
'encodingStyle'];
5764 $enc_style = $encodingStyle;
5770 if ($parametersArrayType ==
'arraySimple') {
5771 $p = array_shift($parameters);
5772 $this->
debug(
'calling serializeType w/indexed param');
5773 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5774 } elseif (isset($parameters[$name])) {
5775 $this->
debug(
'calling serializeType w/named param');
5776 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5779 $this->
debug(
'calling serializeType w/null param');
5780 $xml .= $this->serializeType($name, $type,
null, $use, $enc_style);
5784 $this->
debug(
'no parameters passed.');
5787 $this->
debug(
"serializeRPCParameters returning: $xml");
5805 public function serializeParameters($operation, $direction, $parameters)
5807 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5810 if ($direction !=
'input' && $direction !=
'output') {
5811 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5812 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5815 if (!$opData = $this->getOperationData($operation)) {
5816 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5817 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5820 $this->
debug(
'opData:');
5824 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5825 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5826 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5827 $enc_style = $encodingStyle;
5832 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5833 $use = $opData[$direction][
'use'];
5834 $this->
debug(
"use=$use");
5835 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5836 if (is_array($parameters)) {
5838 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5839 foreach ($opData[$direction][
'parts'] as $name => $type) {
5840 $this->
debug(
'serializing part "' . $name .
'" of type "' . $type .
'"');
5842 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5843 $encodingStyle = $opData[$direction][
'encodingStyle'];
5844 $enc_style = $encodingStyle;
5850 if ($parametersArrayType ==
'arraySimple') {
5851 $p = array_shift($parameters);
5852 $this->
debug(
'calling serializeType w/indexed param');
5853 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5854 } elseif (isset($parameters[$name])) {
5855 $this->
debug(
'calling serializeType w/named param');
5856 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5859 $this->
debug(
'calling serializeType w/null param');
5860 $xml .= $this->serializeType($name, $type,
null, $use, $enc_style);
5864 $this->
debug(
'no parameters passed.');
5867 $this->
debug(
"serializeParameters returning: $xml");
5883 public function serializeType($name, $type, $value, $use =
'encoded', $encodingStyle =
false, $unqualified =
false)
5885 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5887 if ($use ==
'encoded' && $encodingStyle) {
5888 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5892 if (is_object($value) && get_class($value) ==
'soapval') {
5893 if ($value->type_ns) {
5894 $type = $value->type_ns .
':' . $value->type;
5896 $this->
debug(
"in serializeType: soapval overrides type to $type");
5897 } elseif ($value->type) {
5898 $type = $value->type;
5900 $this->
debug(
"in serializeType: soapval overrides type to $type");
5903 $this->
debug(
"in serializeType: soapval does not override type");
5905 $attrs = $value->attributes;
5906 $value = $value->value;
5907 $this->
debug(
"in serializeType: soapval overrides value to $value");
5909 if (!is_array($value)) {
5910 $value[
'!'] = $value;
5912 foreach ($attrs as $n => $v) {
5913 $value[
'!' . $n] = $v;
5915 $this->
debug(
"in serializeType: soapval provides attributes");
5922 if (strpos($type,
':')) {
5923 $uqType = substr($type, strrpos($type,
':') + 1);
5924 $ns = substr($type, 0, strrpos($type,
':'));
5925 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5928 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5931 if ($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/') {
5932 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5933 if ($unqualified && $use ==
'literal') {
5934 $elementNS =
" xmlns=\"\"";
5938 if (is_null($value)) {
5939 if ($use ==
'literal') {
5941 $xml =
"<$name$elementNS/>";
5944 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5946 $this->
debug(
"in serializeType: returning: $xml");
5949 if ($uqType ==
'Array') {
5951 return $this->
serialize_val($value, $name,
false,
false,
false,
false, $use);
5953 if ($uqType ==
'boolean') {
5954 if ((is_string($value) && $value ==
'false') || (! $value)) {
5960 if ($uqType ==
'string' && gettype($value) ==
'string') {
5963 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5964 $value = sprintf(
"%.0lf", $value);
5969 if (!$this->getTypeDef($uqType, $ns)) {
5970 if ($use ==
'literal') {
5972 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
5974 $xml =
"<$name$elementNS>$value</$name>";
5977 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
5979 $this->
debug(
"in serializeType: returning: $xml");
5982 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5983 } elseif ($ns ==
'http://xml.apache.org/xml-soap') {
5984 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
5985 if ($uqType ==
'Map') {
5988 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
5989 $tt_prefix =
'ns' . rand(1000, 9999);
5990 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
5995 foreach ($value as $k => $v) {
5996 $this->
debug(
"serializing map element: key $k, value $v");
5997 $contents .=
'<item>';
5998 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false, $use);
5999 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false, $use);
6000 $contents .=
'</item>';
6002 if ($use ==
'literal') {
6004 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
6006 $xml =
"<$name>$contents</$name>";
6009 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
6011 $this->
debug(
"in serializeType: returning: $xml");
6014 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
6019 $this->
debug(
"in serializeType: No namespace for type $type");
6023 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
6024 $this->
setError(
"$type ($uqType) is not a supported type.");
6025 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
6028 $this->
debug(
"in serializeType: found typeDef");
6030 if (substr($uqType, -1) ==
'^') {
6031 $uqType = substr($uqType, 0, -1);
6034 $phpType = $typeDef[
'phpType'];
6035 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
''));
6037 if ($phpType ==
'struct') {
6038 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
6039 $elementName = $uqType;
6040 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6041 $elementNS =
" xmlns=\"$ns\"";
6043 $elementNS =
" xmlns=\"\"";
6046 $elementName = $name;
6048 $elementNS =
" xmlns=\"\"";
6053 if (is_null($value)) {
6054 if ($use ==
'literal') {
6056 $xml =
"<$elementName$elementNS/>";
6058 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
6060 $this->
debug(
"in serializeType: returning: $xml");
6063 if (is_object($value)) {
6064 $value = get_object_vars($value);
6066 if (is_array($value)) {
6067 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6068 if ($use ==
'literal') {
6070 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
6072 $xml =
"<$elementName$elementNS$elementAttrs>";
6075 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
6078 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6079 $xml .=
"</$elementName>";
6081 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
6082 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
6085 } elseif ($phpType ==
'array') {
6086 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6087 $elementNS =
" xmlns=\"$ns\"";
6090 $elementNS =
" xmlns=\"\"";
6095 if (is_null($value)) {
6096 if ($use ==
'literal') {
6098 $xml =
"<$name$elementNS/>";
6100 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6107 $this->
getLocalPart($typeDef[
'arrayType']) .
"[0]\"/>";
6109 $this->
debug(
"in serializeType: returning: $xml");
6112 if (isset($typeDef[
'multidimensional'])) {
6114 foreach ($value as $v) {
6115 $cols =
',' .
sizeof($v);
6116 $nv = array_merge($nv, $v);
6122 if (is_array($value) &&
sizeof($value) >= 1) {
6123 $rows =
sizeof($value);
6125 foreach ($value as $k => $v) {
6126 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6128 if (!in_array($typeDef[
'arrayType'], $this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6129 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6131 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'],
null, $this->XMLSchemaVersion,
false, $use);
6140 if ($use ==
'literal') {
6141 $xml =
"<$name$elementNS>" 6145 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/') .
':Array" ' .
6149 .
":" . $this->
getLocalPart($typeDef[
'arrayType']) .
"[$rows$cols]\">" 6153 } elseif ($phpType ==
'scalar') {
6154 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6155 $elementNS =
" xmlns=\"$ns\"";
6158 $elementNS =
" xmlns=\"\"";
6163 if ($use ==
'literal') {
6165 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6167 $xml =
"<$name$elementNS>$value</$name>";
6170 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6173 $this->
debug(
"in serializeType: returning: $xml");
6187 public function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
6190 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6191 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6192 if (is_array($value)) {
6194 } elseif (is_object($value)) {
6195 $xvalue = get_object_vars($value);
6197 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6200 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6201 if (isset($xvalue[
'!' . $aName])) {
6202 $xname =
'!' . $aName;
6203 $this->
debug(
"value provided for attribute $aName with key $xname");
6204 } elseif (isset($xvalue[$aName])) {
6206 $this->
debug(
"value provided for attribute $aName with key $xname");
6207 } elseif (isset($attrs[
'default'])) {
6208 $xname =
'!' . $aName;
6209 $xvalue[$xname] = $attrs[
'default'];
6210 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6213 $this->
debug(
"no value provided for attribute $aName");
6216 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6220 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6222 if (isset($typeDef[
'extensionBase'])) {
6223 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6224 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6228 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6229 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6230 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6232 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6250 public function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use =
'encoded', $encodingStyle =
false)
6253 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6254 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6255 if (is_array($value)) {
6257 } elseif (is_object($value)) {
6258 $xvalue = get_object_vars($value);
6260 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6264 if (count($typeDef[
'elements']) != count($xvalue)) {
6267 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6268 if (!isset($xvalue[$eName])) {
6269 if (isset($attrs[
'default'])) {
6270 $xvalue[$eName] = $attrs[
'default'];
6271 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6275 if (isset($optionals)
6276 && (!isset($xvalue[$eName]))
6277 && ((!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6279 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6280 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6283 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6286 if (isset($xvalue[$eName])) {
6287 $v = $xvalue[$eName];
6291 if (isset($attrs[
'form'])) {
6292 $unqualified = ($attrs[
'form'] ==
'unqualified');
6294 $unqualified =
false;
6296 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6298 foreach ($vv as $k => $v) {
6299 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6301 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6304 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6305 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6309 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6311 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6314 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6315 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6321 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6323 if (isset($typeDef[
'extensionBase'])) {
6324 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6325 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6329 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6330 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6331 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6333 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6353 public function addComplexType($name, $typeClass =
'complexType', $phpType =
'array', $compositor =
'', $restrictionBase =
'', $elements = array(), $attrs = array(), $arrayType =
'')
6355 if (count($elements) > 0) {
6356 $eElements = array();
6357 foreach ($elements as $n =>
$e) {
6360 foreach (
$e as $k => $v) {
6361 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6362 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6365 $eElements[$n] = $ee;
6367 $elements = $eElements;
6370 if (count($attrs) > 0) {
6371 foreach ($attrs as $n =>
$a) {
6373 foreach (
$a as $k => $v) {
6374 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6375 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6383 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6384 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6386 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6387 $this->schemas[$typens][0]->addComplexType($name, $typeClass, $phpType, $compositor, $restrictionBase, $elements, $attrs, $arrayType);
6401 public function addSimpleType($name, $restrictionBase =
'', $typeClass =
'simpleType', $phpType =
'scalar', $enumeration = array())
6403 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6405 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6406 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6416 public function addElement($attrs)
6418 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6419 $this->schemas[$typens][0]->addElement($attrs);
6436 public function addOperation($name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false, $style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
'')
6438 if ($use ==
'encoded' && $encodingStyle ==
'') {
6439 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6442 if ($style ==
'document') {
6443 $elements = array();
6444 foreach ($in as $n => $t) {
6445 $elements[$n] = array(
'name' => $n,
'type' => $t);
6447 $this->addComplexType($name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6448 $this->addElement(array(
'name' => $name,
'type' => $name .
'RequestType'));
6449 $in = array(
'parameters' =>
'tns:' . $name .
'^');
6451 $elements = array();
6452 foreach (
$out as $n => $t) {
6453 $elements[$n] = array(
'name' => $n,
'type' => $t);
6455 $this->addComplexType($name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6456 $this->addElement(array(
'name' => $name .
'Response',
'type' => $name .
'ResponseType',
'form' =>
'qualified'));
6457 $out = array(
'parameters' =>
'tns:' . $name .
'Response' .
'^');
6461 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][$name] =
6464 'binding' => $this->serviceName .
'Binding',
6465 'endpoint' => $this->endpoint,
6466 'soapAction' => $soapaction,
6471 'encodingStyle' => $encodingStyle,
6472 'message' => $name .
'Request',
6477 'encodingStyle' => $encodingStyle,
6478 'message' => $name .
'Response',
6481 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6482 'documentation' => $documentation);
6486 foreach ($in as $pName => $pType) {
6487 if (strpos($pType,
':')) {
6490 $this->messages[$name .
'Request'][$pName] = $pType;
6493 $this->messages[$name .
'Request'] =
'0';
6496 foreach (
$out as $pName => $pType) {
6497 if (strpos($pType,
':')) {
6500 $this->messages[$name .
'Response'][$pName] = $pType;
6503 $this->messages[$name .
'Response'] =
'0';
6523 public $methodNamespace;
6526 public $xml_encoding =
'';
6527 public $method =
'';
6528 public $root_struct =
'';
6529 public $root_struct_name =
'';
6530 public $root_struct_namespace =
'';
6531 public $root_header =
'';
6532 public $document =
'';
6534 public $status =
'';
6535 public $position = 0;
6537 public $default_namespace =
'';
6540 public $parent =
'';
6541 public $fault =
false;
6542 public $fault_code =
'';
6543 public $fault_str =
'';
6544 public $fault_detail =
'';
6545 public $depth_array = array();
6546 public $debug_flag =
true;
6547 public $soapresponse =
null;
6548 public $soapheader =
null;
6549 public $responseHeaders =
'';
6550 public $body_position = 0;
6553 public $ids = array();
6555 public $multirefs = array();
6557 public $decode_utf8 =
true;
6568 public function __construct($xml, $encoding =
'UTF-8', $method =
'', $decode_utf8 =
true)
6572 $this->xml_encoding = $encoding;
6573 $this->method = $method;
6574 $this->decode_utf8 = $decode_utf8;
6579 $pos_xml = strpos($xml,
'<?xml');
6580 if ($pos_xml !==
false) {
6581 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6582 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6583 $xml_encoding =
$res[1];
6584 if (strtoupper($xml_encoding) != $encoding) {
6585 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6587 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6593 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6596 $this->
debug(
'No encoding specified in XML declaration');
6599 $this->
debug(
'No XML declaration');
6601 $this->
debug(
'Entering nusoap_parser(), length=' . strlen($xml) .
', encoding=' . $encoding);
6603 $this->parser = xml_parser_create($this->xml_encoding);
6606 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6607 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6610 xml_set_element_handler($this->parser, $this->start_element(...), $this->end_element(...));
6611 xml_set_character_data_handler($this->parser, $this->character_data(...));
6614 if (!xml_parse($this->parser, $xml,
true)) {
6617 'XML error parsing SOAP payload on line %d: %s',
6618 xml_get_current_line_number($this->parser),
6619 xml_error_string(xml_get_error_code($this->parser))
6622 $this->
debug(
"XML payload:\n" . $xml);
6625 $this->
debug(
'parsed successfully, found root struct: ' . $this->root_struct .
' of name ' . $this->root_struct_name);
6627 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6629 if ($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])) {
6630 $this->soapheader = $this->message[$this->root_header][
'result'];
6633 if (
sizeof($this->multirefs) > 0) {
6634 foreach ($this->multirefs as
$id => $hrefs) {
6635 $this->
debug(
'resolving multirefs for id: ' .
$id);
6636 $idVal = $this->buildVal($this->ids[
$id]);
6637 if (is_array($idVal) && isset($idVal[
'!id'])) {
6638 unset($idVal[
'!id']);
6640 foreach ($hrefs as $refPos => $ref) {
6641 $this->
debug(
'resolving href at pos ' . $refPos);
6642 $this->multirefs[
$id][$refPos] = $idVal;
6647 xml_parser_free($this->parser);
6649 $this->
debug(
'xml was empty, didn\'t parse!');
6650 $this->
setError(
'xml was empty, didn\'t parse!');
6662 public function start_element($parser, $name, $attrs)
6666 $pos = $this->position++;
6668 $this->message[$pos] = array(
'pos' => $pos,
'children' =>
'',
'cdata' =>
'');
6671 $this->message[$pos][
'depth'] = $this->depth++;
6675 $this->message[$this->parent][
'children'] .=
'|' . $pos;
6678 $this->message[$pos][
'parent'] = $this->parent;
6680 $this->parent = $pos;
6682 $this->depth_array[$this->depth] = $pos;
6684 if (strpos($name,
':')) {
6686 $prefix = substr($name, 0, strpos($name,
':'));
6688 $name = substr(strstr($name,
':'), 1);
6691 if ($name ==
'Envelope') {
6692 $this->status =
'envelope';
6693 } elseif ($name ==
'Header' && $this->status =
'envelope') {
6694 $this->root_header = $pos;
6695 $this->status =
'header';
6696 } elseif ($name ==
'Body' && $this->status =
'envelope') {
6697 $this->status =
'body';
6698 $this->body_position = $pos;
6700 } elseif ($this->status ==
'body' && $pos == ($this->body_position + 1)) {
6701 $this->status =
'method';
6702 $this->root_struct_name = $name;
6703 $this->root_struct = $pos;
6704 $this->message[$pos][
'type'] =
'struct';
6705 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6708 $this->message[$pos][
'status'] = $this->status;
6710 $this->message[$pos][
'name'] = htmlspecialchars($name);
6712 $this->message[$pos][
'attrs'] = $attrs;
6716 foreach ($attrs as $key => $value) {
6720 if ($key_prefix ==
'xmlns') {
6721 if (preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/', $value)) {
6722 $this->XMLSchemaVersion = $value;
6724 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion .
'-instance';
6726 $this->namespaces[$key_localpart] = $value;
6728 if ($name == $this->root_struct_name) {
6729 $this->methodNamespace = $value;
6732 } elseif ($key_localpart ==
'type') {
6733 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6736 $value_prefix = $this->
getPrefix($value);
6738 $this->message[$pos][
'type'] = $value_localpart;
6739 $this->message[$pos][
'typePrefix'] = $value_prefix;
6740 if (isset($this->namespaces[$value_prefix])) {
6741 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6742 } elseif (isset($attrs[
'xmlns:' . $value_prefix])) {
6743 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:' . $value_prefix];
6747 } elseif ($key_localpart ==
'arrayType') {
6748 $this->message[$pos][
'type'] =
'array';
6757 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6758 if (preg_match($expr, $value, $regs)) {
6759 $this->message[$pos][
'typePrefix'] = $regs[1];
6760 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6761 if (isset($this->namespaces[$regs[1]])) {
6762 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6763 } elseif (isset($attrs[
'xmlns:' . $regs[1]])) {
6764 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:' . $regs[1]];
6766 $this->message[$pos][
'arrayType'] = $regs[2];
6767 $this->message[$pos][
'arraySize'] = $regs[3];
6768 $this->message[$pos][
'arrayCols'] = $regs[4];
6771 } elseif ($key_localpart ==
'nil') {
6772 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6774 } elseif ($key !=
'href' && $key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6775 $this->message[$pos][
'xattrs'][
'!' . $key] = $value;
6778 if ($key ==
'xmlns') {
6779 $this->default_namespace = $value;
6783 $this->ids[$value] = $pos;
6786 if ($key_localpart ==
'root' && $value == 1) {
6787 $this->status =
'method';
6788 $this->root_struct_name = $name;
6789 $this->root_struct = $pos;
6790 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6793 $attstr .=
" $key=\"$value\"";
6796 if (isset($prefix)) {
6797 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6798 $this->default_namespace = $this->namespaces[$prefix];
6800 $this->message[$pos][
'namespace'] = $this->default_namespace;
6802 if ($this->status ==
'header') {
6803 if ($this->root_header != $pos) {
6804 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6806 } elseif ($this->root_struct_name !=
'') {
6807 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6818 public function end_element($parser, $name)
6821 $pos = $this->depth_array[$this->depth--];
6824 if (strpos($name,
':')) {
6826 $prefix = substr($name, 0, strpos($name,
':'));
6828 $name = substr(strstr($name,
':'), 1);
6832 if (isset($this->body_position) && $pos > $this->body_position) {
6834 if (isset($this->message[$pos][
'attrs'][
'href'])) {
6836 $id = substr($this->message[$pos][
'attrs'][
'href'], 1);
6838 $this->multirefs[
$id][$pos] =
'placeholder';
6840 $this->message[$pos][
'result'] = & $this->multirefs[
$id][$pos];
6842 } elseif ($this->message[$pos][
'children'] !=
'') {
6844 if (!isset($this->message[$pos][
'result'])) {
6845 $this->message[$pos][
'result'] = $this->buildVal($pos);
6848 } elseif (isset($this->message[$pos][
'xattrs'])) {
6849 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6850 $this->message[$pos][
'xattrs'][
'!'] =
null;
6851 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6852 if (isset($this->message[$pos][
'type'])) {
6853 $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'] :
'');
6855 $parent = $this->message[$pos][
'parent'];
6856 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6857 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6859 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6863 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6867 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6868 $this->message[$pos][
'xattrs'][
'!'] =
null;
6869 } elseif (isset($this->message[$pos][
'type'])) {
6870 $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'] :
'');
6872 $parent = $this->message[$pos][
'parent'];
6873 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6874 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6876 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6894 if ($this->status ==
'header') {
6895 if ($this->root_header != $pos) {
6896 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6898 } elseif ($pos >= $this->root_struct) {
6899 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6902 if ($pos == $this->root_struct) {
6903 $this->status =
'body';
6904 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6905 } elseif ($name ==
'Body') {
6906 $this->status =
'envelope';
6907 } elseif ($name ==
'Header') {
6908 $this->status =
'envelope';
6909 } elseif ($name ==
'Envelope') {
6913 $this->parent = $this->message[$pos][
'parent'];
6923 public function character_data($parser,
$data)
6925 $pos = $this->depth_array[$this->depth];
6926 if ($this->xml_encoding ==
'UTF-8') {
6930 if ($this->decode_utf8) {
6934 $this->message[$pos][
'cdata'] .=
$data;
6936 if ($this->status ==
'header') {
6937 $this->responseHeaders .=
$data;
6939 $this->document .=
$data;
6950 public function get_response()
6952 return $this->soapresponse;
6961 public function get_soapbody()
6963 return $this->soapresponse;
6972 public function get_soapheader()
6974 return $this->soapheader;
6983 public function getHeaders()
6985 return $this->responseHeaders;
6997 public function decodeSimple($value, $type, $typens)
7000 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
7001 return (
string) $value;
7003 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
7004 return (
int) $value;
7006 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
7007 return (
float) $value;
7009 if ($type ==
'boolean') {
7010 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
7013 return (
bool) $value;
7015 if ($type ==
'base64' || $type ==
'base64Binary') {
7016 $this->
debug(
'Decode base64 value');
7017 return base64_decode($value);
7020 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 7021 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 7022 || $type ==
'unsignedInt' 7023 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
7024 return (
int) $value;
7027 if ($type ==
'array') {
7031 return (
string) $value;
7042 public function buildVal($pos)
7044 if (!isset($this->message[$pos][
'type'])) {
7045 $this->message[$pos][
'type'] =
'';
7047 $this->
debug(
'in buildVal() for ' . $this->message[$pos][
'name'] .
"(pos $pos) of type " . $this->message[$pos][
'type']);
7049 if ($this->message[$pos][
'children'] !=
'') {
7050 $this->
debug(
'in buildVal, there are children');
7051 $children = explode(
'|', $this->message[$pos][
'children']);
7052 array_shift($children);
7054 if (isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
'') {
7057 foreach ($children as $child_pos) {
7058 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
7059 $params[
$r][] = $this->message[$child_pos][
'result'];
7061 if (
$c == $this->message[$pos][
'arrayCols']) {
7067 } elseif ($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array') {
7068 $this->
debug(
'in buildVal, adding array ' . $this->message[$pos][
'name']);
7069 foreach ($children as $child_pos) {
7070 $params[] = &$this->message[$child_pos][
'result'];
7073 } elseif ($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7074 $this->
debug(
'in buildVal, Java Map ' . $this->message[$pos][
'name']);
7075 foreach ($children as $child_pos) {
7076 $kv = explode(
"|", $this->message[$child_pos][
'children']);
7077 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
7083 $this->
debug(
'in buildVal, adding Java Vector or generic compound type ' . $this->message[$pos][
'name']);
7084 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7090 foreach ($children as $child_pos) {
7092 $params[] = &$this->message[$child_pos][
'result'];
7094 if (isset(
$params[$this->message[$child_pos][
'name']])) {
7096 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
7097 $params[$this->message[$child_pos][
'name']] = array(
$params[$this->message[$child_pos][
'name']]);
7099 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
7101 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
7106 if (isset($this->message[$pos][
'xattrs'])) {
7107 $this->
debug(
'in buildVal, handling attributes');
7108 foreach ($this->message[$pos][
'xattrs'] as $n => $v) {
7113 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7114 $this->
debug(
'in buildVal, handling simpleContent');
7115 if (isset($this->message[$pos][
'type'])) {
7116 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7118 $parent = $this->message[$pos][
'parent'];
7119 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7120 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7122 $params[
'!'] = $this->message[$pos][
'cdata'];
7127 $this->
debug(
'in buildVal, return:');
7131 $this->
debug(
'in buildVal, no children, building scalar');
7132 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7133 if (isset($this->message[$pos][
'type'])) {
7134 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7135 $this->
debug(
"in buildVal, return: $ret");
7138 $parent = $this->message[$pos][
'parent'];
7139 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7140 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7141 $this->
debug(
"in buildVal, return: $ret");
7144 $ret = $this->message[$pos][
'cdata'];
7145 $this->
debug(
"in buildVal, return: $ret");
7189 public $username =
'';
7190 public $password =
'';
7191 public $authtype =
'';
7192 public $certRequest = array();
7193 public $requestHeaders =
false;
7194 public $responseHeaders =
'';
7195 public $responseHeader =
null;
7196 public $document =
'';
7198 public $forceEndpoint =
'';
7199 public $proxyhost =
'';
7200 public $proxyport =
'';
7201 public $proxyusername =
'';
7202 public $proxypassword =
'';
7203 public $xml_encoding =
'';
7204 public $http_encoding =
false;
7205 public $timeout = 0;
7206 public $response_timeout = 30;
7207 public $endpointType =
'';
7208 public $persistentConnection =
false;
7209 public $defaultRpcParams =
false;
7210 public $request =
'';
7213 public $cookies = array();
7214 public $decode_utf8 =
true;
7215 public $operations = array();
7216 public $curl_options = array();
7217 public $bindingType =
'';
7218 public $use_curl =
false;
7258 public function __construct($endpoint, $wsdl =
false, $proxyhost =
false, $proxyport =
false, $proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30)
7261 $this->endpoint = $endpoint;
7262 $this->proxyhost = $proxyhost;
7263 $this->proxyport = $proxyport;
7264 $this->proxyusername = $proxyusername;
7265 $this->proxypassword = $proxypassword;
7266 $this->timeout = $timeout;
7267 $this->response_timeout = $response_timeout;
7269 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7274 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7275 $this->
wsdl = $endpoint;
7276 $this->endpoint = $this->
wsdl->wsdl;
7277 $this->wsdlFile = $this->endpoint;
7278 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7281 $this->wsdlFile = $this->endpoint;
7283 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7285 $this->endpointType =
'wsdl';
7287 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7288 $this->endpointType =
'soap';
7317 public function call($operation,
$params = array(),
$namespace =
'http://tempuri.org', $soapAction =
'', $headers =
false, $rpcParams =
null, $style =
'rpc', $use =
'encoded')
7319 $this->operation = $operation;
7320 $this->fault =
false;
7322 $this->request =
'';
7323 $this->response =
'';
7324 $this->responseData =
'';
7325 $this->faultstring =
'';
7326 $this->faultcode =
'';
7327 $this->opData = array();
7329 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7333 $this->requestHeaders = $headers;
7335 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7342 if ($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)) {
7344 $this->opData = $opData;
7345 $this->
debug(
"found operation");
7347 if (isset($opData[
'soapAction'])) {
7348 $soapAction = $opData[
'soapAction'];
7350 if (! $this->forceEndpoint) {
7351 $this->endpoint = $opData[
'endpoint'];
7353 $this->endpoint = $this->forceEndpoint;
7355 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7356 $style = $opData[
'style'];
7357 $use = $opData[
'input'][
'use'];
7360 $nsPrefix =
'ns' . rand(1000, 9999);
7366 $this->
debug(
"serializing param string for WSDL operation $operation");
7368 } elseif (is_array(
$params)) {
7369 $this->
debug(
"serializing param array for WSDL operation $operation");
7372 $this->
debug(
'params must be array or string');
7373 $this->
setError(
'params must be array or string');
7377 if (isset($opData[
'input'][
'encodingStyle'])) {
7378 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7380 $encodingStyle =
'';
7385 $this->
debug(
'got wsdl error: ' . $errstr);
7386 $this->
setError(
'wsdl error: ' . $errstr);
7389 } elseif ($this->endpointType ==
'wsdl') {
7393 $this->
setError(
'operation ' . $operation .
' not present.');
7394 $this->
debug(
"operation '$operation' not present.");
7399 $nsPrefix =
'ns' . rand(1000, 9999);
7403 $this->
debug(
"serializing param string for operation $operation");
7405 } elseif (is_array(
$params)) {
7406 $this->
debug(
"serializing param array for operation $operation");
7407 foreach (
$params as $k => $v) {
7411 $this->
debug(
'params must be array or string');
7412 $this->
setError(
'params must be array or string');
7416 if ($use ==
'encoded') {
7417 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7419 $encodingStyle =
'';
7423 if ($style ==
'rpc') {
7424 if ($use ==
'literal') {
7425 $this->
debug(
"wrapping RPC request with literal method element");
7428 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7430 "</$nsPrefix:$operation>";
7435 $this->
debug(
"wrapping RPC request with encoded method element");
7437 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7439 "</$nsPrefix:$operation>";
7449 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7450 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7452 $return = $this->
send($this->getHTTPBody($soapmsg), $soapAction, $this->timeout, $this->response_timeout);
7454 $this->
debug(
'Error: ' . $errstr);
7457 $this->
return = $return;
7458 $this->
debug(
'sent message successfully and got a(n) ' . gettype($return));
7462 if (is_array($return) && isset($return[
'faultcode'])) {
7463 $this->
debug(
'got fault');
7464 $this->
setError($return[
'faultcode'] .
': ' . $return[
'faultstring']);
7465 $this->fault =
true;
7466 foreach ($return as $k => $v) {
7468 $this->
debug(
"$k = $v<br>");
7471 } elseif ($style ==
'document') {
7477 if (is_array($return)) {
7480 if (
sizeof($return) > 1) {
7484 $return = array_shift($return);
7485 $this->
debug(
'return shifted value: ');
7501 public function checkWSDL()
7505 $this->
debug(
'checkWSDL');
7508 $this->
debug(
'got wsdl error: ' . $errstr);
7509 $this->
setError(
'wsdl error: ' . $errstr);
7511 $this->bindingType =
'soap';
7512 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7514 $this->bindingType =
'soap12';
7515 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7516 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7518 $this->
debug(
'getOperations returned false');
7519 $this->
setError(
'no operations defined in the WSDL document!');
7528 public function loadWSDL()
7530 $this->
debug(
'instantiating wsdl class with doc: ' . $this->wsdlFile);
7531 $this->
wsdl =
new wsdl(
'', $this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword, $this->timeout, $this->response_timeout, $this->curl_options, $this->use_curl);
7532 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7544 public function getOperationData($operation)
7546 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7552 if (isset($this->operations[$operation])) {
7553 return $this->operations[$operation];
7555 $this->
debug(
"No data for operation: $operation");
7572 public function send($msg, $soapaction =
'', $timeout = 0, $response_timeout = 30)
7574 $this->checkCookies();
7578 case preg_match(
'/^http/', $this->endpoint):
7579 $this->
debug(
'transporting via HTTP');
7580 if ($this->persistentConnection ==
true && is_object($this->persistentConnection)) {
7581 $http = & $this->persistentConnection;
7584 if ($this->persistentConnection) {
7585 $http->usePersistentConnection();
7588 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7589 $http->setSOAPAction($soapaction);
7590 if ($this->proxyhost && $this->proxyport) {
7591 $http->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
7593 if ($this->authtype !=
'') {
7594 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7596 if ($this->http_encoding !=
'') {
7597 $http->setEncoding($this->http_encoding);
7599 $this->
debug(
'sending message, length=' . strlen($msg));
7600 if (preg_match(
'/^http:/', $this->endpoint)) {
7602 $this->responseData =
$http->send($msg, $timeout, $response_timeout, $this->cookies);
7603 } elseif (preg_match(
'/^https/', $this->endpoint)) {
7610 $this->responseData =
$http->sendHTTPS($msg, $timeout, $response_timeout, $this->cookies);
7612 $this->
setError(
'no http/s in endpoint url');
7614 $this->request =
$http->outgoing_payload;
7615 $this->response =
$http->incoming_payload;
7617 $this->UpdateCookies(
$http->incoming_cookies);
7620 if ($this->persistentConnection) {
7621 $http->clearDebug();
7622 if (!is_object($this->persistentConnection)) {
7623 $this->persistentConnection =
$http;
7627 if ($err =
$http->getError()) {
7628 $this->
setError(
'HTTP Error: ' . $err);
7633 $this->
debug(
'got response, length=' . strlen($this->responseData) .
' type=' .
$http->incoming_headers[
'content-type']);
7634 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7638 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7652 public function parseResponse($headers,
$data)
7654 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7656 if (!strstr($headers[
'content-type'],
'text/xml')) {
7657 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7660 if (strpos($headers[
'content-type'],
'=')) {
7661 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7662 $this->
debug(
'Got response encoding: ' . $enc);
7663 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
7664 $this->xml_encoding = strtoupper($enc);
7666 $this->xml_encoding =
'US-ASCII';
7670 $this->xml_encoding =
'ISO-8859-1';
7672 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7673 $parser =
new nusoap_parser(
$data, $this->xml_encoding, $this->operation, $this->decode_utf8);
7677 if ($errstr = $parser->getError()) {
7684 $this->responseHeaders = $parser->getHeaders();
7686 $this->responseHeader = $parser->get_soapheader();
7688 $return = $parser->get_soapbody();
7690 $this->document = $parser->document;
7705 public function setCurlOption($option, $value)
7707 $this->
debug(
"setCurlOption option=$option, value=");
7709 $this->curl_options[$option] = $value;
7718 public function setEndpoint($endpoint)
7720 $this->
debug(
"setEndpoint(\"$endpoint\")");
7721 $this->forceEndpoint = $endpoint;
7730 public function setHeaders($headers)
7732 $this->
debug(
"setHeaders headers=");
7734 $this->requestHeaders = $headers;
7743 public function getHeaders()
7745 return $this->responseHeaders;
7754 public function getHeader()
7756 return $this->responseHeader;
7768 public function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'')
7770 $this->proxyhost = $proxyhost;
7771 $this->proxyport = $proxyport;
7772 $this->proxyusername = $proxyusername;
7773 $this->proxypassword = $proxypassword;
7785 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
7787 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7789 $this->username = $username;
7790 $this->password = $password;
7791 $this->authtype = $authtype;
7792 $this->certRequest = $certRequest;
7801 public function setHTTPEncoding($enc =
'gzip, deflate')
7803 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7804 $this->http_encoding = $enc;
7813 public function setUseCURL($use)
7815 $this->
debug(
"setUseCURL($use)");
7816 $this->use_curl = $use;
7824 public function useHTTPPersistentConnection()
7826 $this->
debug(
"useHTTPPersistentConnection");
7827 $this->persistentConnection =
true;
7841 public function getDefaultRpcParams()
7843 return $this->defaultRpcParams;
7857 public function setDefaultRpcParams($rpcParams)
7859 $this->defaultRpcParams = $rpcParams;
7869 public function getProxy()
7872 $evalStr = $this->_getProxyClassCode(
$r);
7875 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7881 eval(
"\$proxy = new nusoap_proxy_$r('');");
7883 $proxy->endpointType =
'wsdl';
7884 $proxy->wsdlFile = $this->wsdlFile;
7885 $proxy->wsdl = $this->wsdl;
7886 $proxy->operations = $this->operations;
7887 $proxy->defaultRpcParams = $this->defaultRpcParams;
7890 $proxy->username = $this->username;
7891 $proxy->password = $this->password;
7892 $proxy->authtype = $this->authtype;
7893 $proxy->certRequest = $this->certRequest;
7894 $proxy->requestHeaders = $this->requestHeaders;
7895 $proxy->endpoint = $this->endpoint;
7896 $proxy->forceEndpoint = $this->forceEndpoint;
7897 $proxy->proxyhost = $this->proxyhost;
7898 $proxy->proxyport = $this->proxyport;
7899 $proxy->proxyusername = $this->proxyusername;
7900 $proxy->proxypassword = $this->proxypassword;
7901 $proxy->http_encoding = $this->http_encoding;
7902 $proxy->timeout = $this->timeout;
7903 $proxy->response_timeout = $this->response_timeout;
7904 $proxy->persistentConnection = &$this->persistentConnection;
7905 $proxy->decode_utf8 = $this->decode_utf8;
7906 $proxy->curl_options = $this->curl_options;
7907 $proxy->bindingType = $this->bindingType;
7908 $proxy->use_curl = $this->use_curl;
7918 public function _getProxyClassCode(
$r)
7920 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7922 if ($this->endpointType !=
'wsdl') {
7923 $evalStr =
'A proxy can only be created for a WSDL client';
7925 $evalStr =
"echo \"$evalStr\";";
7928 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7931 return "echo \"" . $this->
getError() .
"\";";
7935 foreach ($this->operations as $operation => $opData) {
7936 if ($operation !=
'') {
7938 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7940 $paramArrayStr =
'';
7941 $paramCommentStr =
'';
7942 foreach ($opData[
'input'][
'parts'] as $name => $type) {
7943 $paramStr .=
"\$$name, ";
7944 $paramArrayStr .=
"'$name' => \$$name, ";
7945 $paramCommentStr .=
"$type \$$name, ";
7947 $paramStr = substr($paramStr, 0, strlen($paramStr) - 2);
7948 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr) - 2);
7949 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr) - 2);
7952 $paramArrayStr =
'';
7953 $paramCommentStr =
'void';
7955 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7956 $evalStr .=
"// $paramCommentStr 7957 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7958 \$params = array($paramArrayStr); 7959 return \$this->call('$operation', \$params, '" . $opData[
'namespace'] .
"', '" . (isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'') .
"'); 7963 unset($paramCommentStr);
7966 $evalStr =
'class nusoap_proxy_' .
$r .
' extends nusoap_client { 7978 public function getProxyClassCode()
7981 return $this->_getProxyClassCode(
$r);
7991 public function getHTTPBody($soapmsg)
8004 public function getHTTPContentType()
8018 public function getHTTPContentTypeCharset()
8029 public function decodeUTF8($bool)
8031 $this->decode_utf8 = $bool;
8043 public function setCookie($name, $value)
8045 if (strlen($name) == 0) {
8048 $this->cookies[] = array(
'name' => $name,
'value' => $value);
8058 public function getCookies()
8060 return $this->cookies;
8069 public function checkCookies()
8071 if (
sizeof($this->cookies) == 0) {
8074 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
8075 $curr_cookies = $this->cookies;
8076 $this->cookies = array();
8077 foreach ($curr_cookies as $cookie) {
8078 if (! is_array($cookie)) {
8079 $this->
debug(
'Remove cookie that is not an array');
8082 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
8083 if (strtotime($cookie[
'expires']) > time()) {
8084 $this->cookies[] = $cookie;
8086 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
8089 $this->cookies[] = $cookie;
8092 $this->
debug(
'checkCookie: ' .
sizeof($this->cookies) .
' cookies left in array');
8103 public function UpdateCookies($cookies)
8105 if (
sizeof($this->cookies) == 0) {
8107 if (
sizeof($cookies) > 0) {
8108 $this->
debug(
'Setting new cookie(s)');
8109 $this->cookies = $cookies;
8113 if (
sizeof($cookies) == 0) {
8118 foreach ($cookies as $newCookie) {
8119 if (!is_array($newCookie)) {
8122 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
8125 $newName = $newCookie[
'name'];
8128 for ($i = 0; $i < count($this->cookies); $i++) {
8129 $cookie = $this->cookies[$i];
8130 if (!is_array($cookie)) {
8133 if (!isset($cookie[
'name'])) {
8136 if ($newName != $cookie[
'name']) {
8139 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
8140 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
8141 if ($newDomain != $domain) {
8144 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
8145 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
8146 if ($newPath !=
$path) {
8149 $this->cookies[$i] = $newCookie;
8151 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8155 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8156 $this->cookies[] = $newCookie;
8163 if (!extension_loaded(
'soap')) {
if($err=$client->getError()) $namespace
appendDebug($string)
adds debug data to the instance debug string without formatting
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
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
if(empty($path)) $serviceName
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.
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
if(count($parts) !=3) $payload
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed ...
serialize($debug=0)
serialize the parsed wsdl
For creating serializable abstractions of native PHP types.
catch(\Exception $e) $req
getError()
returns error string if present
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
debug($string)
adds debug data to the instance debug string with formatting
serializeRPCParameters($operation, $direction, $parameters, $bindingType='soap')
serialize PHP values according to a WSDL message definition contrary to the method name...
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
expandQname($qname)
expands (changes prefix to namespace) 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.
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded', $encodingStyle='http://schemas.xmlsoap.org/soap/encoding/')
serializes a message
varDump($data)
Returns a string with the output of var_dump.
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
serialize()
serialize a fault
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
__construct(Container $dic, ilPlugin $plugin)
expandEntities($val)
expands entities, e.g.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace
nusoap_parser class parses SOAP XML messages into native PHP values
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='', $encodingStyle='')
register an operation with the server
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
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded', $soapval=false)
serializes PHP values in accordance w/ section 5.
catch(ilCmiXapiException $e) send($response)