For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
1012 $start = gettimeofday();
1015 $stop = gettimeofday();
1016 $timePassed = 1000000 * ($stop[
'sec'] - $start[
'sec'])
1017 + $stop[
'usec'] - $start[
'usec'];
1018 }
while ($timePassed < $usec);
1086 foreach ($this->namespaces as $k => $v) {
1087 $ns_string .=
"\n xmlns:$k=\"$v\"";
1090 '<?xml version="1.0" encoding="' . $this->soap_defencoding .
'"?>' .
1091 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string .
">\n" .
1093 '<SOAP-ENV:Fault>' .
1098 '</SOAP-ENV:Fault>' .
1099 '</SOAP-ENV:Body>' .
1100 '</SOAP-ENV:Envelope>';
1128 public $schema =
'';
1131 public $enclosingNamespaces;
1133 public $schemaInfo = array();
1134 public $schemaTargetNamespace =
'';
1136 public $attributes = array();
1137 public $complexTypes = array();
1138 public $complexTypeStack = array();
1139 public $currentComplexType = null;
1140 public $elements = array();
1141 public $elementStack = array();
1142 public $currentElement = null;
1143 public $simpleTypes = array();
1144 public $simpleTypeStack = array();
1145 public $currentSimpleType = null;
1147 public $imports = array();
1150 public $position = 0;
1152 public $depth_array = array();
1153 public $message = array();
1154 public $defaultNamespace = array();
1167 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
1169 $this->schema = $schema;
1174 $this->namespaces = array_merge($this->namespaces,
$namespaces);
1177 if ($schema !=
'') {
1178 $this->
debug(
'initial schema file: ' . $schema);
1179 $this->parseFile($schema,
'schema');
1184 $this->
debug(
'initial xml file: ' . $xml);
1185 $this->parseFile($xml,
'xml');
1197 public function parseFile($xml, $type)
1201 $xmlStr = @join(
"", @file($xml));
1202 if ($xmlStr ==
"") {
1203 $msg =
'Error reading XML from ' . $xml;
1208 $this->
debug(
"parsing $xml");
1209 $this->parseString($xmlStr, $type);
1210 $this->
debug(
"done parsing $xml");
1224 public function parseString($xml, $type)
1229 $this->parser = xml_parser_create();
1231 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1234 xml_set_object($this->parser, $this);
1237 if ($type ==
"schema") {
1238 xml_set_element_handler($this->parser,
'schemaStartElement',
'schemaEndElement');
1239 xml_set_character_data_handler($this->parser,
'schemaCharacterData');
1240 } elseif ($type ==
"xml") {
1241 xml_set_element_handler($this->parser,
'xmlStartElement',
'xmlEndElement');
1242 xml_set_character_data_handler($this->parser,
'xmlCharacterData');
1246 if (!xml_parse($this->parser, $xml,
true)) {
1249 'XML error parsing XML schema on line %d: %s',
1250 xml_get_current_line_number($this->parser),
1251 xml_error_string(xml_get_error_code($this->parser))
1253 $this->
debug($errstr);
1254 $this->
debug(
"XML payload:\n" . $xml);
1258 xml_parser_free($this->parser);
1260 $this->
debug(
'no xml passed to parseString()!!');
1261 $this->
setError(
'no xml passed to parseString()!!');
1272 public function CreateTypeName($ename)
1275 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1276 $scope .= $this->complexTypeStack[$i] .
'_';
1278 return $scope . $ename .
'_ContainedType';
1289 public function schemaStartElement($parser, $name, $attrs)
1293 $pos = $this->position++;
1294 $depth = $this->depth++;
1296 $this->depth_array[$depth] = $pos;
1297 $this->message[$pos] = array(
'cdata' =>
'');
1299 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1301 $this->defaultNamespace[$pos] =
false;
1305 if ($prefix = $this->
getPrefix($name)) {
1313 if (count($attrs) > 0) {
1314 foreach ($attrs as $k => $v) {
1316 if (preg_match(
'/^xmlns/', $k)) {
1319 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
1321 $this->namespaces[$ns_prefix] = $v;
1323 $this->defaultNamespace[$pos] = $v;
1325 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $v;
1328 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
1329 $this->XMLSchemaVersion = $v;
1330 $this->namespaces[
'xsi'] = $v .
'-instance';
1334 foreach ($attrs as $k => $v) {
1336 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1337 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1351 $this->complexTypes[$this->currentComplexType][
'compositor'] = $name;
1358 $this->xdebug(
"parsing attribute:");
1360 if (!isset($attrs[
'form'])) {
1361 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1363 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1364 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1365 if (!strpos($v,
':')) {
1367 if ($this->defaultNamespace[$pos]) {
1369 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1373 if (isset($attrs[
'name'])) {
1374 $this->attributes[$attrs[
'name']] = $attrs;
1375 $aname = $attrs[
'name'];
1376 } elseif (isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
1377 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1378 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1382 } elseif (isset($attrs[
'ref'])) {
1383 $aname = $attrs[
'ref'];
1384 $this->attributes[$attrs[
'ref']] = $attrs;
1387 if ($this->currentComplexType) {
1388 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1391 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType') {
1392 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1394 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1395 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1399 if (strpos($v,
'[,]')) {
1400 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1402 $v = substr($v, 0, strpos($v,
'['));
1403 if (!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
1404 $v = $this->XMLSchemaVersion .
':' . $v;
1406 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1409 case 'complexContent':
1412 array_push($this->complexTypeStack, $this->currentComplexType);
1413 if (isset($attrs[
'name'])) {
1416 $this->xdebug(
'processing named complexType ' . $attrs[
'name']);
1418 $this->currentComplexType = $attrs[
'name'];
1419 $this->complexTypes[$this->currentComplexType] = $attrs;
1420 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1428 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1429 $this->xdebug(
'complexType is unusual array');
1430 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1432 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1435 $name = $this->CreateTypeName($this->currentElement);
1436 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' . $name);
1437 $this->currentComplexType = $name;
1439 $this->complexTypes[$this->currentComplexType] = $attrs;
1440 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1448 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1449 $this->xdebug(
'complexType is unusual array');
1450 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1452 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1457 array_push($this->elementStack, $this->currentElement);
1458 if (!isset($attrs[
'form'])) {
1459 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1461 if (isset($attrs[
'type'])) {
1462 $this->xdebug(
"processing typed element " . $attrs[
'name'] .
" of type " . $attrs[
'type']);
1463 if (! $this->
getPrefix($attrs[
'type'])) {
1464 if ($this->defaultNamespace[$pos]) {
1465 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1466 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1476 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1477 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1478 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1480 $this->currentElement = $attrs[
'name'];
1481 $ename = $attrs[
'name'];
1482 } elseif (isset($attrs[
'ref'])) {
1483 $this->xdebug(
"processing element as ref to " . $attrs[
'ref']);
1484 $this->currentElement =
"ref to " . $attrs[
'ref'];
1487 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1488 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' . $type);
1489 $this->currentElement = $attrs[
'name'];
1490 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $type;
1491 $ename = $attrs[
'name'];
1493 if (isset($ename) && $this->currentComplexType) {
1494 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1495 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1496 } elseif (!isset($attrs[
'ref'])) {
1497 $this->xdebug(
"add element $ename to elements array");
1498 $this->elements[ $attrs[
'name'] ] = $attrs;
1499 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1503 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1504 if ($this->currentSimpleType) {
1505 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1506 } elseif ($this->currentComplexType) {
1507 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1511 $this->xdebug(
'extension ' . $attrs[
'base']);
1512 if ($this->currentComplexType) {
1513 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1517 if (isset($attrs[
'schemaLocation'])) {
1519 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1522 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1524 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
1531 $this->xdebug(
'restriction ' . $attrs[
'base']);
1532 if ($this->currentSimpleType) {
1533 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1534 } elseif ($this->currentComplexType) {
1535 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1536 if (strstr($attrs[
'base'],
':') ==
':Array') {
1537 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1542 $this->schemaInfo = $attrs;
1544 if (isset($attrs[
'targetNamespace'])) {
1545 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1547 if (!isset($attrs[
'elementFormDefault'])) {
1548 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1550 if (!isset($attrs[
'attributeFormDefault'])) {
1551 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1554 case 'simpleContent':
1557 array_push($this->simpleTypeStack, $this->currentSimpleType);
1558 if (isset($attrs[
'name'])) {
1559 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1560 $this->currentSimpleType = $attrs[
'name'];
1561 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1562 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1563 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1565 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1566 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' . $name);
1567 $this->currentSimpleType = $name;
1569 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1570 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1587 public function schemaEndElement($parser, $name)
1592 if (isset($this->depth_array[$this->depth])) {
1593 $pos = $this->depth_array[$this->depth];
1596 if ($prefix = $this->
getPrefix($name)) {
1603 if ($name ==
'complexType') {
1604 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1605 $this->currentComplexType = array_pop($this->complexTypeStack);
1608 if ($name ==
'element') {
1609 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1610 $this->currentElement = array_pop($this->elementStack);
1612 if ($name ==
'simpleType') {
1613 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1614 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1625 public function schemaCharacterData($parser,
$data)
1627 $pos = $this->depth_array[$this->depth - 1];
1628 $this->message[$pos][
'cdata'] .=
$data;
1636 public function serializeSchema()
1641 if (
sizeof($this->imports) > 0) {
1642 foreach ($this->imports as $ns => $list) {
1643 foreach ($list as $ii) {
1644 if ($ii[
'location'] !=
'') {
1645 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1647 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1653 foreach ($this->complexTypes as $typeName => $attrs) {
1656 if (isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)) {
1657 foreach ($attrs[
'elements'] as $element => $eParts) {
1658 if (isset($eParts[
'ref'])) {
1659 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1661 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1662 foreach ($eParts as $aName => $aValue) {
1664 if ($aName !=
'name' && $aName !=
'type') {
1665 $contentStr .=
" $aName=\"$aValue\"";
1668 $contentStr .=
"/>\n";
1672 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1673 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n" . $contentStr .
" </$schemaPrefix:$attrs[compositor]>\n";
1677 if (isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)) {
1678 foreach ($attrs[
'attrs'] as $attr => $aParts) {
1679 $contentStr .=
" <$schemaPrefix:attribute";
1680 foreach ($aParts as
$a => $v) {
1681 if (
$a ==
'ref' ||
$a ==
'type') {
1682 $contentStr .=
" $a=\"" . $this->contractQName($v) .
'"';
1683 } elseif (
$a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1684 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1685 $contentStr .=
' wsdl:arrayType="' . $this->contractQName($v) .
'"';
1687 $contentStr .=
" $a=\"$v\"";
1690 $contentStr .=
"/>\n";
1694 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
'') {
1695 $contentStr =
" <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs[
'restrictionBase']) .
"\">\n" . $contentStr .
" </$schemaPrefix:restriction>\n";
1697 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)) {
1698 $contentStr =
" <$schemaPrefix:complexContent>\n" . $contentStr .
" </$schemaPrefix:complexContent>\n";
1702 if ($contentStr !=
'') {
1703 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr .
" </$schemaPrefix:complexType>\n";
1705 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1707 $xml .= $contentStr;
1710 if (isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
1711 foreach ($this->simpleTypes as $typeName => $eParts) {
1712 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts[
'type']) .
"\">\n";
1713 if (isset($eParts[
'enumeration'])) {
1714 foreach ($eParts[
'enumeration'] as
$e) {
1715 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1718 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1722 if (isset($this->elements) && count($this->elements) > 0) {
1723 foreach ($this->elements as $element => $eParts) {
1724 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"/>\n";
1728 if (isset($this->attributes) && count($this->attributes) > 0) {
1729 foreach ($this->attributes as $attr => $aParts) {
1730 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts[
'type']) .
"\"\n/>";
1735 foreach ($this->schemaInfo as $k => $v) {
1736 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1737 $attr .=
" $k=\"$v\"";
1740 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1741 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1742 $el .=
" xmlns:$nsp=\"$ns\"";
1744 $xml = $el .
">\n" . $xml .
"</$schemaPrefix:schema>\n";
1754 public function xdebug($string)
1756 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> ' . $string);
1771 public function getPHPType($type, $ns)
1773 if (isset($this->typemap[$ns][$type])) {
1775 return $this->typemap[$ns][$type];
1776 } elseif (isset($this->complexTypes[$type])) {
1778 return $this->complexTypes[$type][
'phpType'];
1805 public function getTypeDef($type)
1808 if (substr($type, -1) ==
'^') {
1810 $type = substr($type, 0, -1);
1815 if ((! $is_element) && isset($this->complexTypes[$type])) {
1816 $this->xdebug(
"in getTypeDef, found complexType $type");
1817 return $this->complexTypes[$type];
1818 } elseif ((! $is_element) && isset($this->simpleTypes[$type])) {
1819 $this->xdebug(
"in getTypeDef, found simpleType $type");
1820 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1823 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1824 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1825 $etype = $this->getTypeDef($uqType);
1827 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1828 $this->xdebug($this->
varDump($etype));
1829 if (isset($etype[
'phpType'])) {
1830 $this->simpleTypes[$type][
'phpType'] = $etype[
'phpType'];
1832 if (isset($etype[
'elements'])) {
1833 $this->simpleTypes[$type][
'elements'] = $etype[
'elements'];
1837 return $this->simpleTypes[$type];
1838 } elseif (isset($this->elements[$type])) {
1839 $this->xdebug(
"in getTypeDef, found element $type");
1840 if (!isset($this->elements[$type][
'phpType'])) {
1842 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1843 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1844 $etype = $this->getTypeDef($uqType);
1846 $this->xdebug(
"in getTypeDef, found type for element $type:");
1847 $this->xdebug($this->
varDump($etype));
1848 if (isset($etype[
'phpType'])) {
1849 $this->elements[$type][
'phpType'] = $etype[
'phpType'];
1851 if (isset($etype[
'elements'])) {
1852 $this->elements[$type][
'elements'] = $etype[
'elements'];
1854 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1855 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1856 $this->elements[$type][
'phpType'] =
'scalar';
1859 return $this->elements[$type];
1860 } elseif (isset($this->attributes[$type])) {
1861 $this->xdebug(
"in getTypeDef, found attribute $type");
1862 return $this->attributes[$type];
1863 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1864 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1865 $typeDef[
'typeClass'] =
'simpleType';
1866 $typeDef[
'phpType'] =
'scalar';
1867 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1870 $this->xdebug(
"in getTypeDef, did not find $type");
1882 public function serializeTypeDef($type)
1885 if ($typeDef = $this->getTypeDef($type)) {
1886 $str .=
'<' . $type;
1887 if (is_array($typeDef[
'attrs'])) {
1888 foreach ($typeDef[
'attrs'] as $attName =>
$data) {
1889 $str .=
" $attName=\"{type = " .
$data[
'type'] .
"}\"";
1892 $str .=
" xmlns=\"" . $this->schema[
'targetNamespace'] .
"\"";
1893 if (count($typeDef[
'elements']) > 0) {
1895 foreach ($typeDef[
'elements'] as $element => $eData) {
1896 $str .= $this->serializeTypeDef($element);
1899 } elseif ($typeDef[
'typeClass'] ==
'element') {
1900 $str .=
"></$type>";
1919 public function typeToForm($name, $type)
1922 if ($typeDef = $this->getTypeDef($type)) {
1924 if ($typeDef[
'phpType'] ==
'struct') {
1925 $buffer .=
'<table>';
1926 foreach ($typeDef[
'elements'] as $child => $childDef) {
1928 <tr><td align='right'>$childDef[name] (type: " . $this->
getLocalPart($childDef[
'type']) .
"):</td> 1929 <td><input type='text' name='parameters[" . $name .
"][$childDef[name]]'></td></tr>";
1931 $buffer .=
'</table>';
1933 } elseif ($typeDef[
'phpType'] ==
'array') {
1934 $buffer .=
'<table>';
1935 for ($i=0;$i < 3; $i++) {
1937 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1938 <td><input type='text' name='parameters[" . $name .
"][]'></td></tr>";
1940 $buffer .=
'</table>';
1943 $buffer .=
"<input type='text' name='parameters[$name]'>";
1946 $buffer .=
"<input type='text' name='parameters[$name]'>";
1992 public function addComplexType($name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
1994 $this->complexTypes[$name] = array(
1996 'typeClass' => $typeClass,
1997 'phpType' => $phpType,
1998 'compositor'=> $compositor,
1999 'restrictionBase' => $restrictionBase,
2000 'elements' => $elements,
2002 'arrayType' => $arrayType
2005 $this->xdebug(
"addComplexType $name:");
2021 public function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
2023 $this->simpleTypes[$name] = array(
2025 'typeClass' => $typeClass,
2026 'phpType' => $phpType,
2027 'type' => $restrictionBase,
2028 'enumeration' => $enumeration
2031 $this->xdebug(
"addSimpleType $name:");
2042 public function addElement($attrs)
2044 if (! $this->
getPrefix($attrs[
'type'])) {
2045 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
2047 $this->elements[ $attrs[
'name'] ] = $attrs;
2048 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
2050 $this->xdebug(
"addElement " . $attrs[
'name']);
2133 public function __construct($name=
'soapval', $type=
false, $value=-1, $element_ns=
false, $type_ns=
false, $attributes=
false)
2136 $this->name = $name;
2137 $this->type = $type;
2138 $this->value = $value;
2139 $this->element_ns = $element_ns;
2140 $this->type_ns = $type_ns;
2141 $this->attributes = $attributes;
2151 public function serialize($use=
'encoded')
2153 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2162 public function decode()
2164 return $this->value;
2189 public $digest_uri =
'';
2190 public $scheme =
'';
2194 public $request_method =
'POST';
2195 public $protocol_version =
'1.0';
2196 public $encoding =
'';
2197 public $outgoing_headers = array();
2198 public $incoming_headers = array();
2199 public $incoming_cookies = array();
2200 public $outgoing_payload =
'';
2201 public $incoming_payload =
'';
2202 public $response_status_line;
2203 public $useSOAPAction =
true;
2204 public $persistentConnection =
false;
2206 public $ch_options = array();
2207 public $use_curl =
false;
2208 public $proxy = null;
2209 public $username =
'';
2210 public $password =
'';
2211 public $authtype =
'';
2212 public $digestRequest = array();
2213 public $certRequest = array();
2230 public function __construct(
$url, $curl_options = null, $use_curl =
false)
2233 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2235 $this->setURL(
$url);
2236 if (is_array($curl_options)) {
2237 $this->ch_options = $curl_options;
2239 $this->use_curl = $use_curl;
2240 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2242 $this->setHeader(
'User-Agent', $this->title .
'/' . $this->version .
' (' . ($rev[1] ??
'1.1') .
')');
2252 public function setCurlOption($option, $value)
2254 $this->
debug(
"setCurlOption option=$option, value=");
2256 curl_setopt($this->ch, $option, $value);
2266 public function setHeader($name, $value)
2268 $this->outgoing_headers[$name] = $value;
2269 $this->
debug(
"set header $name: $value");
2278 public function unsetHeader($name)
2280 if (isset($this->outgoing_headers[$name])) {
2281 $this->
debug(
"unset header $name");
2282 unset($this->outgoing_headers[$name]);
2292 public function setURL(
$url)
2296 $u = parse_url(
$url);
2297 foreach ($u as $k => $v) {
2298 $this->
debug(
"parsed URL $k = $v");
2303 if (isset($u[
'query']) && $u[
'query'] !=
'') {
2304 $this->path .=
'?' . $u[
'query'];
2308 if (!isset($u[
'port'])) {
2309 if ($u[
'scheme'] ==
'https') {
2317 $this->digest_uri = $this->uri;
2320 if (!isset($u[
'port'])) {
2321 $this->setHeader(
'Host', $this->host);
2323 $this->setHeader(
'Host', $this->host .
':' . $this->port);
2326 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2327 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2337 public function io_method()
2339 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm')) {
2342 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm')) {
2356 public function connect($connection_timeout=0, $response_timeout=30)
2370 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2371 if ($this->io_method() ==
'socket') {
2372 if (!is_array($this->proxy)) {
2373 $host = $this->host;
2374 $port = $this->port;
2376 $host = $this->proxy[
'host'];
2377 $port = $this->proxy[
'port'];
2381 if ($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
2382 if (!feof($this->fp)) {
2383 $this->
debug(
'Re-use persistent connection');
2387 $this->
debug(
'Closed persistent connection at EOF');
2391 if ($this->scheme ==
'ssl') {
2392 $host =
'ssl://' . $host;
2394 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2397 if ($connection_timeout > 0) {
2398 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2400 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
2405 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2409 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2417 $this->
debug(
'set response timeout to ' . $response_timeout);
2418 socket_set_timeout($this->fp, $response_timeout);
2420 $this->
debug(
'socket connected');
2422 } elseif ($this->io_method() ==
'curl') {
2423 if (!extension_loaded(
'curl')) {
2425 $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.');
2429 if (defined(
'CURLOPT_CONNECTIONTIMEOUT')) {
2430 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2432 $CURLOPT_CONNECTIONTIMEOUT = 78;
2434 if (defined(
'CURLOPT_HTTPAUTH')) {
2435 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2437 $CURLOPT_HTTPAUTH = 107;
2439 if (defined(
'CURLOPT_PROXYAUTH')) {
2440 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2442 $CURLOPT_PROXYAUTH = 111;
2444 if (defined(
'CURLAUTH_BASIC')) {
2445 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2447 $CURLAUTH_BASIC = 1;
2449 if (defined(
'CURLAUTH_DIGEST')) {
2450 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2452 $CURLAUTH_DIGEST = 2;
2454 if (defined(
'CURLAUTH_NTLM')) {
2455 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2460 $this->
debug(
'connect using cURL');
2462 $this->ch = curl_init();
2464 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2467 $this->setCurlOption(CURLOPT_URL, $hostURL);
2469 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2470 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2471 $this->
debug(
'safe_mode = ');
2473 $this->
debug(
'open_basedir = ');
2476 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2479 $this->setCurlOption(CURLOPT_HEADER, 1);
2481 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2488 if ($this->persistentConnection) {
2494 $this->persistentConnection =
false;
2495 $this->setHeader(
'Connection',
'close');
2498 if ($connection_timeout != 0) {
2499 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2501 if ($response_timeout != 0) {
2502 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2505 if ($this->scheme ==
'https') {
2506 $this->
debug(
'set cURL SSL verify options');
2511 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2512 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2515 if ($this->authtype ==
'certificate') {
2516 $this->
debug(
'set cURL certificate options');
2517 if (isset($this->certRequest[
'cainfofile'])) {
2518 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2520 if (isset($this->certRequest[
'verifypeer'])) {
2521 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2523 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2525 if (isset($this->certRequest[
'verifyhost'])) {
2526 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2528 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2530 if (isset($this->certRequest[
'sslcertfile'])) {
2531 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2533 if (isset($this->certRequest[
'sslkeyfile'])) {
2534 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2536 if (isset($this->certRequest[
'passphrase'])) {
2537 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2539 if (isset($this->certRequest[
'certpassword'])) {
2540 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2544 if ($this->authtype && ($this->authtype !=
'certificate')) {
2545 if ($this->username) {
2546 $this->
debug(
'set cURL username/password');
2547 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2549 if ($this->authtype ==
'basic') {
2550 $this->
debug(
'set cURL for Basic authentication');
2551 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2553 if ($this->authtype ==
'digest') {
2554 $this->
debug(
'set cURL for digest authentication');
2555 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2557 if ($this->authtype ==
'ntlm') {
2558 $this->
debug(
'set cURL for NTLM authentication');
2559 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2562 if (is_array($this->proxy)) {
2563 $this->
debug(
'set cURL proxy options');
2564 if ($this->proxy[
'port'] !=
'') {
2565 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'] .
':' . $this->proxy[
'port']);
2567 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2569 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2570 $this->
debug(
'set cURL proxy authentication options');
2571 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'] .
':' . $this->proxy[
'password']);
2572 if ($this->proxy[
'authtype'] ==
'basic') {
2573 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2575 if ($this->proxy[
'authtype'] ==
'ntlm') {
2576 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2580 $this->
debug(
'cURL connection set up');
2583 $this->
setError(
'Unknown scheme ' . $this->scheme);
2584 $this->
debug(
'Unknown scheme ' . $this->scheme);
2599 public function send(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2601 $this->
debug(
'entered send() with data of length: ' . strlen(
$data));
2603 $this->tryagain =
true;
2605 while ($this->tryagain) {
2606 $this->tryagain =
false;
2609 if (!$this->connect($timeout, $response_timeout)) {
2614 if (!$this->sendRequest(
$data, $cookies)) {
2619 $respdata = $this->getResponse();
2621 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2624 $this->
debug(
'end of send()');
2640 public function sendHTTPS(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2642 return $this->
send(
$data, $timeout, $response_timeout, $cookies);
2655 public function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array())
2657 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2659 $this->
debug(
"certRequest=");
2662 if ($authtype ==
'basic') {
2663 $this->setHeader(
'Authorization',
'Basic ' . base64_encode(str_replace(
':',
'', $username) .
':' . $password));
2664 } elseif ($authtype ==
'digest') {
2665 if (isset($digestRequest[
'nonce'])) {
2666 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2671 $A1 = $username .
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2677 $A2 = $this->request_method .
':' . $this->digest_uri;
2693 $unhashedDigest =
'';
2694 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2696 if ($digestRequest[
'qop'] !=
'') {
2697 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2699 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2702 $hashedDigest = md5($unhashedDigest);
2705 if (isset($digestRequest[
'opaque'])) {
2706 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2709 $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 .
'"');
2711 } elseif ($authtype ==
'certificate') {
2712 $this->certRequest = $certRequest;
2713 $this->
debug(
'Authorization header not set for certificate');
2714 } elseif ($authtype ==
'ntlm') {
2716 $this->
debug(
'Authorization header not set for ntlm');
2718 $this->username = $username;
2719 $this->password = $password;
2720 $this->authtype = $authtype;
2721 $this->digestRequest = $digestRequest;
2730 public function setSOAPAction($soapaction)
2732 $this->setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2741 public function setEncoding($enc=
'gzip, deflate')
2743 if (function_exists(
'gzdeflate')) {
2744 $this->protocol_version =
'1.1';
2745 $this->setHeader(
'Accept-Encoding', $enc);
2746 if (!isset($this->outgoing_headers[
'Connection'])) {
2747 $this->setHeader(
'Connection',
'close');
2748 $this->persistentConnection =
false;
2750 #set_magic_quotes_runtime(0); 2752 $this->encoding = $enc;
2766 public function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic')
2769 $this->proxy = array(
2770 'host' => $proxyhost,
2771 'port' => $proxyport,
2772 'username' => $proxyusername,
2773 'password' => $proxypassword,
2774 'authtype' => $proxyauthtype
2776 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2777 $this->setHeader(
'Proxy-Authorization',
' Basic ' . base64_encode($proxyusername .
':' . $proxypassword));
2780 $this->
debug(
'remove proxy');
2782 unsetHeader(
'Proxy-Authorization');
2795 public function isSkippableCurlHeader(&
$data)
2797 $skipHeaders = array(
'HTTP/1.1 100',
2804 'HTTP/1.0 200 Connection established');
2805 foreach ($skipHeaders as $hd) {
2806 $prefix = substr(
$data, 0, strlen($hd));
2807 if ($prefix == $hd) {
2825 public function decodeChunked($buffer, $lb)
2833 $chunkend = strpos($buffer, $lb);
2834 if ($chunkend ==
false) {
2835 $this->
debug(
'no linebreak found in decodeChunked');
2838 $temp = substr($buffer, 0, $chunkend);
2839 $chunk_size = hexdec(trim($temp));
2840 $chunkstart = $chunkend + strlen($lb);
2842 while ($chunk_size > 0) {
2843 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2844 $chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
2847 if ($chunkend ==
false) {
2848 $chunk = substr($buffer, $chunkstart);
2851 $length += strlen($chunk);
2856 $chunk = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2860 $length += strlen($chunk);
2862 $chunkstart = $chunkend + strlen($lb);
2864 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2865 if ($chunkend ==
false) {
2868 $temp = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2869 $chunk_size = hexdec(trim($temp));
2870 $chunkstart = $chunkend;
2883 public function buildPayload(
$data, $cookie_str =
'')
2890 $this->setHeader(
'Content-Length', strlen(
$data));
2898 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2899 $this->
debug(
"HTTP request: $req");
2900 $this->outgoing_payload =
"$req\r\n";
2903 foreach ($this->outgoing_headers as $k => $v) {
2904 $hdr = $k .
': ' . $v;
2905 $this->
debug(
"HTTP header: $hdr");
2906 $this->outgoing_payload .=
"$hdr\r\n";
2910 if ($cookie_str !=
'') {
2911 $hdr =
'Cookie: ' . $cookie_str;
2912 $this->
debug(
"HTTP header: $hdr");
2913 $this->outgoing_payload .=
"$hdr\r\n";
2917 $this->outgoing_payload .=
"\r\n";
2920 $this->outgoing_payload .=
$data;
2931 public function sendRequest(
$data, $cookies = null)
2934 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2937 $this->buildPayload(
$data, $cookie_str);
2939 if ($this->io_method() ==
'socket') {
2941 if (!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2942 $this->
setError(
'couldn\'t write message data to socket');
2943 $this->
debug(
'couldn\'t write message data to socket');
2946 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2948 } elseif ($this->io_method() ==
'curl') {
2954 $curl_headers = array();
2955 foreach ($this->outgoing_headers as $k => $v) {
2956 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2957 $this->
debug(
"Skip cURL header $k: $v");
2959 $curl_headers[] =
"$k: $v";
2962 if ($cookie_str !=
'') {
2963 $curl_headers[] =
'Cookie: ' . $cookie_str;
2965 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2966 $this->
debug(
'set cURL HTTP headers');
2967 if ($this->request_method ==
"POST") {
2968 $this->setCurlOption(CURLOPT_POST, 1);
2969 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2970 $this->
debug(
'set cURL POST data');
2974 foreach ($this->ch_options as $key => $val) {
2975 $this->setCurlOption($key, $val);
2978 $this->
debug(
'set cURL payload');
2989 public function getResponse()
2991 $this->incoming_payload =
'';
2993 if ($this->io_method() ==
'socket') {
2996 while (!isset($lb)) {
2998 if (feof($this->fp)) {
2999 $this->incoming_payload =
$data;
3000 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
3001 $this->
debug(
"received before EOF:\n" .
$data);
3002 $this->
setError(
'server failed to send headers');
3006 $tmp = fgets($this->fp, 256);
3007 $tmplen = strlen($tmp);
3008 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
3011 $this->incoming_payload =
$data;
3012 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
3013 $this->
debug(
"read before timeout: " .
$data);
3014 $this->
setError(
'socket read of headers timed out');
3019 $pos = strpos(
$data,
"\r\n\r\n");
3023 $pos = strpos(
$data,
"\n\n");
3029 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3035 $this->incoming_payload .=
$data;
3036 $this->
debug(
'found end of headers after length ' . strlen(
$data));
3038 $header_data = trim(substr(
$data, 0, $pos));
3039 $header_array = explode($lb, $header_data);
3040 $this->incoming_headers = array();
3041 $this->incoming_cookies = array();
3042 foreach ($header_array as $header_line) {
3043 $arr = explode(
':', $header_line, 2);
3044 if (count($arr) > 1) {
3045 $header_name = strtolower(trim($arr[0]));
3046 $this->incoming_headers[$header_name] = trim($arr[1]);
3047 if ($header_name ==
'set-cookie') {
3049 $cookie = $this->parseCookie(trim($arr[1]));
3051 $this->incoming_cookies[] = $cookie;
3052 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3054 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3057 } elseif (isset($header_name)) {
3059 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3064 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
3065 $content_length = 2147483647;
3067 $this->
debug(
"want to read chunked content");
3068 } elseif (isset($this->incoming_headers[
'content-length'])) {
3069 $content_length = $this->incoming_headers[
'content-length'];
3071 $this->
debug(
"want to read content of length $content_length");
3073 $content_length = 2147483647;
3075 $this->
debug(
"want to read content to EOF");
3080 $tmp = fgets($this->fp, 256);
3081 $tmplen = strlen($tmp);
3082 $this->
debug(
"read chunk line of $tmplen bytes");
3084 $this->incoming_payload =
$data;
3085 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3086 $this->
debug(
"read before timeout:\n" .
$data);
3087 $this->
setError(
'socket read of chunk length timed out');
3090 $content_length = hexdec(trim($tmp));
3091 $this->
debug(
"chunk length $content_length");
3094 while (($strlen < $content_length) && (!feof($this->fp))) {
3095 $readlen = min(8192, $content_length - $strlen);
3096 $tmp = fread($this->fp, $readlen);
3097 $tmplen = strlen($tmp);
3098 $this->
debug(
"read buffer of $tmplen bytes");
3099 if (($tmplen == 0) && (!feof($this->fp))) {
3100 $this->incoming_payload =
$data;
3101 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3102 $this->
debug(
"read before timeout:\n" .
$data);
3103 $this->
setError(
'socket read of body timed out');
3109 if ($chunked && ($content_length > 0)) {
3110 $tmp = fgets($this->fp, 256);
3111 $tmplen = strlen($tmp);
3112 $this->
debug(
"read chunk terminator of $tmplen bytes");
3114 $this->incoming_payload =
$data;
3115 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3116 $this->
debug(
"read before timeout:\n" .
$data);
3117 $this->
setError(
'socket read of chunk terminator timed out');
3121 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3122 if (feof($this->fp)) {
3123 $this->
debug(
'read to EOF');
3125 $this->
debug(
'read body of length ' . strlen(
$data));
3126 $this->incoming_payload .=
$data;
3127 $this->
debug(
'received a total of ' . strlen($this->incoming_payload) .
' bytes of data from server');
3131 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3132 (! $this->persistentConnection) || feof($this->fp)) {
3135 $this->
debug(
'closed socket');
3139 if ($this->incoming_payload ==
'') {
3140 $this->
setError(
'no response from server');
3154 } elseif ($this->io_method() ==
'curl') {
3156 $this->
debug(
'send and receive with cURL');
3157 $this->incoming_payload = curl_exec($this->ch);
3158 $data = $this->incoming_payload;
3160 $cErr = curl_error($this->ch);
3162 $err =
'cURL ERROR: ' . curl_errno($this->ch) .
': ' . $cErr .
'<br>';
3164 foreach (curl_getinfo($this->ch) as $k => $v) {
3165 $err .=
"$k: $v<br>";
3169 curl_close($this->ch);
3177 $this->
debug(
'No cURL error, closing cURL');
3178 curl_close($this->ch);
3182 while ($this->isSkippableCurlHeader(
$data)) {
3183 $this->
debug(
"Found HTTP header to skip");
3184 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3186 } elseif ($pos = strpos(
$data,
"\n\n")) {
3194 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3195 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3197 } elseif ($pos = strpos(
$data,
"\n\n")) {
3204 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3206 } elseif ($pos = strpos(
$data,
"\n\n")) {
3209 $this->
debug(
'no proper separation of headers and document');
3210 $this->
setError(
'no proper separation of headers and document');
3213 $header_data = trim(substr(
$data, 0, $pos));
3214 $header_array = explode($lb, $header_data);
3216 $this->
debug(
'found proper separation of headers and document');
3217 $this->
debug(
'cleaned data, stringlen: ' . strlen(
$data));
3219 foreach ($header_array as $header_line) {
3220 $arr = explode(
':', $header_line, 2);
3221 if (count($arr) > 1) {
3222 $header_name = strtolower(trim($arr[0]));
3223 $this->incoming_headers[$header_name] = trim($arr[1]);
3224 if ($header_name ==
'set-cookie') {
3226 $cookie = $this->parseCookie(trim($arr[1]));
3228 $this->incoming_cookies[] = $cookie;
3229 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3231 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3234 } elseif (isset($header_name)) {
3236 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3241 $this->response_status_line = $header_array[0];
3242 $arr = explode(
' ', $this->response_status_line, 3);
3243 $http_version = $arr[0];
3244 $http_status = intval($arr[1]);
3245 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3248 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3249 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3250 $this->setURL($this->incoming_headers[
'location']);
3251 $this->tryagain =
true;
3256 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3257 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3258 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3259 $this->
debug(
'Server wants digest authentication');
3261 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3264 $digestElements = explode(
',', $digestString);
3265 foreach ($digestElements as $val) {
3266 $tempElement = explode(
'=', trim($val), 2);
3267 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3271 if (isset($digestRequest[
'nonce'])) {
3272 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3273 $this->tryagain =
true;
3277 $this->
debug(
'HTTP authentication failed');
3278 $this->
setError(
'HTTP authentication failed');
3283 ($http_status >= 300 && $http_status <= 307) ||
3284 ($http_status >= 400 && $http_status <= 417) ||
3285 ($http_status >= 501 && $http_status <= 505)
3287 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3292 if (isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
'') {
3293 if (strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip') {
3295 if (function_exists(
'gzinflate')) {
3299 $this->
debug(
'The gzinflate function exists');
3300 $datalen = strlen(
$data);
3301 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3302 if ($degzdata = @gzinflate(
$data)) {
3304 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3305 if (strlen(
$data) < $datalen) {
3307 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3308 if ($degzdata = @gzinflate(
$data)) {
3310 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3314 $this->
debug(
'Error using gzinflate to inflate the payload');
3315 $this->
setError(
'Error using gzinflate to inflate the payload');
3317 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3318 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3320 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3321 if (strlen(
$data) < $datalen) {
3323 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3324 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3326 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3330 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3331 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3337 $this->incoming_payload = $header_data . $lb . $lb .
$data;
3339 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3340 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3343 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3344 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3347 $this->
debug(
'No Content-Encoding header');
3350 if (strlen(
$data) == 0) {
3351 $this->
debug(
'no data after headers!');
3352 $this->
setError(
'no data present after HTTP headers');
3366 public function setContentType($type, $charset =
false)
3368 $this->setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3377 public function usePersistentConnection()
3379 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3382 $this->protocol_version =
'1.1';
3383 $this->persistentConnection =
true;
3384 $this->setHeader(
'Connection',
'Keep-Alive');
3398 public function parseCookie($cookie_str)
3400 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3403 $data = explode(
';', $cookie_str);
3404 $value_str =
$data[0];
3406 $cookie_param =
'domain=';
3407 $start = strpos($cookie_str, $cookie_param);
3409 $domain = substr($cookie_str, $start + strlen($cookie_param));
3410 $domain = substr($domain, 0, strpos($domain,
';'));
3415 $cookie_param =
'expires=';
3416 $start = strpos($cookie_str, $cookie_param);
3418 $expires = substr($cookie_str, $start + strlen($cookie_param));
3419 $expires = substr($expires, 0, strpos($expires,
';'));
3424 $cookie_param =
'path=';
3425 $start = strpos($cookie_str, $cookie_param);
3427 $path = substr($cookie_str, $start + strlen($cookie_param));
3433 $cookie_param =
';secure;';
3434 if (strpos($cookie_str, $cookie_param) !==
false) {
3440 $sep_pos = strpos($value_str,
'=');
3443 $name = substr($value_str, 0, $sep_pos);
3444 $value = substr($value_str, $sep_pos + 1);
3445 $cookie= array(
'name' => $name,
3447 'domain' => $domain,
3449 'expires' => $expires,
3465 public function getCookiesForRequest($cookies, $secure=
false)
3468 if ((! is_null($cookies)) && (is_array($cookies))) {
3469 foreach ($cookies as $cookie) {
3470 if (! is_array($cookie)) {
3473 $this->
debug(
"check cookie for validity: " . $cookie[
'name'] .
'=' . $cookie[
'value']);
3474 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3475 if (strtotime($cookie[
'expires']) <= time()) {
3476 $this->
debug(
'cookie has expired');
3480 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3481 $domain = preg_quote($cookie[
'domain']);
3482 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3483 $this->
debug(
'cookie has different domain');
3487 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3488 $path = preg_quote($cookie[
'path']);
3489 if (! preg_match(
"'^$path.*'i", $this->path)) {
3490 $this->
debug(
'cookie is for a different path');
3494 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3495 $this->
debug(
'cookie is secure, transport is not');
3498 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3499 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3528 public $headers = array();
3534 public $request =
'';
3540 public $requestHeaders =
'';
3546 public $requestHeader = null;
3552 public $document =
'';
3558 public $requestSOAP =
'';
3564 public $methodURI =
'';
3570 public $methodname =
'';
3576 public $methodparams = array();
3582 public $SOAPAction =
'';
3588 public $xml_encoding =
'';
3594 public $decode_utf8 =
true;
3602 public $outgoing_headers = array();
3614 public $responseHeaders =
'';
3620 public $responseSOAP =
'';
3626 public $methodreturn =
false;
3632 public $methodreturnisliteralxml =
false;
3638 public $fault =
false;
3644 public $result =
'successful';
3652 public $operations = array();
3658 public $wsdl =
false;
3664 public $externalWSDLURL =
false;
3670 public $debug_flag =
false;
3685 global $HTTP_SERVER_VARS;
3688 $this->
debug(
"_SERVER is defined:");
3690 } elseif (isset($HTTP_SERVER_VARS)) {
3691 $this->
debug(
"HTTP_SERVER_VARS is defined:");
3694 $this->
debug(
"Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3697 if (isset($debug)) {
3698 $this->
debug(
"In nusoap_server, set debug_flag=$debug based on global flag");
3699 $this->debug_flag = $debug;
3700 } elseif (isset(
$_SERVER[
'QUERY_STRING'])) {
3701 $qs = explode(
'&',
$_SERVER[
'QUERY_STRING']);
3702 foreach ($qs as $v) {
3703 if (substr($v, 0, 6) ==
'debug=') {
3704 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #1");
3705 $this->debug_flag = substr($v, 6);
3708 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3709 $qs = explode(
'&', $HTTP_SERVER_VARS[
'QUERY_STRING']);
3710 foreach ($qs as $v) {
3711 if (substr($v, 0, 6) ==
'debug=') {
3712 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #2");
3713 $this->debug_flag = substr($v, 6);
3720 $this->
debug(
"In nusoap_server, WSDL is specified");
3721 if (is_object($wsdl) && (get_class($wsdl) ==
'wsdl')) {
3722 $this->
wsdl = $wsdl;
3723 $this->externalWSDLURL = $this->
wsdl->wsdl;
3724 $this->
debug(
'Use existing wsdl instance from ' . $this->externalWSDLURL);
3726 $this->
debug(
'Create wsdl from ' . $wsdl);
3728 $this->externalWSDLURL = $wsdl;
3733 die(
'WSDL ERROR: ' . $err);
3744 public function service(
$data)
3746 global $HTTP_SERVER_VARS;
3748 if (isset(
$_SERVER[
'QUERY_STRING'])) {
3750 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3751 $qs = $HTTP_SERVER_VARS[
'QUERY_STRING'];
3755 $this->
debug(
"In service, query string=$qs");
3757 if (preg_match(
'/wsdl/', $qs)) {
3758 $this->
debug(
"In service, this is a request for WSDL");
3759 if ($this->externalWSDLURL) {
3760 if (strpos($this->externalWSDLURL,
"://")!==
false) {
3761 header(
'Location: ' . $this->externalWSDLURL);
3763 header(
"Content-Type: text/xml\r\n");
3764 $fp = fopen($this->externalWSDLURL,
'r');
3767 } elseif ($this->
wsdl) {
3768 header(
"Content-Type: text/xml; charset=ISO-8859-1\r\n");
3770 if ($this->debug_flag) {
3771 $this->
debug(
'wsdl:');
3776 header(
"Content-Type: text/html; charset=ISO-8859-1\r\n");
3777 print
"This service does not provide WSDL";
3780 $this->
debug(
"In service, there is no data, so return Web description");
3783 $this->
debug(
"In service, invoke the request");
3784 $this->parse_request(
$data);
3785 if (! $this->fault) {
3786 $this->invoke_method();
3788 if (! $this->fault) {
3789 $this->serialize_return();
3791 $this->send_response();
3807 public function parse_http_headers()
3809 global $HTTP_SERVER_VARS;
3811 $this->request =
'';
3812 $this->SOAPAction =
'';
3813 if (function_exists(
'getallheaders')) {
3814 $this->
debug(
"In parse_http_headers, use getallheaders");
3815 $headers = getallheaders();
3816 foreach ($headers as $k=>$v) {
3817 $k = strtolower($k);
3818 $this->headers[$k] = $v;
3819 $this->request .=
"$k: $v\r\n";
3820 $this->
debug(
"$k: $v");
3823 if (isset($this->headers[
'soapaction'])) {
3824 $this->SOAPAction = str_replace(
'"',
'', $this->headers[
'soapaction']);
3827 if (isset($this->headers[
'content-type']) && strpos($this->headers[
'content-type'],
'=')) {
3828 $enc = str_replace(
'"',
'', substr(strstr($this->headers[
"content-type"],
'='), 1));
3829 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3830 $this->xml_encoding = strtoupper($enc);
3832 $this->xml_encoding =
'US-ASCII';
3836 $this->xml_encoding =
'ISO-8859-1';
3839 $this->
debug(
"In parse_http_headers, use _SERVER");
3841 if (substr($k, 0, 5) ==
'HTTP_') {
3842 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3844 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3846 if ($k ==
'soapaction') {
3849 $v = str_replace(
'"',
'', $v);
3850 $v = str_replace(
'\\',
'', $v);
3851 $this->SOAPAction = $v;
3852 } elseif ($k ==
'content-type') {
3854 if (strpos($v,
'=')) {
3855 $enc = substr(strstr($v,
'='), 1);
3856 $enc = str_replace(
'"',
'', $enc);
3857 $enc = str_replace(
'\\',
'', $enc);
3858 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3859 $this->xml_encoding = strtoupper($enc);
3861 $this->xml_encoding =
'US-ASCII';
3865 $this->xml_encoding =
'ISO-8859-1';
3868 $this->headers[$k] = $v;
3869 $this->request .=
"$k: $v\r\n";
3870 $this->
debug(
"$k: $v");
3872 } elseif (is_array($HTTP_SERVER_VARS)) {
3873 $this->
debug(
"In parse_http_headers, use HTTP_SERVER_VARS");
3874 foreach ($HTTP_SERVER_VARS as $k => $v) {
3875 if (substr($k, 0, 5) ==
'HTTP_') {
3876 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3877 $k = strtolower(substr($k, 5));
3879 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3880 $k = strtolower($k);
3882 if ($k ==
'soapaction') {
3885 $v = str_replace(
'"',
'', $v);
3886 $v = str_replace(
'\\',
'', $v);
3887 $this->SOAPAction = $v;
3888 } elseif ($k ==
'content-type') {
3890 if (strpos($v,
'=')) {
3891 $enc = substr(strstr($v,
'='), 1);
3892 $enc = str_replace(
'"',
'', $enc);
3893 $enc = str_replace(
'\\',
'', $enc);
3894 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3895 $this->xml_encoding = strtoupper($enc);
3897 $this->xml_encoding =
'US-ASCII';
3901 $this->xml_encoding =
'ISO-8859-1';
3904 $this->headers[$k] = $v;
3905 $this->request .=
"$k: $v\r\n";
3906 $this->
debug(
"$k: $v");
3909 $this->
debug(
"In parse_http_headers, HTTP headers not accessible");
3910 $this->
setError(
"HTTP headers not accessible");
3936 public function parse_request(
$data=
'')
3938 $this->
debug(
'entering parse_request()');
3939 $this->parse_http_headers();
3940 $this->
debug(
'got character encoding: ' . $this->xml_encoding);
3942 if (isset($this->headers[
'content-encoding']) && $this->headers[
'content-encoding'] !=
'') {
3943 $this->
debug(
'got content encoding: ' . $this->headers[
'content-encoding']);
3944 if ($this->headers[
'content-encoding'] ==
'deflate' || $this->headers[
'content-encoding'] ==
'gzip') {
3946 if (function_exists(
'gzuncompress')) {
3947 if ($this->headers[
'content-encoding'] ==
'deflate' && $degzdata = @gzuncompress(
$data)) {
3949 } elseif ($this->headers[
'content-encoding'] ==
'gzip' && $degzdata = gzinflate(substr(
$data, 10))) {
3952 $this->fault(
'SOAP-ENV:Client',
'Errors occurred when trying to decode the data');
3956 $this->fault(
'SOAP-ENV:Client',
'This Server does not support compressed data');
3961 $this->request .=
"\r\n" .
$data;
3962 $data = $this->parseRequest($this->headers,
$data);
3963 $this->requestSOAP =
$data;
3964 $this->
debug(
'leaving parse_request');
3984 public function invoke_method()
3986 $this->
debug(
'in invoke_method, methodname=' . $this->methodname .
' methodURI=' . $this->methodURI .
' SOAPAction=' . $this->SOAPAction);
3990 $this->
debug(
'in invoke_method, found WSDL operation=' . $this->methodname);
3994 $this->
debug(
'in invoke_method, found WSDL soapAction=' . $this->SOAPAction .
' for operation=' . $this->opData[
'name']);
3996 $this->methodname = $this->opData[
'name'];
3998 $this->
debug(
'in invoke_method, no WSDL for operation=' . $this->methodname);
3999 $this->fault(
'SOAP-ENV:Client',
"Operation '" . $this->methodname .
"' is not defined in the WSDL for this service");
4003 $this->
debug(
'in invoke_method, no WSDL to validate method');
4011 if (strpos($this->methodname,
'..') > 0) {
4013 } elseif (strpos($this->methodname,
'.') > 0) {
4019 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
4020 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
4022 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
4023 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
4024 $this->
debug(
"in invoke_method, class=$class method=$method delim=$delim");
4028 if ($class ==
'' && $this->
class !=
'') {
4029 $class = $this->class;
4031 $method = $this->methodname;
4036 if (!function_exists($this->methodname)) {
4037 $this->
debug(
"in invoke_method, function '$this->methodname' not found!");
4038 $this->result =
'fault: method not found';
4039 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4043 $method_to_compare = (substr(phpversion(), 0, 2) ==
'4.') ? strtolower($method) : $method;
4044 if (!in_array($method_to_compare, get_class_methods($class))) {
4045 $this->
debug(
"in invoke_method, method '$this->methodname' not found in class '$class'!");
4046 $this->result =
'fault: method not found';
4047 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4054 if (! $this->verify_method($this->methodname, $this->methodparams)) {
4056 $this->
debug(
'ERROR: request not verified against method signature');
4057 $this->result =
'fault: request failed validation against method signature';
4059 $this->fault(
'SOAP-ENV:Client',
"Operation '$this->methodname' not defined in service.");
4064 $this->
debug(
'in invoke_method, params:');
4066 $this->
debug(
"in invoke_method, calling '$this->methodname'");
4067 if (!function_exists(
'call_user_func_array')) {
4069 $this->
debug(
'in invoke_method, calling function using eval()');
4070 $funcCall =
"\$this->methodreturn = $this->methodname(";
4072 if ($delim ==
'..') {
4073 $this->
debug(
'in invoke_method, calling class method using eval()');
4074 $funcCall =
"\$this->methodreturn = " . $class .
"::" . $method .
"(";
4076 $this->
debug(
'in invoke_method, calling instance method using eval()');
4078 $instname =
"\$inst_" . time();
4079 $funcCall = $instname .
" = new " . $class .
"(); ";
4080 $funcCall .=
"\$this->methodreturn = " . $instname .
"->" . $method .
"(";
4083 if ($this->methodparams) {
4084 foreach ($this->methodparams as
$param) {
4085 if (is_array($param) || is_object($param)) {
4086 $this->fault(
'SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
4089 $funcCall .=
"\"$param\",";
4091 $funcCall = substr($funcCall, 0, -1);
4094 $this->
debug(
'in invoke_method, function call: ' . $funcCall);
4098 $this->
debug(
'in invoke_method, calling function using call_user_func_array()');
4099 $call_arg =
"$this->methodname";
4100 } elseif ($delim ==
'..') {
4101 $this->
debug(
'in invoke_method, calling class method using call_user_func_array()');
4102 $call_arg = array($class, $method);
4104 $this->
debug(
'in invoke_method, calling instance method using call_user_func_array()');
4105 $instance =
new $class();
4106 $call_arg = array(&$instance, $method);
4108 if (is_array($this->methodparams)) {
4109 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4111 $this->methodreturn = call_user_func_array($call_arg, array());
4114 $this->
debug(
'in invoke_method, methodreturn:');
4116 $this->
debug(
"in invoke_method, called method $this->methodname, received data of type " . gettype($this->methodreturn));
4130 public function serialize_return()
4132 $this->
debug(
'Entering serialize_return methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4134 if (isset($this->methodreturn) && ((get_class((
object)$this->methodreturn) ==
'soap_fault') || (get_class((
object)$this->methodreturn) ==
'nusoap_fault'))) {
4135 $this->
debug(
'got a fault object from method');
4136 $this->fault = $this->methodreturn;
4138 } elseif ($this->methodreturnisliteralxml) {
4139 $return_val = $this->methodreturn;
4142 $this->
debug(
'got a(n) ' . gettype($this->methodreturn) .
' from method');
4143 $this->
debug(
'serializing return value');
4145 if (
sizeof($this->opData[
'output'][
'parts']) > 1) {
4146 $this->
debug(
'more than one output part, so use the method return unchanged');
4147 $opParams = $this->methodreturn;
4148 } elseif (
sizeof($this->opData[
'output'][
'parts']) == 1) {
4149 $this->
debug(
'exactly one output part, so wrap the method return in a simple array');
4154 $opParams = array($this->methodreturn);
4160 $this->
debug(
'got wsdl error: ' . $errstr);
4161 $this->fault(
'SOAP-ENV:Server',
'unable to serialize result');
4165 if (isset($this->methodreturn)) {
4166 $return_val = $this->
serialize_val($this->methodreturn,
'return');
4169 $this->
debug(
'in absence of WSDL, assume void return for backward compatibility');
4173 $this->
debug(
'return value:');
4176 $this->
debug(
'serializing response');
4178 $this->
debug(
'have WSDL for serialization: style is ' . $this->opData[
'style']);
4179 if ($this->opData[
'style'] ==
'rpc') {
4180 $this->
debug(
'style is rpc for serialization: use is ' . $this->opData[
'output'][
'use']);
4181 if ($this->opData[
'output'][
'use'] ==
'literal') {
4183 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4185 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4188 $this->
debug(
'style is not rpc for serialization: assume document');
4192 $this->
debug(
'do not have WSDL for serialization: assume rpc/encoded');
4193 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4195 $this->result =
'successful';
4200 if (isset($opData[
'output'][
'encodingStyle'])) {
4201 $encodingStyle = $opData[
'output'][
'encodingStyle'];
4203 $encodingStyle =
'';
4206 $this->responseSOAP = $this->
serializeEnvelope(
$payload, $this->responseHeaders, $this->
wsdl->usedNamespaces, $this->opData[
'style'], $this->opData[
'output'][
'use'], $encodingStyle);
4210 $this->
debug(
"Leaving serialize_return");
4223 public function send_response()
4225 $this->
debug(
'Enter send_response');
4227 $payload = $this->fault->serialize();
4228 $this->outgoing_headers[] =
"HTTP/1.0 500 Internal Server Error";
4229 $this->outgoing_headers[] =
"Status: 500 Internal Server Error";
4239 if (isset($this->debug_flag) && $this->debug_flag) {
4242 $this->outgoing_headers[] =
"Server: $this->title Server v$this->version";
4243 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
4244 $this->outgoing_headers[] =
"X-SOAP-Server: $this->title/$this->version (" . $rev[1] .
")";
4248 $type = $this->getHTTPContentType();
4249 $charset = $this->getHTTPContentTypeCharset();
4250 $this->outgoing_headers[] =
"Content-Type: $type" . ($charset ?
'; charset=' . $charset :
'');
4254 if (strlen(
$payload) > 1024 && isset($this->headers) && isset($this->headers[
'accept-encoding'])) {
4255 if (strstr($this->headers[
'accept-encoding'],
'gzip')) {
4256 if (function_exists(
'gzencode')) {
4257 if (isset($this->debug_flag) && $this->debug_flag) {
4258 $payload .=
"<!-- Content being gzipped -->";
4260 $this->outgoing_headers[] =
"Content-Encoding: gzip";
4263 if (isset($this->debug_flag) && $this->debug_flag) {
4264 $payload .=
"<!-- Content will not be gzipped: no gzencode -->";
4267 } elseif (strstr($this->headers[
'accept-encoding'],
'deflate')) {
4271 if (function_exists(
'gzdeflate')) {
4272 if (isset($this->debug_flag) && $this->debug_flag) {
4273 $payload .=
"<!-- Content being deflated -->";
4275 $this->outgoing_headers[] =
"Content-Encoding: deflate";
4278 if (isset($this->debug_flag) && $this->debug_flag) {
4279 $payload .=
"<!-- Content will not be deflated: no gzcompress -->";
4285 $this->outgoing_headers[] =
"Content-Length: " . strlen(
$payload);
4286 reset($this->outgoing_headers);
4287 foreach ($this->outgoing_headers as $hdr) {
4291 $this->response = join(
"\r\n", $this->outgoing_headers) .
"\r\n\r\n" .
$payload;
4303 public function verify_method($operation, $request)
4305 if (isset($this->
wsdl) && is_object($this->
wsdl)) {
4309 } elseif (isset($this->operations[$operation])) {
4323 public function parseRequest($headers,
$data)
4325 $this->
debug(
'Entering parseRequest() for data of length ' . strlen(
$data) .
' and type ' . $headers[
'content-type']);
4326 if (!strstr($headers[
'content-type'],
'text/xml')) {
4327 $this->
setError(
'Request not of type text/xml');
4330 if (strpos($headers[
'content-type'],
'=')) {
4331 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
4332 $this->
debug(
'Got response encoding: ' . $enc);
4333 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
4334 $this->xml_encoding = strtoupper($enc);
4336 $this->xml_encoding =
'US-ASCII';
4340 $this->xml_encoding =
'ISO-8859-1';
4342 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
4346 $this->
debug(
"parser debug: \n" . $parser->getDebug());
4348 if ($err = $parser->getError()) {
4349 $this->result =
'fault: error in msg parsing: ' . $err;
4350 $this->fault(
'SOAP-ENV:Client',
"error in msg parsing:\n" . $err);
4354 $this->methodURI = $parser->root_struct_namespace;
4355 $this->methodname = $parser->root_struct_name;
4356 $this->
debug(
'methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4357 $this->
debug(
'calling parser->get_soapbody()');
4358 $this->methodparams = $parser->get_soapbody();
4360 $this->requestHeaders = $parser->getHeaders();
4362 $this->requestHeader = $parser->get_soapheader();
4364 $this->document = $parser->document;
4375 public function getHTTPBody($soapmsg)
4388 public function getHTTPContentType()
4402 public function getHTTPContentTypeCharset()
4416 public function add_to_map($methodname, $in,
$out)
4418 $this->operations[$methodname] = array(
'name' => $methodname,
'in' => $in,
'out' =>
$out);
4435 public function register($name, $in=array(),
$out=array(),
$namespace=
false, $soapaction=
false, $style=
false, $use=
false, $documentation=
'', $encodingStyle=
'')
4437 global $HTTP_SERVER_VARS;
4439 if ($this->externalWSDLURL) {
4440 die(
'You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4443 die(
'You must specify a name when you register an operation');
4445 if (!is_array($in)) {
4446 die(
'You must provide an array for operation inputs');
4448 if (!is_array(
$out)) {
4449 die(
'You must provide an array for operation outputs');
4453 if (
false == $soapaction) {
4455 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4457 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4458 } elseif (isset($HTTP_SERVER_VARS)) {
4459 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4460 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4461 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4463 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4465 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4470 $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4472 if (
false == $style) {
4475 if (
false == $use) {
4478 if ($use ==
'encoded' && $encodingStyle =
'') {
4479 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
4482 $this->operations[$name] = array(
4487 'soapaction' => $soapaction,
4525 public function configureWSDL(
$serviceName,
$namespace =
false, $endpoint =
false, $style=
'rpc', $transport =
'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace =
false)
4527 global $HTTP_SERVER_VARS;
4530 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4531 $SERVER_PORT =
$_SERVER[
'SERVER_PORT'];
4533 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4534 } elseif (isset($HTTP_SERVER_VARS)) {
4535 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4536 $SERVER_PORT = $HTTP_SERVER_VARS[
'SERVER_PORT'];
4537 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4538 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4540 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4543 $colon = strpos($SERVER_NAME,
":");
4545 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4547 if ($SERVER_PORT == 80) {
4550 $SERVER_PORT =
':' . $SERVER_PORT;
4553 $namespace =
"http://$SERVER_NAME/soap/$serviceName";
4556 if (
false == $endpoint) {
4557 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4562 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4565 if (
false == $schemaTargetNamespace) {
4571 $this->
wsdl->endpoint = $endpoint;
4573 $this->
wsdl->namespaces[
'soap'] =
'http://schemas.xmlsoap.org/wsdl/soap/';
4574 $this->
wsdl->namespaces[
'wsdl'] =
'http://schemas.xmlsoap.org/wsdl/';
4576 $this->
wsdl->namespaces[
'types'] = $schemaTargetNamespace;
4579 if ($style ==
'document') {
4580 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo[
'elementFormDefault'] =
'qualified';
4582 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4583 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4584 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4588 'transport'=>$transport,
4592 'location'=>$endpoint,
4593 'bindingType'=>
'http://schemas.xmlsoap.org/wsdl/soap/');
4598 $port = $this->
wsdl->ports[$serviceName .
'Port'] ?? [
4599 'binding'=> $serviceName .
'Binding',
4601 'bindingType'=>
'http://schemas.xmlsoap.org/wsdl/soap/' 4604 $port[
'location'] = is_array($port[
'location']) ? array_merge($port[
'location'], [$url]) : [$port[
'location'], $url];
4606 $this->
wsdl->ports[$serviceName .
'Port'] = $port;
4635 public $currentPortOperation;
4638 public $schemas = array();
4639 public $currentSchema;
4640 public $message = array();
4641 public $complexTypes = array();
4642 public $messages = array();
4643 public $currentMessage;
4644 public $currentOperation;
4645 public $portTypes = array();
4646 public $currentPortType;
4647 public $bindings = array();
4648 public $currentBinding;
4649 public $ports = array();
4650 public $currentPort;
4651 public $opData = array();
4652 public $status =
'';
4653 public $documentation =
false;
4654 public $endpoint =
'';
4656 public $import = array();
4659 public $position = 0;
4661 public $depth_array = array();
4663 public $proxyhost =
'';
4664 public $proxyport =
'';
4665 public $proxyusername =
'';
4666 public $proxypassword =
'';
4667 public $timeout = 0;
4668 public $response_timeout = 30;
4669 public $curl_options = array();
4670 public $use_curl =
false;
4672 public $username =
'';
4673 public $password =
'';
4674 public $authtype =
'';
4675 public $certRequest = array();
4691 public function __construct($wsdl =
'', $proxyhost=
false, $proxyport=
false, $proxyusername=
false, $proxypassword=
false, $timeout=0, $response_timeout=30, $curl_options=null, $use_curl=
false)
4694 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4695 $this->proxyhost = $proxyhost;
4696 $this->proxyport = $proxyport;
4697 $this->proxyusername = $proxyusername;
4698 $this->proxypassword = $proxypassword;
4699 $this->timeout = $timeout;
4700 $this->response_timeout = $response_timeout;
4701 if (is_array($curl_options)) {
4702 $this->curl_options = $curl_options;
4704 $this->use_curl = $use_curl;
4705 $this->fetchWSDL($wsdl);
4713 public function fetchWSDL($wsdl)
4715 $this->
debug(
"parse and process WSDL path=$wsdl");
4716 $this->
wsdl = $wsdl;
4718 if ($this->
wsdl !=
"") {
4719 $this->parseWSDL($this->
wsdl);
4723 $imported_urls = array();
4725 while ($imported > 0) {
4728 foreach ($this->schemas as $ns => $list) {
4729 foreach ($list as $xs) {
4730 $wsdlparts = parse_url($this->
wsdl);
4731 foreach ($xs->imports as $ns2 => $list2) {
4732 for ($ii = 0; $ii < count($list2); $ii++) {
4733 if (! $list2[$ii][
'loaded']) {
4734 $this->schemas[$ns]->imports[$ns2][$ii][
'loaded'] =
true;
4735 $url = $list2[$ii][
'location'];
4737 $urlparts = parse_url(
$url);
4738 if (!isset($urlparts[
'host'])) {
4739 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4740 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4742 if (! in_array(
$url, $imported_urls)) {
4743 $this->parseWSDL(
$url);
4745 $imported_urls[] =
$url;
4748 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4756 $wsdlparts = parse_url($this->
wsdl);
4757 foreach ($this->
import as $ns => $list) {
4758 for ($ii = 0; $ii < count($list); $ii++) {
4759 if (! $list[$ii][
'loaded']) {
4760 $this->
import[$ns][$ii][
'loaded'] =
true;
4761 $url = $list[$ii][
'location'];
4763 $urlparts = parse_url(
$url);
4764 if (!isset($urlparts[
'host'])) {
4765 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4766 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4768 if (! in_array(
$url, $imported_urls)) {
4769 $this->parseWSDL(
$url);
4771 $imported_urls[] =
$url;
4774 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4781 foreach ($this->bindings as $binding => $bindingData) {
4782 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4783 foreach ($bindingData[
'operations'] as $operation =>
$data) {
4784 $this->
debug(
'post-parse data gathering for ' . $operation);
4785 $this->bindings[$binding][
'operations'][$operation][
'input'] =
4786 isset($this->bindings[$binding][
'operations'][$operation][
'input']) ?
4787 array_merge($this->bindings[$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4788 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4789 $this->bindings[$binding][
'operations'][$operation][
'output'] =
4790 isset($this->bindings[$binding][
'operations'][$operation][
'output']) ?
4791 array_merge($this->bindings[$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4792 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4793 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ])) {
4794 $this->bindings[$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ];
4796 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ])) {
4797 $this->bindings[$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ];
4800 if (isset($bindingData[
'style']) && !isset($this->bindings[$binding][
'operations'][$operation][
'style'])) {
4801 $this->bindings[$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4803 $this->bindings[$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4804 $this->bindings[$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4805 $this->bindings[$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4817 public function parseWSDL($wsdl =
'')
4819 $this->
debug(
"parse WSDL at path=$wsdl");
4822 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4823 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4828 $wsdl_props = parse_url($wsdl);
4830 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4831 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4834 $tr->request_method =
'GET';
4835 $tr->useSOAPAction =
false;
4836 if ($this->proxyhost && $this->proxyport) {
4837 $tr->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
4839 if ($this->authtype !=
'') {
4840 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4842 $tr->setEncoding(
'gzip, deflate');
4843 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4848 if ($err = $tr->getError()) {
4849 $errstr =
'HTTP ERROR: ' . $err;
4850 $this->
debug($errstr);
4856 $this->
debug(
"got WSDL URL");
4859 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4860 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4865 if ($fp = @fopen(
$path,
'r')) {
4867 while (
$data = fread($fp, 32768)) {
4868 $wsdl_string .=
$data;
4872 $errstr =
"Bad path to WSDL file $path";
4873 $this->
debug($errstr);
4878 $this->
debug(
'Parse WSDL');
4881 $this->parser = xml_parser_create();
4884 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4886 xml_set_object($this->parser, $this);
4888 xml_set_element_handler($this->parser,
'start_element',
'end_element');
4889 xml_set_character_data_handler($this->parser,
'character_data');
4891 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4894 'XML error parsing WSDL from %s on line %d: %s',
4896 xml_get_current_line_number($this->parser),
4897 xml_error_string(xml_get_error_code($this->parser))
4899 $this->
debug($errstr);
4900 $this->
debug(
"XML payload:\n" . $wsdl_string);
4905 xml_parser_free($this->parser);
4906 $this->
debug(
'Parsing WSDL done');
4922 public function start_element($parser, $name, $attrs)
4924 if ($this->status ==
'schema') {
4925 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4926 $this->
appendDebug($this->currentSchema->getDebug());
4927 $this->currentSchema->clearDebug();
4928 } elseif (preg_match(
'/schema$/', $name)) {
4929 $this->
debug(
'Parsing WSDL schema');
4931 $this->status =
'schema';
4933 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4934 $this->
appendDebug($this->currentSchema->getDebug());
4935 $this->currentSchema->clearDebug();
4938 $pos = $this->position++;
4939 $depth = $this->depth++;
4941 $this->depth_array[$depth] = $pos;
4942 $this->message[$pos] = array(
'cdata' =>
'');
4944 if (count($attrs) > 0) {
4946 foreach ($attrs as $k => $v) {
4947 if (preg_match(
'/^xmlns/', $k)) {
4948 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4949 $this->namespaces[$ns_prefix] = $v;
4951 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4953 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4954 $this->XMLSchemaVersion = $v;
4955 $this->namespaces[
'xsi'] = $v .
'-instance';
4960 foreach ($attrs as $k => $v) {
4961 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4962 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4963 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4972 if (preg_match(
'/:/', $name)) {
4974 $prefix = substr($name, 0, strpos($name,
':'));
4976 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4978 $name = substr(strstr($name,
':'), 1);
4982 switch ($this->status) {
4984 if ($name ==
'part') {
4985 if (isset($attrs[
'type'])) {
4986 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4987 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4989 if (isset($attrs[
'element'])) {
4990 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4991 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4998 $this->currentPortOperation = $attrs[
'name'];
4999 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
5000 if (isset($attrs[
'parameterOrder'])) {
5001 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
5004 case 'documentation':
5005 $this->documentation =
true;
5009 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
5010 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name][
'message'] = $m;
5018 if (isset($attrs[
'style'])) {
5019 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
5021 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
5024 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
5027 if (isset($attrs[
'soapAction'])) {
5028 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
5030 if (isset($attrs[
'style'])) {
5031 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
5033 if (isset($attrs[
'name'])) {
5034 $this->currentOperation = $attrs[
'name'];
5035 $this->
debug(
"current binding operation: $this->currentOperation");
5036 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
5037 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
5038 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
5042 $this->opStatus =
'input';
5045 $this->opStatus =
'output';
5048 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
5049 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
5051 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
5059 $this->currentPort = $attrs[
'name'];
5060 $this->
debug(
'current port: ' . $this->currentPort);
5061 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
5065 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
5066 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
5067 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
5068 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
5076 if (isset($attrs[
'location'])) {
5077 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
5078 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]) .
')');
5080 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
5082 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
5084 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - [no location] (' . count($this->
import[$attrs[
'namespace']]) .
')');
5092 $this->status =
'message';
5093 $this->messages[$attrs[
'name']] = array();
5094 $this->currentMessage = $attrs[
'name'];
5097 $this->status =
'portType';
5098 $this->portTypes[$attrs[
'name']] = array();
5099 $this->currentPortType = $attrs[
'name'];
5102 if (isset($attrs[
'name'])) {
5104 if (strpos($attrs[
'name'],
':')) {
5105 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
5107 $this->currentBinding = $attrs[
'name'];
5109 $this->status =
'binding';
5110 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
5111 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
5115 $this->serviceName = $attrs[
'name'];
5116 $this->status =
'service';
5117 $this->
debug(
'current service: ' . $this->serviceName);
5120 foreach ($attrs as $name => $value) {
5121 $this->wsdl_info[$name] = $value;
5135 public function end_element($parser, $name)
5138 if ( preg_match(
'/schema$/', $name)) {
5140 $this->
appendDebug($this->currentSchema->getDebug());
5141 $this->currentSchema->clearDebug();
5142 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5143 $this->
debug(
'Parsing WSDL schema done');
5145 if ($this->status ==
'schema') {
5146 $this->currentSchema->schemaEndElement($parser, $name);
5152 if ($this->documentation) {
5155 $this->documentation =
false;
5166 public function character_data($parser,
$data)
5168 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5169 if (isset($this->message[$pos][
'cdata'])) {
5170 $this->message[$pos][
'cdata'] .=
$data;
5172 if ($this->documentation) {
5173 $this->documentation .=
$data;
5186 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
5188 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5190 $this->username = $username;
5191 $this->password = $password;
5192 $this->authtype = $authtype;
5193 $this->certRequest = $certRequest;
5196 public function getBindingData($binding)
5198 if (is_array($this->bindings[$binding])) {
5199 return $this->bindings[$binding];
5210 public function getOperations($bindingType =
'soap')
5213 if ($bindingType ==
'soap') {
5214 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5215 } elseif ($bindingType ==
'soap12') {
5216 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5219 foreach ($this->ports as $port => $portData) {
5221 if ($portData[
'bindingType'] == $bindingType) {
5226 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5227 $ops = array_merge($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5242 public function getOperationData($operation, $bindingType =
'soap')
5244 if ($bindingType ==
'soap') {
5245 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5246 } elseif ($bindingType ==
'soap12') {
5247 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5250 foreach ($this->ports as $port => $portData) {
5252 if ($portData[
'bindingType'] == $bindingType) {
5255 foreach (array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5257 if ($operation == $bOperation) {
5258 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5274 public function getOperationDataForSoapAction($soapAction, $bindingType =
'soap')
5276 if ($bindingType ==
'soap') {
5277 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5278 } elseif ($bindingType ==
'soap12') {
5279 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5282 foreach ($this->ports as $port => $portData) {
5284 if ($portData[
'bindingType'] == $bindingType) {
5286 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5287 if ($opData[
'soapAction'] == $soapAction) {
5313 public function getTypeDef($type, $ns)
5315 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5316 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5317 $ns = $this->namespaces[
'tns'];
5318 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5320 if (!isset($this->schemas[$ns])) {
5321 foreach ($this->schemas as $ns0 => $schema0) {
5322 if (strcasecmp($ns, $ns0) == 0) {
5323 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5329 if (isset($this->schemas[$ns])) {
5330 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5331 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5332 $xs = &$this->schemas[$ns][$i];
5333 $t = $xs->getTypeDef($type);
5337 if (!isset($t[
'phpType'])) {
5339 $uqType = substr($t[
'type'], strrpos($t[
'type'],
':') + 1);
5340 $ns = substr($t[
'type'], 0, strrpos($t[
'type'],
':'));
5341 $etype = $this->getTypeDef($uqType, $ns);
5343 $this->
debug(
"found type for [element] $type:");
5345 if (isset($etype[
'phpType'])) {
5346 $t[
'phpType'] = $etype[
'phpType'];
5348 if (isset($etype[
'elements'])) {
5349 $t[
'elements'] = $etype[
'elements'];
5351 if (isset($etype[
'attrs'])) {
5352 $t[
'attrs'] = $etype[
'attrs'];
5360 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5370 public function webDescription()
5372 global $HTTP_SERVER_VARS;
5376 } elseif (isset($HTTP_SERVER_VARS)) {
5377 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5379 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5382 $PHP_SELF = htmlspecialchars($PHP_SELF, ENT_QUOTES | ENT_HTML5,
'UTF-8');
5386 <html><head><title>NuSOAP: ' . $this->serviceName .
'</title> 5387 <style type="text/css"> 5388 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5389 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5390 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5391 ul { margin-top: 10px; margin-left: 20px; } 5392 li { list-style-type: none; margin-top: 10px; color: #000000; } 5394 margin-left: 0px; padding-bottom: 2em; } 5396 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5397 margin-top: 10px; margin-left: 0px; color: #000000; 5398 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5400 font-family: arial; font-size: 26px; color: #ffffff; 5401 background-color: #999999; width: 105%; margin-left: 0px; 5402 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5404 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5405 font-family: arial; overflow: hidden; width: 600; 5406 padding: 20px; font-size: 10px; background-color: #999999; 5407 layer-background-color:#FFFFFF; } 5408 a,a:active { color: charcoal; font-weight: bold; } 5409 a:visited { color: #666666; font-weight: bold; } 5410 a:hover { color: cc3300; font-weight: bold; } 5412 <script language="JavaScript" type="text/javascript"> 5414 // POP-UP CAPTIONS... 5415 function lib_bwcheck(){ //Browsercheck (needed) 5416 this.ver=navigator.appVersion 5417 this.agent=navigator.userAgent 5418 this.dom=document.getElementById?1:0 5419 this.opera5=this.agent.indexOf("Opera 5")>-1 5420 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5421 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5422 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5423 this.ie=this.ie4||this.ie5||this.ie6 5424 this.mac=this.agent.indexOf("Mac")>-1 5425 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5426 this.ns4=(document.layers && !this.dom)?1:0; 5427 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5430 var bw = new lib_bwcheck() 5431 //Makes crossbrowser object. 5432 function makeObj(obj){ 5433 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5434 if(!this.evnt) return false 5435 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5436 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5437 this.writeIt=b_writeIt; 5440 // A unit of measure that will be added when setting the position of a layer. 5441 //var px = bw.ns4||window.opera?"":"px"; 5442 function b_writeIt(text){ 5443 if (bw.ns4){this.wref.write(text);this.wref.close()} 5444 else this.wref.innerHTML = text 5446 //Shows the messages 5448 function popup(divid){ 5449 if(oDesc = new makeObj(divid)){ 5450 oDesc.css.visibility = "visible" 5453 function popout(){ // Hides message 5454 if(oDesc) oDesc.css.visibility = "hidden" 5462 <div class=title>' . $this->serviceName .
'</div> 5464 <p>View the <a href="' . $PHP_SELF .
'?wsdl">WSDL</a> for the service. 5465 Click on an operation name to view it's details.</p> 5467 foreach ($this->getOperations() as $op =>
$data) {
5469 if (isset(
$data[
'endpoint'])) {
5470 $data[
'endpoint'] = htmlspecialchars(
$data[
'endpoint'], ENT_QUOTES | ENT_HTML5,
'UTF-8');
5473 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5475 $b .=
"<div id='$op' class='hidden'> 5476 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5477 foreach (
$data as $donnie => $marie) {
5478 if ($donnie ==
'input' || $donnie ==
'output') {
5479 $b .=
"<font color='white'>" . ucfirst($donnie) .
':</font><br>';
5480 foreach ($marie as $captain => $tenille) {
5481 if ($captain ==
'parts') {
5482 $b .=
" $captain:<br>";
5484 foreach ($tenille as $joanie => $chachi) {
5485 $b .=
" $joanie: $chachi<br>";
5489 $b .=
" $captain: $tenille<br>";
5493 $b .=
"<font color='white'>" . ucfirst($donnie) .
":</font> $marie<br>";
5501 </div></body></html>';
5514 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5515 $xml .=
"\n<definitions";
5516 foreach ($this->namespaces as $k => $v) {
5517 $xml .=
" xmlns:$k=\"$v\"";
5520 if (isset($this->namespaces[
'wsdl'])) {
5521 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5523 if (isset($this->namespaces[
'tns'])) {
5524 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5528 if (
sizeof($this->
import) > 0) {
5529 foreach ($this->
import as $ns => $list) {
5530 foreach ($list as $ii) {
5531 if ($ii[
'location'] !=
'') {
5532 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5534 $xml .=
'<import namespace="' . $ns .
'" />';
5540 if (count($this->schemas)>=1) {
5541 $xml .=
"\n<types>\n";
5542 foreach ($this->schemas as $ns => $list) {
5543 foreach ($list as $xs) {
5544 $xml .= $xs->serializeSchema();
5550 if (count($this->messages) >= 1) {
5551 foreach ($this->messages as $msgName => $msgParts) {
5552 $xml .=
"\n<message name=\"" . $msgName .
'">';
5553 if (is_array($msgParts)) {
5554 foreach ($msgParts as $partName => $partType) {
5556 if (strpos($partType,
':')) {
5558 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5560 $typePrefix =
'xsd';
5562 foreach ($this->typemap as $ns => $types) {
5563 if (isset($types[$partType])) {
5567 if (!isset($typePrefix)) {
5568 die(
"$partType has no namespace!");
5573 $typeDef = $this->getTypeDef($localPart, $ns);
5574 if (($typeDef[
'typeClass'] ??
'') ==
'element') {
5575 $elementortype =
'element';
5576 if (substr($localPart, -1) ==
'^') {
5577 $localPart = substr($localPart, 0, -1);
5580 $elementortype =
'type';
5582 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5585 $xml .=
'</message>';
5589 if (count($this->bindings) >= 1) {
5592 foreach ($this->bindings as $bindingName => $attrs) {
5593 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5594 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5595 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5596 foreach ($attrs[
'operations'] as $opName => $opParts) {
5597 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5598 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="' . $opParts[
'style'] .
'"/>';
5599 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5600 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5604 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5605 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5606 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5610 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5611 $binding_xml .=
"\n" .
' </operation>';
5612 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5613 if (isset($opParts[
'parameterOrder'])) {
5614 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5616 $portType_xml .=
'>';
5617 if (isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5618 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5620 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5621 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5622 $portType_xml .=
"\n" .
' </operation>';
5624 $portType_xml .=
"\n" .
'</portType>';
5625 $binding_xml .=
"\n" .
'</binding>';
5627 $xml .= $portType_xml . $binding_xml;
5630 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5631 $has_client = isset(
$_GET[
'client_id']);
5632 if (count($this->ports) >= 1) {
5633 foreach ($this->ports as $pName => $attrs) {
5634 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5635 $locations = $attrs[
'location'];
5636 $locations = is_array($locations) ? $locations : [$locations];
5638 $address = $location . ($debug || $has_client ?
"?" :
"")
5639 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5640 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5641 $xml .=
"\n" .
' <soap:address location="' . $address .
'"/>';
5643 $xml .=
"\n" .
' </port>';
5647 $xml .=
"\n" .
'</service>';
5648 return $xml .
"\n</definitions>";
5660 public function parametersMatchWrapped($type, &$parameters)
5662 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5666 if (strpos($type,
':')) {
5667 $uqType = substr($type, strrpos($type,
':') + 1);
5668 $ns = substr($type, 0, strrpos($type,
':'));
5669 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5672 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5677 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5683 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5684 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5687 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5689 if (substr($uqType, -1) ==
'^') {
5690 $uqType = substr($uqType, 0, -1);
5692 $phpType = $typeDef[
'phpType'];
5693 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5694 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5697 if ($phpType !=
'struct') {
5698 $this->
debug(
"in parametersMatchWrapped: not a struct");
5703 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5707 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5708 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5711 foreach ($typeDef[
'elements'] as $name => $attrs) {
5713 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5714 $parameters[$name] = $parameters[$elements];
5715 unset($parameters[$elements]);
5717 } elseif (isset($parameters[$name])) {
5718 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5721 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5726 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5727 if ($matches == 0) {
5735 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5736 return count($parameters) == 0;
5754 public function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap')
5756 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5759 if ($direction !=
'input' && $direction !=
'output') {
5760 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5761 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5764 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5765 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5766 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5769 $this->
debug(
'in serializeRPCParameters: opData:');
5773 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5774 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5775 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5776 $enc_style = $encodingStyle;
5781 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5782 $parts = &$opData[$direction][
'parts'];
5783 $part_count =
sizeof(
$parts);
5784 $style = $opData[
'style'];
5785 $use = $opData[$direction][
'use'];
5786 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5787 if (is_array($parameters)) {
5789 $parameter_count = count($parameters);
5790 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5792 if ($style ==
'document' && $use ==
'literal' && $part_count == 1 && isset(
$parts[
'parameters'])) {
5793 $this->
debug(
'check whether the caller has wrapped the parameters');
5794 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5795 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5796 if ($this->parametersMatchWrapped(
$parts[
'parameters'], $parameters)) {
5797 $this->
debug(
'wrap the parameters for the caller');
5798 $parameters = array(
'parameters' => $parameters);
5799 $parameter_count = 1;
5803 foreach (
$parts as $name => $type) {
5804 $this->
debug(
"serializing part $name of type $type");
5806 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5807 $encodingStyle = $opData[$direction][
'encodingStyle'];
5808 $enc_style = $encodingStyle;
5814 if ($parametersArrayType ==
'arraySimple') {
5815 $p = array_shift($parameters);
5816 $this->
debug(
'calling serializeType w/indexed param');
5817 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5818 } elseif (isset($parameters[$name])) {
5819 $this->
debug(
'calling serializeType w/named param');
5820 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5823 $this->
debug(
'calling serializeType w/null param');
5824 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5828 $this->
debug(
'no parameters passed.');
5831 $this->
debug(
"serializeRPCParameters returning: $xml");
5849 public function serializeParameters($operation, $direction, $parameters)
5851 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5854 if ($direction !=
'input' && $direction !=
'output') {
5855 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5856 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5859 if (!$opData = $this->getOperationData($operation)) {
5860 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5861 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5864 $this->
debug(
'opData:');
5868 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5869 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5870 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5871 $enc_style = $encodingStyle;
5876 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5877 $use = $opData[$direction][
'use'];
5878 $this->
debug(
"use=$use");
5879 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5880 if (is_array($parameters)) {
5882 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5883 foreach ($opData[$direction][
'parts'] as $name => $type) {
5884 $this->
debug(
'serializing part "' . $name .
'" of type "' . $type .
'"');
5886 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5887 $encodingStyle = $opData[$direction][
'encodingStyle'];
5888 $enc_style = $encodingStyle;
5894 if ($parametersArrayType ==
'arraySimple') {
5895 $p = array_shift($parameters);
5896 $this->
debug(
'calling serializeType w/indexed param');
5897 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5898 } elseif (isset($parameters[$name])) {
5899 $this->
debug(
'calling serializeType w/named param');
5900 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5903 $this->
debug(
'calling serializeType w/null param');
5904 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5908 $this->
debug(
'no parameters passed.');
5911 $this->
debug(
"serializeParameters returning: $xml");
5927 public function serializeType($name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5929 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5931 if ($use ==
'encoded' && $encodingStyle) {
5932 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5936 if (is_object($value) && get_class($value) ==
'soapval') {
5937 if ($value->type_ns) {
5938 $type = $value->type_ns .
':' . $value->type;
5940 $this->
debug(
"in serializeType: soapval overrides type to $type");
5941 } elseif ($value->type) {
5942 $type = $value->type;
5944 $this->
debug(
"in serializeType: soapval overrides type to $type");
5947 $this->
debug(
"in serializeType: soapval does not override type");
5949 $attrs = $value->attributes;
5950 $value = $value->value;
5951 $this->
debug(
"in serializeType: soapval overrides value to $value");
5953 if (!is_array($value)) {
5954 $value[
'!'] = $value;
5956 foreach ($attrs as $n => $v) {
5957 $value[
'!' . $n] = $v;
5959 $this->
debug(
"in serializeType: soapval provides attributes");
5966 if (strpos($type,
':')) {
5967 $uqType = substr($type, strrpos($type,
':') + 1);
5968 $ns = substr($type, 0, strrpos($type,
':'));
5969 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5972 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5975 if ($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/') {
5976 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5977 if ($unqualified && $use ==
'literal') {
5978 $elementNS =
" xmlns=\"\"";
5982 if (is_null($value)) {
5983 if ($use ==
'literal') {
5985 $xml =
"<$name$elementNS/>";
5988 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5990 $this->
debug(
"in serializeType: returning: $xml");
5993 if ($uqType ==
'Array') {
5995 return $this->
serialize_val($value, $name,
false,
false,
false,
false, $use);
5997 if ($uqType ==
'boolean') {
5998 if ((is_string($value) && $value ==
'false') || (! $value)) {
6004 if ($uqType ==
'string' && gettype($value) ==
'string') {
6007 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
6008 $value = sprintf(
"%.0lf", $value);
6013 if (!$this->getTypeDef($uqType, $ns)) {
6014 if ($use ==
'literal') {
6016 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6018 $xml =
"<$name$elementNS>$value</$name>";
6021 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6023 $this->
debug(
"in serializeType: returning: $xml");
6026 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
6027 } elseif ($ns ==
'http://xml.apache.org/xml-soap') {
6028 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
6029 if ($uqType ==
'Map') {
6032 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
6033 $tt_prefix =
'ns' . rand(1000, 9999);
6034 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
6039 foreach ($value as $k => $v) {
6040 $this->
debug(
"serializing map element: key $k, value $v");
6041 $contents .=
'<item>';
6042 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false, $use);
6043 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false, $use);
6044 $contents .=
'</item>';
6046 if ($use ==
'literal') {
6048 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
6050 $xml =
"<$name>$contents</$name>";
6053 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
6055 $this->
debug(
"in serializeType: returning: $xml");
6058 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
6063 $this->
debug(
"in serializeType: No namespace for type $type");
6067 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
6068 $this->
setError(
"$type ($uqType) is not a supported type.");
6069 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
6072 $this->
debug(
"in serializeType: found typeDef");
6074 if (substr($uqType, -1) ==
'^') {
6075 $uqType = substr($uqType, 0, -1);
6078 $phpType = $typeDef[
'phpType'];
6079 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
''));
6081 if ($phpType ==
'struct') {
6082 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
6083 $elementName = $uqType;
6084 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6085 $elementNS =
" xmlns=\"$ns\"";
6087 $elementNS =
" xmlns=\"\"";
6090 $elementName = $name;
6092 $elementNS =
" xmlns=\"\"";
6097 if (is_null($value)) {
6098 if ($use ==
'literal') {
6100 $xml =
"<$elementName$elementNS/>";
6102 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
6104 $this->
debug(
"in serializeType: returning: $xml");
6107 if (is_object($value)) {
6108 $value = get_object_vars($value);
6110 if (is_array($value)) {
6111 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6112 if ($use ==
'literal') {
6114 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
6116 $xml =
"<$elementName$elementNS$elementAttrs>";
6119 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
6122 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6123 $xml .=
"</$elementName>";
6125 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
6126 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
6129 } elseif ($phpType ==
'array') {
6130 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6131 $elementNS =
" xmlns=\"$ns\"";
6134 $elementNS =
" xmlns=\"\"";
6139 if (is_null($value)) {
6140 if ($use ==
'literal') {
6142 $xml =
"<$name$elementNS/>";
6144 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6151 $this->
getLocalPart($typeDef[
'arrayType']) .
"[0]\"/>";
6153 $this->
debug(
"in serializeType: returning: $xml");
6156 if (isset($typeDef[
'multidimensional'])) {
6158 foreach ($value as $v) {
6159 $cols =
',' .
sizeof($v);
6160 $nv = array_merge($nv, $v);
6166 if (is_array($value) &&
sizeof($value) >= 1) {
6167 $rows =
sizeof($value);
6169 foreach ($value as $k => $v) {
6170 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6172 if (!in_array($typeDef[
'arrayType'], $this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6173 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6175 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6184 if ($use ==
'literal') {
6185 $xml =
"<$name$elementNS>" 6189 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/') .
':Array" ' .
6193 .
":" . $this->
getLocalPart($typeDef[
'arrayType']) .
"[$rows$cols]\">" 6197 } elseif ($phpType ==
'scalar') {
6198 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6199 $elementNS =
" xmlns=\"$ns\"";
6202 $elementNS =
" xmlns=\"\"";
6207 if ($use ==
'literal') {
6209 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6211 $xml =
"<$name$elementNS>$value</$name>";
6214 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6217 $this->
debug(
"in serializeType: returning: $xml");
6231 public function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
6234 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6235 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6236 if (is_array($value)) {
6238 } elseif (is_object($value)) {
6239 $xvalue = get_object_vars($value);
6241 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6244 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6245 if (isset($xvalue[
'!' . $aName])) {
6246 $xname =
'!' . $aName;
6247 $this->
debug(
"value provided for attribute $aName with key $xname");
6248 } elseif (isset($xvalue[$aName])) {
6250 $this->
debug(
"value provided for attribute $aName with key $xname");
6251 } elseif (isset($attrs[
'default'])) {
6252 $xname =
'!' . $aName;
6253 $xvalue[$xname] = $attrs[
'default'];
6254 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6257 $this->
debug(
"no value provided for attribute $aName");
6260 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6264 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6266 if (isset($typeDef[
'extensionBase'])) {
6267 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6268 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6272 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6273 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6274 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6276 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6294 public function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false)
6297 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6298 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6299 if (is_array($value)) {
6301 } elseif (is_object($value)) {
6302 $xvalue = get_object_vars($value);
6304 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6308 if (count($typeDef[
'elements']) != count($xvalue)) {
6311 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6312 if (!isset($xvalue[$eName])) {
6313 if (isset($attrs[
'default'])) {
6314 $xvalue[$eName] = $attrs[
'default'];
6315 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6319 if (isset($optionals)
6320 && (!isset($xvalue[$eName]))
6321 && ((!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6323 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6324 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6327 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6330 if (isset($xvalue[$eName])) {
6331 $v = $xvalue[$eName];
6335 if (isset($attrs[
'form'])) {
6336 $unqualified = ($attrs[
'form'] ==
'unqualified');
6338 $unqualified =
false;
6340 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6342 foreach ($vv as $k => $v) {
6343 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6345 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6348 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6349 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6353 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6355 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6358 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6359 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6365 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6367 if (isset($typeDef[
'extensionBase'])) {
6368 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6369 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6373 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6374 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6375 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6377 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6397 public function addComplexType($name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
6399 if (count($elements) > 0) {
6400 $eElements = array();
6401 foreach ($elements as $n =>
$e) {
6404 foreach (
$e as $k => $v) {
6405 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6406 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6409 $eElements[$n] = $ee;
6411 $elements = $eElements;
6414 if (count($attrs) > 0) {
6415 foreach ($attrs as $n =>
$a) {
6417 foreach (
$a as $k => $v) {
6418 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6419 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6427 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6428 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6430 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6431 $this->schemas[$typens][0]->addComplexType($name, $typeClass, $phpType, $compositor, $restrictionBase, $elements, $attrs, $arrayType);
6445 public function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
6447 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6449 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6450 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6460 public function addElement($attrs)
6462 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6463 $this->schemas[$typens][0]->addElement($attrs);
6480 public function addOperation($name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false, $style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
'')
6482 if ($use ==
'encoded' && $encodingStyle ==
'') {
6483 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6486 if ($style ==
'document') {
6487 $elements = array();
6488 foreach ($in as $n => $t) {
6489 $elements[$n] = array(
'name' => $n,
'type' => $t);
6491 $this->addComplexType($name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6492 $this->addElement(array(
'name' => $name,
'type' => $name .
'RequestType'));
6493 $in = array(
'parameters' =>
'tns:' . $name .
'^');
6495 $elements = array();
6496 foreach (
$out as $n => $t) {
6497 $elements[$n] = array(
'name' => $n,
'type' => $t);
6499 $this->addComplexType($name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6500 $this->addElement(array(
'name' => $name .
'Response',
'type' => $name .
'ResponseType',
'form' =>
'qualified'));
6501 $out = array(
'parameters' =>
'tns:' . $name .
'Response' .
'^');
6505 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][$name] =
6508 'binding' => $this->serviceName .
'Binding',
6509 'endpoint' => $this->endpoint,
6510 'soapAction' => $soapaction,
6515 'encodingStyle' => $encodingStyle,
6516 'message' => $name .
'Request',
6521 'encodingStyle' => $encodingStyle,
6522 'message' => $name .
'Response',
6525 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6526 'documentation' => $documentation);
6530 foreach ($in as $pName => $pType) {
6531 if (strpos($pType,
':')) {
6534 $this->messages[$name .
'Request'][$pName] = $pType;
6537 $this->messages[$name .
'Request']=
'0';
6540 foreach (
$out as $pName => $pType) {
6541 if (strpos($pType,
':')) {
6544 $this->messages[$name .
'Response'][$pName] = $pType;
6547 $this->messages[$name .
'Response']=
'0';
6567 public $methodNamespace;
6570 public $xml_encoding =
'';
6571 public $method =
'';
6572 public $root_struct =
'';
6573 public $root_struct_name =
'';
6574 public $root_struct_namespace =
'';
6575 public $root_header =
'';
6576 public $document =
'';
6578 public $status =
'';
6579 public $position = 0;
6581 public $default_namespace =
'';
6583 public $message = array();
6584 public $parent =
'';
6585 public $fault =
false;
6586 public $fault_code =
'';
6587 public $fault_str =
'';
6588 public $fault_detail =
'';
6589 public $depth_array = array();
6590 public $debug_flag =
true;
6591 public $soapresponse = null;
6592 public $soapheader = null;
6593 public $responseHeaders =
'';
6594 public $body_position = 0;
6597 public $ids = array();
6599 public $multirefs = array();
6601 public $decode_utf8 =
true;
6612 public function __construct($xml, $encoding=
'UTF-8', $method=
'', $decode_utf8=
true)
6616 $this->xml_encoding = $encoding;
6617 $this->method = $method;
6618 $this->decode_utf8 = $decode_utf8;
6623 $pos_xml = strpos($xml,
'<?xml');
6624 if ($pos_xml !==
false) {
6625 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6626 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6627 $xml_encoding =
$res[1];
6628 if (strtoupper($xml_encoding) != $encoding) {
6629 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6631 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6637 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6640 $this->
debug(
'No encoding specified in XML declaration');
6643 $this->
debug(
'No XML declaration');
6645 $this->
debug(
'Entering nusoap_parser(), length=' . strlen($xml) .
', encoding=' . $encoding);
6647 $this->parser = xml_parser_create($this->xml_encoding);
6650 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6651 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6653 xml_set_object($this->parser, $this);
6655 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6656 xml_set_character_data_handler($this->parser,
'character_data');
6659 if (!xml_parse($this->parser, $xml,
true)) {
6662 'XML error parsing SOAP payload on line %d: %s',
6663 xml_get_current_line_number($this->parser),
6664 xml_error_string(xml_get_error_code($this->parser))
6667 $this->
debug(
"XML payload:\n" . $xml);
6670 $this->
debug(
'parsed successfully, found root struct: ' . $this->root_struct .
' of name ' . $this->root_struct_name);
6672 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6674 if ($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])) {
6675 $this->soapheader = $this->message[$this->root_header][
'result'];
6678 if (
sizeof($this->multirefs) > 0) {
6679 foreach ($this->multirefs as
$id => $hrefs) {
6680 $this->
debug(
'resolving multirefs for id: ' .
$id);
6681 $idVal = $this->buildVal($this->ids[
$id]);
6682 if (is_array($idVal) && isset($idVal[
'!id'])) {
6683 unset($idVal[
'!id']);
6685 foreach ($hrefs as $refPos => $ref) {
6686 $this->
debug(
'resolving href at pos ' . $refPos);
6687 $this->multirefs[
$id][$refPos] = $idVal;
6692 xml_parser_free($this->parser);
6694 $this->
debug(
'xml was empty, didn\'t parse!');
6695 $this->
setError(
'xml was empty, didn\'t parse!');
6707 public function start_element($parser, $name, $attrs)
6711 $pos = $this->position++;
6713 $this->message[$pos] = array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6716 $this->message[$pos][
'depth'] = $this->depth++;
6720 $this->message[$this->parent][
'children'] .=
'|' . $pos;
6723 $this->message[$pos][
'parent'] = $this->parent;
6725 $this->parent = $pos;
6727 $this->depth_array[$this->depth] = $pos;
6729 if (strpos($name,
':')) {
6731 $prefix = substr($name, 0, strpos($name,
':'));
6733 $name = substr(strstr($name,
':'), 1);
6736 if ($name ==
'Envelope') {
6737 $this->status =
'envelope';
6738 } elseif ($name ==
'Header' && $this->status =
'envelope') {
6739 $this->root_header = $pos;
6740 $this->status =
'header';
6741 } elseif ($name ==
'Body' && $this->status =
'envelope') {
6742 $this->status =
'body';
6743 $this->body_position = $pos;
6745 } elseif ($this->status ==
'body' && $pos == ($this->body_position+1)) {
6746 $this->status =
'method';
6747 $this->root_struct_name = $name;
6748 $this->root_struct = $pos;
6749 $this->message[$pos][
'type'] =
'struct';
6750 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6753 $this->message[$pos][
'status'] = $this->status;
6755 $this->message[$pos][
'name'] = htmlspecialchars($name);
6757 $this->message[$pos][
'attrs'] = $attrs;
6761 foreach ($attrs as $key => $value) {
6765 if ($key_prefix ==
'xmlns') {
6766 if (preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/', $value)) {
6767 $this->XMLSchemaVersion = $value;
6769 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion .
'-instance';
6771 $this->namespaces[$key_localpart] = $value;
6773 if ($name == $this->root_struct_name) {
6774 $this->methodNamespace = $value;
6777 } elseif ($key_localpart ==
'type') {
6778 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6781 $value_prefix = $this->
getPrefix($value);
6783 $this->message[$pos][
'type'] = $value_localpart;
6784 $this->message[$pos][
'typePrefix'] = $value_prefix;
6785 if (isset($this->namespaces[$value_prefix])) {
6786 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6787 } elseif (isset($attrs[
'xmlns:' . $value_prefix])) {
6788 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:' . $value_prefix];
6792 } elseif ($key_localpart ==
'arrayType') {
6793 $this->message[$pos][
'type'] =
'array';
6802 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6803 if (preg_match($expr, $value, $regs)) {
6804 $this->message[$pos][
'typePrefix'] = $regs[1];
6805 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6806 if (isset($this->namespaces[$regs[1]])) {
6807 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6808 } elseif (isset($attrs[
'xmlns:' . $regs[1]])) {
6809 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:' . $regs[1]];
6811 $this->message[$pos][
'arrayType'] = $regs[2];
6812 $this->message[$pos][
'arraySize'] = $regs[3];
6813 $this->message[$pos][
'arrayCols'] = $regs[4];
6816 } elseif ($key_localpart ==
'nil') {
6817 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6819 } elseif ($key !=
'href' && $key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6820 $this->message[$pos][
'xattrs'][
'!' . $key] = $value;
6823 if ($key ==
'xmlns') {
6824 $this->default_namespace = $value;
6828 $this->ids[$value] = $pos;
6831 if ($key_localpart ==
'root' && $value == 1) {
6832 $this->status =
'method';
6833 $this->root_struct_name = $name;
6834 $this->root_struct = $pos;
6835 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6838 $attstr .=
" $key=\"$value\"";
6841 if (isset($prefix)) {
6842 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6843 $this->default_namespace = $this->namespaces[$prefix];
6845 $this->message[$pos][
'namespace'] = $this->default_namespace;
6847 if ($this->status ==
'header') {
6848 if ($this->root_header != $pos) {
6849 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6851 } elseif ($this->root_struct_name !=
'') {
6852 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6863 public function end_element($parser, $name)
6866 $pos = $this->depth_array[$this->depth--];
6869 if (strpos($name,
':')) {
6871 $prefix = substr($name, 0, strpos($name,
':'));
6873 $name = substr(strstr($name,
':'), 1);
6877 if (isset($this->body_position) && $pos > $this->body_position) {
6879 if (isset($this->message[$pos][
'attrs'][
'href'])) {
6881 $id = substr($this->message[$pos][
'attrs'][
'href'], 1);
6883 $this->multirefs[
$id][$pos] =
'placeholder';
6885 $this->message[$pos][
'result'] =& $this->multirefs[
$id][$pos];
6887 } elseif ($this->message[$pos][
'children'] !=
'') {
6889 if (!isset($this->message[$pos][
'result'])) {
6890 $this->message[$pos][
'result'] = $this->buildVal($pos);
6893 } elseif (isset($this->message[$pos][
'xattrs'])) {
6894 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6895 $this->message[$pos][
'xattrs'][
'!'] = null;
6896 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6897 if (isset($this->message[$pos][
'type'])) {
6898 $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'] :
'');
6900 $parent = $this->message[$pos][
'parent'];
6901 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6902 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6904 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6908 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6912 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6913 $this->message[$pos][
'xattrs'][
'!'] = null;
6914 } elseif (isset($this->message[$pos][
'type'])) {
6915 $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'] :
'');
6917 $parent = $this->message[$pos][
'parent'];
6918 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6919 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6921 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6939 if ($this->status ==
'header') {
6940 if ($this->root_header != $pos) {
6941 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6943 } elseif ($pos >= $this->root_struct) {
6944 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6947 if ($pos == $this->root_struct) {
6948 $this->status =
'body';
6949 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6950 } elseif ($name ==
'Body') {
6951 $this->status =
'envelope';
6952 } elseif ($name ==
'Header') {
6953 $this->status =
'envelope';
6954 } elseif ($name ==
'Envelope') {
6958 $this->parent = $this->message[$pos][
'parent'];
6968 public function character_data($parser,
$data)
6970 $pos = $this->depth_array[$this->depth];
6971 if ($this->xml_encoding==
'UTF-8') {
6975 if ($this->decode_utf8) {
6979 $this->message[$pos][
'cdata'] .=
$data;
6981 if ($this->status ==
'header') {
6982 $this->responseHeaders .=
$data;
6984 $this->document .=
$data;
6995 public function get_response()
6997 return $this->soapresponse;
7006 public function get_soapbody()
7008 return $this->soapresponse;
7017 public function get_soapheader()
7019 return $this->soapheader;
7028 public function getHeaders()
7030 return $this->responseHeaders;
7042 public function decodeSimple($value, $type, $typens)
7045 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
7046 return (
string) $value;
7048 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
7049 return (
int) $value;
7051 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
7052 return (
float) $value;
7054 if ($type ==
'boolean') {
7055 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
7058 return (
bool) $value;
7060 if ($type ==
'base64' || $type ==
'base64Binary') {
7061 $this->
debug(
'Decode base64 value');
7062 return base64_decode($value);
7065 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 7066 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 7067 || $type ==
'unsignedInt' 7068 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
7069 return (
int) $value;
7072 if ($type ==
'array') {
7076 return (
string) $value;
7087 public function buildVal($pos)
7089 if (!isset($this->message[$pos][
'type'])) {
7090 $this->message[$pos][
'type'] =
'';
7092 $this->
debug(
'in buildVal() for ' . $this->message[$pos][
'name'] .
"(pos $pos) of type " . $this->message[$pos][
'type']);
7094 if ($this->message[$pos][
'children'] !=
'') {
7095 $this->
debug(
'in buildVal, there are children');
7096 $children = explode(
'|', $this->message[$pos][
'children']);
7097 array_shift($children);
7099 if (isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
'') {
7102 foreach ($children as $child_pos) {
7103 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
7104 $params[
$r][] = $this->message[$child_pos][
'result'];
7106 if (
$c == $this->message[$pos][
'arrayCols']) {
7112 } elseif ($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array') {
7113 $this->
debug(
'in buildVal, adding array ' . $this->message[$pos][
'name']);
7114 foreach ($children as $child_pos) {
7115 $params[] = &$this->message[$child_pos][
'result'];
7118 } elseif ($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7119 $this->
debug(
'in buildVal, Java Map ' . $this->message[$pos][
'name']);
7120 foreach ($children as $child_pos) {
7121 $kv = explode(
"|", $this->message[$child_pos][
'children']);
7122 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
7128 $this->
debug(
'in buildVal, adding Java Vector or generic compound type ' . $this->message[$pos][
'name']);
7129 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7135 foreach ($children as $child_pos) {
7137 $params[] = &$this->message[$child_pos][
'result'];
7139 if (isset(
$params[$this->message[$child_pos][
'name']])) {
7141 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
7142 $params[$this->message[$child_pos][
'name']] = array(
$params[$this->message[$child_pos][
'name']]);
7144 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
7146 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
7151 if (isset($this->message[$pos][
'xattrs'])) {
7152 $this->
debug(
'in buildVal, handling attributes');
7153 foreach ($this->message[$pos][
'xattrs'] as $n => $v) {
7158 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7159 $this->
debug(
'in buildVal, handling simpleContent');
7160 if (isset($this->message[$pos][
'type'])) {
7161 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7163 $parent = $this->message[$pos][
'parent'];
7164 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7165 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7167 $params[
'!'] = $this->message[$pos][
'cdata'];
7172 $this->
debug(
'in buildVal, return:');
7176 $this->
debug(
'in buildVal, no children, building scalar');
7177 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7178 if (isset($this->message[$pos][
'type'])) {
7179 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7180 $this->
debug(
"in buildVal, return: $ret");
7183 $parent = $this->message[$pos][
'parent'];
7184 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7185 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7186 $this->
debug(
"in buildVal, return: $ret");
7189 $ret = $this->message[$pos][
'cdata'];
7190 $this->
debug(
"in buildVal, return: $ret");
7234 public $username =
'';
7235 public $password =
'';
7236 public $authtype =
'';
7237 public $certRequest = array();
7238 public $requestHeaders =
false;
7239 public $responseHeaders =
'';
7240 public $responseHeader = null;
7241 public $document =
'';
7243 public $forceEndpoint =
'';
7244 public $proxyhost =
'';
7245 public $proxyport =
'';
7246 public $proxyusername =
'';
7247 public $proxypassword =
'';
7248 public $xml_encoding =
'';
7249 public $http_encoding =
false;
7250 public $timeout = 0;
7251 public $response_timeout = 30;
7252 public $endpointType =
'';
7253 public $persistentConnection =
false;
7254 public $defaultRpcParams =
false;
7255 public $request =
'';
7258 public $cookies = array();
7259 public $decode_utf8 =
true;
7260 public $operations = array();
7261 public $curl_options = array();
7262 public $bindingType =
'';
7263 public $use_curl =
false;
7303 public function __construct($endpoint, $wsdl =
false, $proxyhost =
false, $proxyport =
false, $proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30)
7306 $this->endpoint = $endpoint;
7307 $this->proxyhost = $proxyhost;
7308 $this->proxyport = $proxyport;
7309 $this->proxyusername = $proxyusername;
7310 $this->proxypassword = $proxypassword;
7311 $this->timeout = $timeout;
7312 $this->response_timeout = $response_timeout;
7314 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7319 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7320 $this->
wsdl = $endpoint;
7321 $this->endpoint = $this->
wsdl->wsdl;
7322 $this->wsdlFile = $this->endpoint;
7323 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7326 $this->wsdlFile = $this->endpoint;
7328 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7330 $this->endpointType =
'wsdl';
7332 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7333 $this->endpointType =
'soap';
7362 public function call($operation,
$params=array(),
$namespace=
'http://tempuri.org', $soapAction=
'', $headers=
false, $rpcParams=null, $style=
'rpc', $use=
'encoded')
7364 $this->operation = $operation;
7365 $this->fault =
false;
7367 $this->request =
'';
7368 $this->response =
'';
7369 $this->responseData =
'';
7370 $this->faultstring =
'';
7371 $this->faultcode =
'';
7372 $this->opData = array();
7374 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7378 $this->requestHeaders = $headers;
7380 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7387 if ($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)) {
7389 $this->opData = $opData;
7390 $this->
debug(
"found operation");
7392 if (isset($opData[
'soapAction'])) {
7393 $soapAction = $opData[
'soapAction'];
7395 if (! $this->forceEndpoint) {
7396 $this->endpoint = $opData[
'endpoint'];
7398 $this->endpoint = $this->forceEndpoint;
7400 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7401 $style = $opData[
'style'];
7402 $use = $opData[
'input'][
'use'];
7405 $nsPrefix =
'ns' . rand(1000, 9999);
7411 $this->
debug(
"serializing param string for WSDL operation $operation");
7413 } elseif (is_array(
$params)) {
7414 $this->
debug(
"serializing param array for WSDL operation $operation");
7417 $this->
debug(
'params must be array or string');
7418 $this->
setError(
'params must be array or string');
7422 if (isset($opData[
'input'][
'encodingStyle'])) {
7423 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7425 $encodingStyle =
'';
7430 $this->
debug(
'got wsdl error: ' . $errstr);
7431 $this->
setError(
'wsdl error: ' . $errstr);
7434 } elseif ($this->endpointType ==
'wsdl') {
7438 $this->
setError(
'operation ' . $operation .
' not present.');
7439 $this->
debug(
"operation '$operation' not present.");
7444 $nsPrefix =
'ns' . rand(1000, 9999);
7448 $this->
debug(
"serializing param string for operation $operation");
7450 } elseif (is_array(
$params)) {
7451 $this->
debug(
"serializing param array for operation $operation");
7452 foreach (
$params as $k => $v) {
7456 $this->
debug(
'params must be array or string');
7457 $this->
setError(
'params must be array or string');
7461 if ($use ==
'encoded') {
7462 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7464 $encodingStyle =
'';
7468 if ($style ==
'rpc') {
7469 if ($use ==
'literal') {
7470 $this->
debug(
"wrapping RPC request with literal method element");
7473 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7475 "</$nsPrefix:$operation>";
7480 $this->
debug(
"wrapping RPC request with encoded method element");
7482 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7484 "</$nsPrefix:$operation>";
7494 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7495 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7497 $return = $this->
send($this->getHTTPBody($soapmsg), $soapAction, $this->timeout, $this->response_timeout);
7499 $this->
debug(
'Error: ' . $errstr);
7502 $this->
return = $return;
7503 $this->
debug(
'sent message successfully and got a(n) ' . gettype($return));
7507 if (is_array($return) && isset($return[
'faultcode'])) {
7508 $this->
debug(
'got fault');
7509 $this->
setError($return[
'faultcode'] .
': ' . $return[
'faultstring']);
7510 $this->fault =
true;
7511 foreach ($return as $k => $v) {
7513 $this->
debug(
"$k = $v<br>");
7516 } elseif ($style ==
'document') {
7522 if (is_array($return)) {
7525 if (
sizeof($return) > 1) {
7529 $return = array_shift($return);
7530 $this->
debug(
'return shifted value: ');
7546 public function checkWSDL()
7550 $this->
debug(
'checkWSDL');
7553 $this->
debug(
'got wsdl error: ' . $errstr);
7554 $this->
setError(
'wsdl error: ' . $errstr);
7556 $this->bindingType =
'soap';
7557 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7559 $this->bindingType =
'soap12';
7560 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7561 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7563 $this->
debug(
'getOperations returned false');
7564 $this->
setError(
'no operations defined in the WSDL document!');
7573 public function loadWSDL()
7575 $this->
debug(
'instantiating wsdl class with doc: ' . $this->wsdlFile);
7576 $this->
wsdl =
new wsdl(
'', $this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword, $this->timeout, $this->response_timeout, $this->curl_options, $this->use_curl);
7577 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7589 public function getOperationData($operation)
7591 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7597 if (isset($this->operations[$operation])) {
7598 return $this->operations[$operation];
7600 $this->
debug(
"No data for operation: $operation");
7617 public function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30)
7619 $this->checkCookies();
7623 case preg_match(
'/^http/', $this->endpoint):
7624 $this->
debug(
'transporting via HTTP');
7625 if ($this->persistentConnection ==
true && is_object($this->persistentConnection)) {
7626 $http =& $this->persistentConnection;
7629 if ($this->persistentConnection) {
7630 $http->usePersistentConnection();
7633 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7634 $http->setSOAPAction($soapaction);
7635 if ($this->proxyhost && $this->proxyport) {
7636 $http->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
7638 if ($this->authtype !=
'') {
7639 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7641 if ($this->http_encoding !=
'') {
7642 $http->setEncoding($this->http_encoding);
7644 $this->
debug(
'sending message, length=' . strlen($msg));
7645 if (preg_match(
'/^http:/', $this->endpoint)) {
7647 $this->responseData =
$http->send($msg, $timeout, $response_timeout, $this->cookies);
7648 } elseif (preg_match(
'/^https/', $this->endpoint)) {
7655 $this->responseData =
$http->sendHTTPS($msg, $timeout, $response_timeout, $this->cookies);
7657 $this->
setError(
'no http/s in endpoint url');
7659 $this->request =
$http->outgoing_payload;
7660 $this->response =
$http->incoming_payload;
7662 $this->UpdateCookies(
$http->incoming_cookies);
7665 if ($this->persistentConnection) {
7666 $http->clearDebug();
7667 if (!is_object($this->persistentConnection)) {
7668 $this->persistentConnection =
$http;
7672 if ($err =
$http->getError()) {
7673 $this->
setError(
'HTTP Error: ' . $err);
7678 $this->
debug(
'got response, length=' . strlen($this->responseData) .
' type=' .
$http->incoming_headers[
'content-type']);
7679 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7683 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7697 public function parseResponse($headers,
$data)
7699 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7701 if (!strstr($headers[
'content-type'],
'text/xml')) {
7702 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7705 if (strpos($headers[
'content-type'],
'=')) {
7706 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7707 $this->
debug(
'Got response encoding: ' . $enc);
7708 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
7709 $this->xml_encoding = strtoupper($enc);
7711 $this->xml_encoding =
'US-ASCII';
7715 $this->xml_encoding =
'ISO-8859-1';
7717 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7718 $parser =
new nusoap_parser(
$data, $this->xml_encoding, $this->operation, $this->decode_utf8);
7722 if ($errstr = $parser->getError()) {
7729 $this->responseHeaders = $parser->getHeaders();
7731 $this->responseHeader = $parser->get_soapheader();
7733 $return = $parser->get_soapbody();
7735 $this->document = $parser->document;
7750 public function setCurlOption($option, $value)
7752 $this->
debug(
"setCurlOption option=$option, value=");
7754 $this->curl_options[$option] = $value;
7763 public function setEndpoint($endpoint)
7765 $this->
debug(
"setEndpoint(\"$endpoint\")");
7766 $this->forceEndpoint = $endpoint;
7775 public function setHeaders($headers)
7777 $this->
debug(
"setHeaders headers=");
7779 $this->requestHeaders = $headers;
7788 public function getHeaders()
7790 return $this->responseHeaders;
7799 public function getHeader()
7801 return $this->responseHeader;
7813 public function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'')
7815 $this->proxyhost = $proxyhost;
7816 $this->proxyport = $proxyport;
7817 $this->proxyusername = $proxyusername;
7818 $this->proxypassword = $proxypassword;
7830 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
7832 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7834 $this->username = $username;
7835 $this->password = $password;
7836 $this->authtype = $authtype;
7837 $this->certRequest = $certRequest;
7846 public function setHTTPEncoding($enc=
'gzip, deflate')
7848 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7849 $this->http_encoding = $enc;
7858 public function setUseCURL($use)
7860 $this->
debug(
"setUseCURL($use)");
7861 $this->use_curl = $use;
7869 public function useHTTPPersistentConnection()
7871 $this->
debug(
"useHTTPPersistentConnection");
7872 $this->persistentConnection =
true;
7886 public function getDefaultRpcParams()
7888 return $this->defaultRpcParams;
7902 public function setDefaultRpcParams($rpcParams)
7904 $this->defaultRpcParams = $rpcParams;
7914 public function getProxy()
7917 $evalStr = $this->_getProxyClassCode(
$r);
7920 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7926 eval(
"\$proxy = new nusoap_proxy_$r('');");
7928 $proxy->endpointType =
'wsdl';
7929 $proxy->wsdlFile = $this->wsdlFile;
7930 $proxy->wsdl = $this->wsdl;
7931 $proxy->operations = $this->operations;
7932 $proxy->defaultRpcParams = $this->defaultRpcParams;
7935 $proxy->username = $this->username;
7936 $proxy->password = $this->password;
7937 $proxy->authtype = $this->authtype;
7938 $proxy->certRequest = $this->certRequest;
7939 $proxy->requestHeaders = $this->requestHeaders;
7940 $proxy->endpoint = $this->endpoint;
7941 $proxy->forceEndpoint = $this->forceEndpoint;
7942 $proxy->proxyhost = $this->proxyhost;
7943 $proxy->proxyport = $this->proxyport;
7944 $proxy->proxyusername = $this->proxyusername;
7945 $proxy->proxypassword = $this->proxypassword;
7946 $proxy->http_encoding = $this->http_encoding;
7947 $proxy->timeout = $this->timeout;
7948 $proxy->response_timeout = $this->response_timeout;
7949 $proxy->persistentConnection = &$this->persistentConnection;
7950 $proxy->decode_utf8 = $this->decode_utf8;
7951 $proxy->curl_options = $this->curl_options;
7952 $proxy->bindingType = $this->bindingType;
7953 $proxy->use_curl = $this->use_curl;
7963 public function _getProxyClassCode(
$r)
7965 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7967 if ($this->endpointType !=
'wsdl') {
7968 $evalStr =
'A proxy can only be created for a WSDL client';
7970 $evalStr =
"echo \"$evalStr\";";
7973 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7976 return "echo \"" . $this->
getError() .
"\";";
7980 foreach ($this->operations as $operation => $opData) {
7981 if ($operation !=
'') {
7983 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7985 $paramArrayStr =
'';
7986 $paramCommentStr =
'';
7987 foreach ($opData[
'input'][
'parts'] as $name => $type) {
7988 $paramStr .=
"\$$name, ";
7989 $paramArrayStr .=
"'$name' => \$$name, ";
7990 $paramCommentStr .=
"$type \$$name, ";
7992 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7993 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7994 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7997 $paramArrayStr =
'';
7998 $paramCommentStr =
'void';
8000 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
8001 $evalStr .=
"// $paramCommentStr 8002 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 8003 \$params = array($paramArrayStr); 8004 return \$this->call('$operation', \$params, '" . $opData[
'namespace'] .
"', '" . (isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'') .
"'); 8008 unset($paramCommentStr);
8011 $evalStr =
'class nusoap_proxy_' .
$r .
' extends nusoap_client { 8023 public function getProxyClassCode()
8026 return $this->_getProxyClassCode(
$r);
8036 public function getHTTPBody($soapmsg)
8049 public function getHTTPContentType()
8063 public function getHTTPContentTypeCharset()
8074 public function decodeUTF8($bool)
8076 $this->decode_utf8 = $bool;
8088 public function setCookie($name, $value)
8090 if (strlen($name) == 0) {
8093 $this->cookies[] = array(
'name' => $name,
'value' => $value);
8103 public function getCookies()
8105 return $this->cookies;
8114 public function checkCookies()
8116 if (
sizeof($this->cookies) == 0) {
8119 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
8120 $curr_cookies = $this->cookies;
8121 $this->cookies = array();
8122 foreach ($curr_cookies as $cookie) {
8123 if (! is_array($cookie)) {
8124 $this->
debug(
'Remove cookie that is not an array');
8127 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
8128 if (strtotime($cookie[
'expires']) > time()) {
8129 $this->cookies[] = $cookie;
8131 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
8134 $this->cookies[] = $cookie;
8137 $this->
debug(
'checkCookie: ' .
sizeof($this->cookies) .
' cookies left in array');
8148 public function UpdateCookies($cookies)
8150 if (
sizeof($this->cookies) == 0) {
8152 if (
sizeof($cookies) > 0) {
8153 $this->
debug(
'Setting new cookie(s)');
8154 $this->cookies = $cookies;
8158 if (
sizeof($cookies) == 0) {
8163 foreach ($cookies as $newCookie) {
8164 if (!is_array($newCookie)) {
8167 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
8170 $newName = $newCookie[
'name'];
8173 for ($i = 0; $i < count($this->cookies); $i++) {
8174 $cookie = $this->cookies[$i];
8175 if (!is_array($cookie)) {
8178 if (!isset($cookie[
'name'])) {
8181 if ($newName != $cookie[
'name']) {
8184 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
8185 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
8186 if ($newDomain != $domain) {
8189 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
8190 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
8191 if ($newPath !=
$path) {
8194 $this->cookies[$i] = $newCookie;
8196 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8200 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8201 $this->cookies[] = $newCookie;
8208 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
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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
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)