For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
1014 $start = gettimeofday();
1017 $stop = gettimeofday();
1018 $timePassed = 1000000 * ($stop[
'sec'] - $start[
'sec'])
1019 + $stop[
'usec'] - $start[
'usec'];
1020 }
while ($timePassed < $usec);
1088 foreach ($this->namespaces as $k => $v) {
1089 $ns_string .=
"\n xmlns:$k=\"$v\"";
1092 '<?xml version="1.0" encoding="' . $this->soap_defencoding .
'"?>' .
1093 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string .
">\n" .
1095 '<SOAP-ENV:Fault>' .
1100 '</SOAP-ENV:Fault>' .
1101 '</SOAP-ENV:Body>' .
1102 '</SOAP-ENV:Envelope>';
1130 public $schema =
'';
1133 public $enclosingNamespaces;
1135 public $schemaInfo = array();
1136 public $schemaTargetNamespace =
'';
1139 public $complexTypes = array();
1140 public $complexTypeStack = array();
1141 public $currentComplexType = null;
1142 public $elements = array();
1143 public $elementStack = array();
1144 public $currentElement = null;
1145 public $simpleTypes = array();
1146 public $simpleTypeStack = array();
1147 public $currentSimpleType = null;
1149 public $imports = array();
1152 public $position = 0;
1154 public $depth_array = array();
1156 public $defaultNamespace = array();
1169 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
1171 $this->schema = $schema;
1176 $this->namespaces = array_merge($this->namespaces,
$namespaces);
1179 if ($schema !=
'') {
1180 $this->
debug(
'initial schema file: ' . $schema);
1181 $this->parseFile($schema,
'schema');
1186 $this->
debug(
'initial xml file: ' .
$xml);
1187 $this->parseFile(
$xml,
'xml');
1203 $xmlStr = @join(
"", @file(
$xml));
1204 if ($xmlStr ==
"") {
1205 $msg =
'Error reading XML from ' .
$xml;
1210 $this->
debug(
"parsing $xml");
1211 $this->parseString($xmlStr,
$type);
1212 $this->
debug(
"done parsing $xml");
1226 public function parseString(
$xml,
$type)
1232 $this->parser = xml_parser_create();
1234 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1237 xml_set_object($this->parser, $this);
1240 if (
$type ==
"schema") {
1241 xml_set_element_handler($this->parser,
'schemaStartElement',
'schemaEndElement');
1242 xml_set_character_data_handler($this->parser,
'schemaCharacterData');
1243 } elseif (
$type ==
"xml") {
1244 xml_set_element_handler($this->parser,
'xmlStartElement',
'xmlEndElement');
1245 xml_set_character_data_handler($this->parser,
'xmlCharacterData');
1249 if (!xml_parse($this->parser,
$xml,
true)) {
1252 'XML error parsing XML schema on line %d: %s',
1253 xml_get_current_line_number($this->parser),
1254 xml_error_string(xml_get_error_code($this->parser))
1256 $this->
debug($errstr);
1261 xml_parser_free($this->parser);
1263 $this->
debug(
'no xml passed to parseString()!!');
1264 $this->
setError(
'no xml passed to parseString()!!');
1275 public function CreateTypeName($ename)
1278 for (
$i = 0;
$i < count($this->complexTypeStack);
$i++) {
1279 $scope .= $this->complexTypeStack[
$i] .
'_';
1281 return $scope . $ename .
'_ContainedType';
1292 public function schemaStartElement($parser,
$name, $attrs)
1296 $pos = $this->position++;
1297 $depth = $this->depth++;
1299 $this->depth_array[$depth] = $pos;
1300 $this->message[$pos] = array(
'cdata' =>
'');
1302 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1304 $this->defaultNamespace[$pos] =
false;
1316 if (count($attrs) > 0) {
1317 foreach ($attrs as $k => $v) {
1319 if (preg_match(
'/^xmlns/', $k)) {
1322 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
1324 $this->namespaces[$ns_prefix] = $v;
1326 $this->defaultNamespace[$pos] = $v;
1328 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $v;
1331 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
1332 $this->XMLSchemaVersion = $v;
1333 $this->namespaces[
'xsi'] = $v .
'-instance';
1337 foreach ($attrs as $k => $v) {
1339 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1340 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1354 $this->complexTypes[$this->currentComplexType][
'compositor'] =
$name;
1361 $this->xdebug(
"parsing attribute:");
1363 if (!isset($attrs[
'form'])) {
1364 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1366 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1367 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1368 if (!strpos($v,
':')) {
1370 if ($this->defaultNamespace[$pos]) {
1372 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1376 if (isset($attrs[
'name'])) {
1377 $this->attributes[$attrs[
'name']] = $attrs;
1378 $aname = $attrs[
'name'];
1379 } elseif (isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
1380 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1381 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1385 } elseif (isset($attrs[
'ref'])) {
1386 $aname = $attrs[
'ref'];
1387 $this->attributes[$attrs[
'ref']] = $attrs;
1390 if ($this->currentComplexType) {
1391 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1394 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType') {
1395 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1397 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1398 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1402 if (strpos($v,
'[,]')) {
1403 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1405 $v = substr($v, 0, strpos($v,
'['));
1406 if (!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
1407 $v = $this->XMLSchemaVersion .
':' . $v;
1409 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1412 case 'complexContent':
1415 array_push($this->complexTypeStack, $this->currentComplexType);
1416 if (isset($attrs[
'name'])) {
1419 $this->xdebug(
'processing named complexType ' . $attrs[
'name']);
1421 $this->currentComplexType = $attrs[
'name'];
1422 $this->complexTypes[$this->currentComplexType] = $attrs;
1423 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1431 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1432 $this->xdebug(
'complexType is unusual array');
1433 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1435 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1438 $name = $this->CreateTypeName($this->currentElement);
1439 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' .
$name);
1440 $this->currentComplexType =
$name;
1442 $this->complexTypes[$this->currentComplexType] = $attrs;
1443 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1451 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1452 $this->xdebug(
'complexType is unusual array');
1453 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1455 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1460 array_push($this->elementStack, $this->currentElement);
1461 if (!isset($attrs[
'form'])) {
1462 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1464 if (isset($attrs[
'type'])) {
1465 $this->xdebug(
"processing typed element " . $attrs[
'name'] .
" of type " . $attrs[
'type']);
1466 if (! $this->
getPrefix($attrs[
'type'])) {
1467 if ($this->defaultNamespace[$pos]) {
1468 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1469 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1479 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1480 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1481 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1483 $this->currentElement = $attrs[
'name'];
1484 $ename = $attrs[
'name'];
1485 } elseif (isset($attrs[
'ref'])) {
1486 $this->xdebug(
"processing element as ref to " . $attrs[
'ref']);
1487 $this->currentElement =
"ref to " . $attrs[
'ref'];
1490 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1491 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' .
$type);
1492 $this->currentElement = $attrs[
'name'];
1493 $attrs[
'type'] = $this->schemaTargetNamespace .
':' .
$type;
1494 $ename = $attrs[
'name'];
1496 if (isset($ename) && $this->currentComplexType) {
1497 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1498 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1499 } elseif (!isset($attrs[
'ref'])) {
1500 $this->xdebug(
"add element $ename to elements array");
1501 $this->elements[ $attrs[
'name'] ] = $attrs;
1502 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1506 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1507 if ($this->currentSimpleType) {
1508 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1509 } elseif ($this->currentComplexType) {
1510 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1514 $this->xdebug(
'extension ' . $attrs[
'base']);
1515 if ($this->currentComplexType) {
1516 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1520 if (isset($attrs[
'schemaLocation'])) {
1522 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1525 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1527 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
1534 $this->xdebug(
'restriction ' . $attrs[
'base']);
1535 if ($this->currentSimpleType) {
1536 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1537 } elseif ($this->currentComplexType) {
1538 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1539 if (strstr($attrs[
'base'],
':') ==
':Array') {
1540 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1545 $this->schemaInfo = $attrs;
1547 if (isset($attrs[
'targetNamespace'])) {
1548 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1550 if (!isset($attrs[
'elementFormDefault'])) {
1551 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1553 if (!isset($attrs[
'attributeFormDefault'])) {
1554 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1557 case 'simpleContent':
1560 array_push($this->simpleTypeStack, $this->currentSimpleType);
1561 if (isset($attrs[
'name'])) {
1562 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1563 $this->currentSimpleType = $attrs[
'name'];
1564 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1565 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1566 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1568 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1569 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' .
$name);
1570 $this->currentSimpleType =
$name;
1572 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1573 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1590 public function schemaEndElement($parser,
$name)
1595 if (isset($this->depth_array[$this->depth])) {
1596 $pos = $this->depth_array[$this->depth];
1606 if (
$name ==
'complexType') {
1607 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1608 $this->currentComplexType = array_pop($this->complexTypeStack);
1611 if (
$name ==
'element') {
1612 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1613 $this->currentElement = array_pop($this->elementStack);
1615 if (
$name ==
'simpleType') {
1616 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1617 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1628 public function schemaCharacterData($parser,
$data)
1630 $pos = $this->depth_array[$this->depth - 1];
1631 $this->message[$pos][
'cdata'] .=
$data;
1639 public function serializeSchema()
1644 if (
sizeof($this->imports) > 0) {
1645 foreach ($this->imports as $ns => $list) {
1646 foreach ($list as $ii) {
1647 if ($ii[
'location'] !=
'') {
1648 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1650 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1656 foreach ($this->complexTypes as $typeName => $attrs) {
1659 if (isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)) {
1660 foreach ($attrs[
'elements'] as $element => $eParts) {
1661 if (isset($eParts[
'ref'])) {
1662 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1664 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1665 foreach ($eParts as $aName => $aValue) {
1667 if ($aName !=
'name' && $aName !=
'type') {
1668 $contentStr .=
" $aName=\"$aValue\"";
1671 $contentStr .=
"/>\n";
1675 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1676 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n" . $contentStr .
" </$schemaPrefix:$attrs[compositor]>\n";
1680 if (isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)) {
1681 foreach ($attrs[
'attrs'] as $attr => $aParts) {
1682 $contentStr .=
" <$schemaPrefix:attribute";
1683 foreach ($aParts as
$a => $v) {
1684 if (
$a ==
'ref' ||
$a ==
'type') {
1685 $contentStr .=
" $a=\"" . $this->contractQName($v) .
'"';
1686 } elseif (
$a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1687 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1688 $contentStr .=
' wsdl:arrayType="' . $this->contractQName($v) .
'"';
1690 $contentStr .=
" $a=\"$v\"";
1693 $contentStr .=
"/>\n";
1697 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
'') {
1698 $contentStr =
" <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs[
'restrictionBase']) .
"\">\n" . $contentStr .
" </$schemaPrefix:restriction>\n";
1700 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)) {
1701 $contentStr =
" <$schemaPrefix:complexContent>\n" . $contentStr .
" </$schemaPrefix:complexContent>\n";
1705 if ($contentStr !=
'') {
1706 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr .
" </$schemaPrefix:complexType>\n";
1708 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1710 $xml .= $contentStr;
1713 if (isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
1714 foreach ($this->simpleTypes as $typeName => $eParts) {
1715 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts[
'type']) .
"\">\n";
1716 if (isset($eParts[
'enumeration'])) {
1717 foreach ($eParts[
'enumeration'] as
$e) {
1718 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1721 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1725 if (isset($this->elements) && count($this->elements) > 0) {
1726 foreach ($this->elements as $element => $eParts) {
1727 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"/>\n";
1731 if (isset($this->attributes) && count($this->attributes) > 0) {
1732 foreach ($this->attributes as $attr => $aParts) {
1733 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts[
'type']) .
"\"\n/>";
1738 foreach ($this->schemaInfo as $k => $v) {
1739 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1740 $attr .=
" $k=\"$v\"";
1743 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1744 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1745 $el .=
" xmlns:$nsp=\"$ns\"";
1747 $xml = $el .
">\n" .
$xml .
"</$schemaPrefix:schema>\n";
1757 public function xdebug($string)
1759 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> ' . $string);
1774 public function getPHPType(
$type, $ns)
1776 if (isset($this->typemap[$ns][
$type])) {
1778 return $this->typemap[$ns][
$type];
1779 } elseif (isset($this->complexTypes[$type])) {
1781 return $this->complexTypes[
$type][
'phpType'];
1808 public function getTypeDef($type)
1811 if (substr($type, -1) ==
'^') {
1813 $type = substr($type, 0, -1);
1818 if ((! $is_element) && isset($this->complexTypes[$type])) {
1819 $this->xdebug(
"in getTypeDef, found complexType $type");
1820 return $this->complexTypes[
$type];
1821 } elseif ((! $is_element) && isset($this->simpleTypes[$type])) {
1822 $this->xdebug(
"in getTypeDef, found simpleType $type");
1823 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1826 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1827 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1828 $etype = $this->getTypeDef($uqType);
1830 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1831 $this->xdebug($this->
varDump($etype));
1832 if (isset($etype[
'phpType'])) {
1833 $this->simpleTypes[
$type][
'phpType'] = $etype[
'phpType'];
1835 if (isset($etype[
'elements'])) {
1836 $this->simpleTypes[
$type][
'elements'] = $etype[
'elements'];
1840 return $this->simpleTypes[
$type];
1841 } elseif (isset($this->elements[$type])) {
1842 $this->xdebug(
"in getTypeDef, found element $type");
1843 if (!isset($this->elements[$type][
'phpType'])) {
1845 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1846 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1847 $etype = $this->getTypeDef($uqType);
1849 $this->xdebug(
"in getTypeDef, found type for element $type:");
1850 $this->xdebug($this->
varDump($etype));
1851 if (isset($etype[
'phpType'])) {
1852 $this->elements[
$type][
'phpType'] = $etype[
'phpType'];
1854 if (isset($etype[
'elements'])) {
1855 $this->elements[
$type][
'elements'] = $etype[
'elements'];
1857 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1858 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1859 $this->elements[
$type][
'phpType'] =
'scalar';
1862 return $this->elements[
$type];
1863 } elseif (isset($this->attributes[$type])) {
1864 $this->xdebug(
"in getTypeDef, found attribute $type");
1865 return $this->attributes[
$type];
1866 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1867 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1868 $typeDef[
'typeClass'] =
'simpleType';
1869 $typeDef[
'phpType'] =
'scalar';
1870 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1873 $this->xdebug(
"in getTypeDef, did not find $type");
1885 public function serializeTypeDef($type)
1888 if ($typeDef = $this->getTypeDef($type)) {
1889 $str .=
'<' .
$type;
1890 if (is_array($typeDef[
'attrs'])) {
1891 foreach ($typeDef[
'attrs'] as $attName =>
$data) {
1892 $str .=
" $attName=\"{type = " .
$data[
'type'] .
"}\"";
1895 $str .=
" xmlns=\"" . $this->schema[
'targetNamespace'] .
"\"";
1896 if (count($typeDef[
'elements']) > 0) {
1898 foreach ($typeDef[
'elements'] as $element => $eData) {
1899 $str .= $this->serializeTypeDef($element);
1902 } elseif ($typeDef[
'typeClass'] ==
'element') {
1903 $str .=
"></$type>";
1922 public function typeToForm(
$name, $type)
1925 if ($typeDef = $this->getTypeDef($type)) {
1927 if ($typeDef[
'phpType'] ==
'struct') {
1928 $buffer .=
'<table>';
1929 foreach ($typeDef[
'elements'] as $child => $childDef) {
1931 <tr><td align='right'>$childDef[name] (type: " . $this->
getLocalPart($childDef[
'type']) .
"):</td> 1932 <td><input type='text' name='parameters[" .
$name .
"][$childDef[name]]'></td></tr>";
1934 $buffer .=
'</table>';
1936 } elseif ($typeDef[
'phpType'] ==
'array') {
1937 $buffer .=
'<table>';
1938 for (
$i=0;
$i < 3;
$i++) {
1940 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1941 <td><input type='text' name='parameters[" .
$name .
"][]'></td></tr>";
1943 $buffer .=
'</table>';
1946 $buffer .=
"<input type='text' name='parameters[$name]'>";
1949 $buffer .=
"<input type='text' name='parameters[$name]'>";
1995 public function addComplexType(
$name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
1997 $this->complexTypes[
$name] = array(
1999 'typeClass' => $typeClass,
2000 'phpType' => $phpType,
2001 'compositor'=> $compositor,
2002 'restrictionBase' => $restrictionBase,
2003 'elements' => $elements,
2005 'arrayType' => $arrayType
2008 $this->xdebug(
"addComplexType $name:");
2024 public function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
2026 $this->simpleTypes[
$name] = array(
2028 'typeClass' => $typeClass,
2029 'phpType' => $phpType,
2030 'type' => $restrictionBase,
2031 'enumeration' => $enumeration
2034 $this->xdebug(
"addSimpleType $name:");
2045 public function addElement($attrs)
2047 if (! $this->
getPrefix($attrs[
'type'])) {
2048 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
2050 $this->elements[ $attrs[
'name'] ] = $attrs;
2051 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
2053 $this->xdebug(
"addElement " . $attrs[
'name']);
2136 public function __construct($name=
'soapval', $type=
false, $value=-1, $element_ns=
false, $type_ns=
false,
$attributes=
false)
2139 $this->name =
$name;
2140 $this->type =
$type;
2141 $this->value = $value;
2142 $this->element_ns = $element_ns;
2143 $this->type_ns = $type_ns;
2154 public function serialize($use=
'encoded')
2156 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2165 public function decode()
2167 return $this->value;
2190 public $digest_uri =
'';
2191 public $scheme =
'';
2195 public $request_method =
'POST';
2196 public $protocol_version =
'1.0';
2197 public $encoding =
'';
2198 public $outgoing_headers = array();
2199 public $incoming_headers = array();
2200 public $incoming_cookies = array();
2201 public $outgoing_payload =
'';
2202 public $incoming_payload =
'';
2203 public $response_status_line;
2204 public $useSOAPAction =
true;
2205 public $persistentConnection =
false;
2207 public $ch_options = array();
2208 public $use_curl =
false;
2209 public $proxy = null;
2210 public $username =
'';
2211 public $password =
'';
2212 public $authtype =
'';
2213 public $digestRequest = array();
2214 public $certRequest = array();
2231 public function __construct($url, $curl_options = null, $use_curl =
false)
2234 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2236 $this->setURL($url);
2237 if (is_array($curl_options)) {
2238 $this->ch_options = $curl_options;
2240 $this->use_curl = $use_curl;
2241 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2243 $this->setHeader(
'User-Agent', $this->title .
'/' . $this->version .
' (' . ($rev[1] ??
'1.1') .
')');
2253 public function setCurlOption($option, $value)
2255 $this->
debug(
"setCurlOption option=$option, value=");
2257 curl_setopt($this->ch, $option, $value);
2267 public function setHeader(
$name, $value)
2269 $this->outgoing_headers[
$name] = $value;
2270 $this->
debug(
"set header $name: $value");
2279 public function unsetHeader(
$name)
2281 if (isset($this->outgoing_headers[
$name])) {
2282 $this->
debug(
"unset header $name");
2283 unset($this->outgoing_headers[$name]);
2293 public function setURL($url)
2297 $u = parse_url($url);
2298 foreach ($u as $k => $v) {
2299 $this->
debug(
"parsed URL $k = $v");
2304 if (isset($u[
'query']) && $u[
'query'] !=
'') {
2305 $this->path .=
'?' . $u[
'query'];
2309 if (!isset($u[
'port'])) {
2310 if ($u[
'scheme'] ==
'https') {
2318 $this->digest_uri = $this->uri;
2321 if (!isset($u[
'port'])) {
2322 $this->setHeader(
'Host', $this->host);
2324 $this->setHeader(
'Host', $this->host .
':' . $this->port);
2327 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2328 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2338 public function io_method()
2340 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm')) {
2343 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm')) {
2357 public function connect($connection_timeout=0, $response_timeout=30)
2371 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2372 if ($this->io_method() ==
'socket') {
2373 if (!is_array($this->proxy)) {
2374 $host = $this->host;
2375 $port = $this->port;
2377 $host = $this->proxy[
'host'];
2378 $port = $this->proxy[
'port'];
2382 if ($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
2383 if (!feof($this->fp)) {
2384 $this->
debug(
'Re-use persistent connection');
2388 $this->
debug(
'Closed persistent connection at EOF');
2392 if ($this->scheme ==
'ssl') {
2393 $host =
'ssl://' . $host;
2395 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2398 if ($connection_timeout > 0) {
2399 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2401 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
2406 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2410 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2418 $this->
debug(
'set response timeout to ' . $response_timeout);
2419 socket_set_timeout($this->fp, $response_timeout);
2421 $this->
debug(
'socket connected');
2423 } elseif ($this->io_method() ==
'curl') {
2424 if (!extension_loaded(
'curl')) {
2426 $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.');
2430 if (defined(
'CURLOPT_CONNECTIONTIMEOUT')) {
2431 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2433 $CURLOPT_CONNECTIONTIMEOUT = 78;
2435 if (defined(
'CURLOPT_HTTPAUTH')) {
2436 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2438 $CURLOPT_HTTPAUTH = 107;
2440 if (defined(
'CURLOPT_PROXYAUTH')) {
2441 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2443 $CURLOPT_PROXYAUTH = 111;
2445 if (defined(
'CURLAUTH_BASIC')) {
2446 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2448 $CURLAUTH_BASIC = 1;
2450 if (defined(
'CURLAUTH_DIGEST')) {
2451 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2453 $CURLAUTH_DIGEST = 2;
2455 if (defined(
'CURLAUTH_NTLM')) {
2456 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2461 $this->
debug(
'connect using cURL');
2463 $this->ch = curl_init();
2465 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2468 $this->setCurlOption(CURLOPT_URL, $hostURL);
2470 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2471 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2472 $this->
debug(
'safe_mode = ');
2474 $this->
debug(
'open_basedir = ');
2477 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2480 $this->setCurlOption(CURLOPT_HEADER, 1);
2482 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2489 if ($this->persistentConnection) {
2495 $this->persistentConnection =
false;
2496 $this->setHeader(
'Connection',
'close');
2499 if ($connection_timeout != 0) {
2500 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2502 if ($response_timeout != 0) {
2503 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2506 if ($this->scheme ==
'https') {
2507 $this->
debug(
'set cURL SSL verify options');
2512 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2513 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2516 if ($this->authtype ==
'certificate') {
2517 $this->
debug(
'set cURL certificate options');
2518 if (isset($this->certRequest[
'cainfofile'])) {
2519 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2521 if (isset($this->certRequest[
'verifypeer'])) {
2522 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2524 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2526 if (isset($this->certRequest[
'verifyhost'])) {
2527 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2529 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2531 if (isset($this->certRequest[
'sslcertfile'])) {
2532 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2534 if (isset($this->certRequest[
'sslkeyfile'])) {
2535 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2537 if (isset($this->certRequest[
'passphrase'])) {
2538 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2540 if (isset($this->certRequest[
'certpassword'])) {
2541 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2545 if ($this->authtype && ($this->authtype !=
'certificate')) {
2546 if ($this->username) {
2547 $this->
debug(
'set cURL username/password');
2548 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2550 if ($this->authtype ==
'basic') {
2551 $this->
debug(
'set cURL for Basic authentication');
2552 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2554 if ($this->authtype ==
'digest') {
2555 $this->
debug(
'set cURL for digest authentication');
2556 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2558 if ($this->authtype ==
'ntlm') {
2559 $this->
debug(
'set cURL for NTLM authentication');
2560 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2563 if (is_array($this->proxy)) {
2564 $this->
debug(
'set cURL proxy options');
2565 if ($this->proxy[
'port'] !=
'') {
2566 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'] .
':' . $this->proxy[
'port']);
2568 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2570 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2571 $this->
debug(
'set cURL proxy authentication options');
2572 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'] .
':' . $this->proxy[
'password']);
2573 if ($this->proxy[
'authtype'] ==
'basic') {
2574 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2576 if ($this->proxy[
'authtype'] ==
'ntlm') {
2577 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2581 $this->
debug(
'cURL connection set up');
2584 $this->
setError(
'Unknown scheme ' . $this->scheme);
2585 $this->
debug(
'Unknown scheme ' . $this->scheme);
2600 public function send(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2602 $this->
debug(
'entered send() with data of length: ' . strlen(
$data));
2604 $this->tryagain =
true;
2606 while ($this->tryagain) {
2607 $this->tryagain =
false;
2610 if (!$this->connect($timeout, $response_timeout)) {
2615 if (!$this->sendRequest(
$data, $cookies)) {
2620 $respdata = $this->getResponse();
2622 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2625 $this->
debug(
'end of send()');
2641 public function sendHTTPS(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2643 return $this->
send(
$data, $timeout, $response_timeout, $cookies);
2656 public function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array())
2658 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2660 $this->
debug(
"certRequest=");
2663 if ($authtype ==
'basic') {
2664 $this->setHeader(
'Authorization',
'Basic ' . base64_encode(str_replace(
':',
'', $username) .
':' . $password));
2665 } elseif ($authtype ==
'digest') {
2666 if (isset($digestRequest[
'nonce'])) {
2667 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2672 $A1 = $username .
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2678 $A2 = $this->request_method .
':' . $this->digest_uri;
2694 $unhashedDigest =
'';
2695 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2697 if ($digestRequest[
'qop'] !=
'') {
2698 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2700 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2703 $hashedDigest = md5($unhashedDigest);
2706 if (isset($digestRequest[
'opaque'])) {
2707 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2710 $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 .
'"');
2712 } elseif ($authtype ==
'certificate') {
2713 $this->certRequest = $certRequest;
2714 $this->
debug(
'Authorization header not set for certificate');
2715 } elseif ($authtype ==
'ntlm') {
2717 $this->
debug(
'Authorization header not set for ntlm');
2719 $this->username = $username;
2720 $this->password = $password;
2721 $this->authtype = $authtype;
2722 $this->digestRequest = $digestRequest;
2731 public function setSOAPAction($soapaction)
2733 $this->setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2742 public function setEncoding($enc=
'gzip, deflate')
2744 if (function_exists(
'gzdeflate')) {
2745 $this->protocol_version =
'1.1';
2746 $this->setHeader(
'Accept-Encoding', $enc);
2747 if (!isset($this->outgoing_headers[
'Connection'])) {
2748 $this->setHeader(
'Connection',
'close');
2749 $this->persistentConnection =
false;
2751 #set_magic_quotes_runtime(0); 2753 $this->encoding = $enc;
2767 public function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic')
2770 $this->proxy = array(
2771 'host' => $proxyhost,
2772 'port' => $proxyport,
2773 'username' => $proxyusername,
2774 'password' => $proxypassword,
2775 'authtype' => $proxyauthtype
2777 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2778 $this->setHeader(
'Proxy-Authorization',
' Basic ' . base64_encode($proxyusername .
':' . $proxypassword));
2781 $this->
debug(
'remove proxy');
2783 unsetHeader(
'Proxy-Authorization');
2796 public function isSkippableCurlHeader(&
$data)
2798 $skipHeaders = array(
'HTTP/1.1 100',
2805 'HTTP/1.0 200 Connection established');
2806 foreach ($skipHeaders as $hd) {
2807 $prefix = substr(
$data, 0, strlen($hd));
2808 if ($prefix == $hd) {
2826 public function decodeChunked($buffer, $lb)
2834 $chunkend = strpos($buffer, $lb);
2835 if ($chunkend ==
false) {
2836 $this->
debug(
'no linebreak found in decodeChunked');
2839 $temp = substr($buffer, 0, $chunkend);
2840 $chunk_size = hexdec(trim($temp));
2841 $chunkstart = $chunkend + strlen($lb);
2843 while ($chunk_size > 0) {
2844 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2845 $chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
2848 if ($chunkend ==
false) {
2849 $chunk = substr($buffer, $chunkstart);
2852 $length += strlen($chunk);
2857 $chunk = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2861 $length += strlen($chunk);
2863 $chunkstart = $chunkend + strlen($lb);
2865 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2866 if ($chunkend ==
false) {
2869 $temp = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2870 $chunk_size = hexdec(trim($temp));
2871 $chunkstart = $chunkend;
2884 public function buildPayload(
$data, $cookie_str =
'')
2891 $this->setHeader(
'Content-Length', strlen(
$data));
2899 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2900 $this->
debug(
"HTTP request: $req");
2901 $this->outgoing_payload =
"$req\r\n";
2904 foreach ($this->outgoing_headers as $k => $v) {
2905 $hdr = $k .
': ' . $v;
2906 $this->
debug(
"HTTP header: $hdr");
2907 $this->outgoing_payload .=
"$hdr\r\n";
2911 if ($cookie_str !=
'') {
2912 $hdr =
'Cookie: ' . $cookie_str;
2913 $this->
debug(
"HTTP header: $hdr");
2914 $this->outgoing_payload .=
"$hdr\r\n";
2918 $this->outgoing_payload .=
"\r\n";
2921 $this->outgoing_payload .=
$data;
2932 public function sendRequest(
$data, $cookies = null)
2935 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2938 $this->buildPayload(
$data, $cookie_str);
2940 if ($this->io_method() ==
'socket') {
2942 if (!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2943 $this->
setError(
'couldn\'t write message data to socket');
2944 $this->
debug(
'couldn\'t write message data to socket');
2947 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2949 } elseif ($this->io_method() ==
'curl') {
2955 $curl_headers = array();
2956 foreach ($this->outgoing_headers as $k => $v) {
2957 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2958 $this->
debug(
"Skip cURL header $k: $v");
2960 $curl_headers[] =
"$k: $v";
2963 if ($cookie_str !=
'') {
2964 $curl_headers[] =
'Cookie: ' . $cookie_str;
2966 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2967 $this->
debug(
'set cURL HTTP headers');
2968 if ($this->request_method ==
"POST") {
2969 $this->setCurlOption(CURLOPT_POST, 1);
2970 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2971 $this->
debug(
'set cURL POST data');
2975 foreach ($this->ch_options as
$key => $val) {
2976 $this->setCurlOption(
$key, $val);
2979 $this->
debug(
'set cURL payload');
2990 public function getResponse()
2992 $this->incoming_payload =
'';
2994 if ($this->io_method() ==
'socket') {
2997 while (!isset($lb)) {
3000 if (feof($this->fp)) {
3001 $this->incoming_payload =
$data;
3002 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
3003 $this->
debug(
"received before EOF:\n" .
$data);
3004 $this->
setError(
'server failed to send headers');
3008 $tmp = fgets($this->fp, 256);
3009 $tmplen = strlen($tmp);
3010 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
3013 $this->incoming_payload =
$data;
3014 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
3015 $this->
debug(
"read before timeout: " .
$data);
3016 $this->
setError(
'socket read of headers timed out');
3021 $pos = strpos(
$data,
"\r\n\r\n");
3025 $pos = strpos(
$data,
"\n\n");
3031 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3037 $this->incoming_payload .=
$data;
3038 $this->
debug(
'found end of headers after length ' . strlen(
$data));
3040 $header_data = trim(substr(
$data, 0, $pos));
3041 $header_array = explode($lb, $header_data);
3042 $this->incoming_headers = array();
3043 $this->incoming_cookies = array();
3044 foreach ($header_array as $header_line) {
3045 $arr = explode(
':', $header_line, 2);
3046 if (count($arr) > 1) {
3047 $header_name = strtolower(trim($arr[0]));
3048 $this->incoming_headers[$header_name] = trim($arr[1]);
3049 if ($header_name ==
'set-cookie') {
3051 $cookie = $this->parseCookie(trim($arr[1]));
3053 $this->incoming_cookies[] = $cookie;
3054 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3056 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3059 } elseif (isset($header_name)) {
3061 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3066 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
3067 $content_length = 2147483647;
3069 $this->
debug(
"want to read chunked content");
3070 } elseif (isset($this->incoming_headers[
'content-length'])) {
3071 $content_length = $this->incoming_headers[
'content-length'];
3073 $this->
debug(
"want to read content of length $content_length");
3075 $content_length = 2147483647;
3077 $this->
debug(
"want to read content to EOF");
3082 $tmp = fgets($this->fp, 256);
3083 $tmplen = strlen($tmp);
3084 $this->
debug(
"read chunk line of $tmplen bytes");
3086 $this->incoming_payload =
$data;
3087 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3088 $this->
debug(
"read before timeout:\n" .
$data);
3089 $this->
setError(
'socket read of chunk length timed out');
3092 $content_length = hexdec(trim($tmp));
3093 $this->
debug(
"chunk length $content_length");
3096 while (($strlen < $content_length) && (!feof($this->fp))) {
3097 $readlen = min(8192, $content_length - $strlen);
3098 $tmp = fread($this->fp, $readlen);
3099 $tmplen = strlen($tmp);
3100 $this->
debug(
"read buffer of $tmplen bytes");
3101 if (($tmplen == 0) && (!feof($this->fp))) {
3102 $this->incoming_payload =
$data;
3103 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3104 $this->
debug(
"read before timeout:\n" .
$data);
3105 $this->
setError(
'socket read of body timed out');
3111 if ($chunked && ($content_length > 0)) {
3112 $tmp = fgets($this->fp, 256);
3113 $tmplen = strlen($tmp);
3114 $this->
debug(
"read chunk terminator of $tmplen bytes");
3116 $this->incoming_payload =
$data;
3117 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3118 $this->
debug(
"read before timeout:\n" .
$data);
3119 $this->
setError(
'socket read of chunk terminator timed out');
3123 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3124 if (feof($this->fp)) {
3125 $this->
debug(
'read to EOF');
3127 $this->
debug(
'read body of length ' . strlen(
$data));
3128 $this->incoming_payload .=
$data;
3129 $this->
debug(
'received a total of ' . strlen($this->incoming_payload) .
' bytes of data from server');
3133 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3134 (! $this->persistentConnection) || feof($this->fp)) {
3137 $this->
debug(
'closed socket');
3141 if ($this->incoming_payload ==
'') {
3142 $this->
setError(
'no response from server');
3156 } elseif ($this->io_method() ==
'curl') {
3158 $this->
debug(
'send and receive with cURL');
3159 $this->incoming_payload = curl_exec($this->ch);
3160 $data = $this->incoming_payload;
3162 $cErr = curl_error($this->ch);
3164 $err =
'cURL ERROR: ' . curl_errno($this->ch) .
': ' . $cErr .
'<br>';
3166 foreach (curl_getinfo($this->ch) as $k => $v) {
3167 $err .=
"$k: $v<br>";
3171 curl_close($this->ch);
3179 $this->
debug(
'No cURL error, closing cURL');
3180 curl_close($this->ch);
3184 while ($this->isSkippableCurlHeader(
$data)) {
3185 $this->
debug(
"Found HTTP header to skip");
3186 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3188 } elseif ($pos = strpos(
$data,
"\n\n")) {
3196 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3197 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3199 } elseif ($pos = strpos(
$data,
"\n\n")) {
3206 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3208 } elseif ($pos = strpos(
$data,
"\n\n")) {
3211 $this->
debug(
'no proper separation of headers and document');
3212 $this->
setError(
'no proper separation of headers and document');
3215 $header_data = trim(substr(
$data, 0, $pos));
3216 $header_array = explode($lb, $header_data);
3218 $this->
debug(
'found proper separation of headers and document');
3219 $this->
debug(
'cleaned data, stringlen: ' . strlen(
$data));
3221 foreach ($header_array as $header_line) {
3222 $arr = explode(
':', $header_line, 2);
3223 if (count($arr) > 1) {
3224 $header_name = strtolower(trim($arr[0]));
3225 $this->incoming_headers[$header_name] = trim($arr[1]);
3226 if ($header_name ==
'set-cookie') {
3228 $cookie = $this->parseCookie(trim($arr[1]));
3230 $this->incoming_cookies[] = $cookie;
3231 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3233 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3236 } elseif (isset($header_name)) {
3238 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3243 $this->response_status_line = $header_array[0];
3244 $arr = explode(
' ', $this->response_status_line, 3);
3245 $http_version = $arr[0];
3246 $http_status = intval($arr[1]);
3247 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3250 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3251 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3252 $this->setURL($this->incoming_headers[
'location']);
3253 $this->tryagain =
true;
3258 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3259 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3260 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3261 $this->
debug(
'Server wants digest authentication');
3263 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3266 $digestElements = explode(
',', $digestString);
3267 foreach ($digestElements as $val) {
3268 $tempElement = explode(
'=', trim($val), 2);
3269 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3273 if (isset($digestRequest[
'nonce'])) {
3274 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3275 $this->tryagain =
true;
3279 $this->
debug(
'HTTP authentication failed');
3280 $this->
setError(
'HTTP authentication failed');
3285 ($http_status >= 300 && $http_status <= 307) ||
3286 ($http_status >= 400 && $http_status <= 417) ||
3287 ($http_status >= 501 && $http_status <= 505)
3289 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3294 if (isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
'') {
3295 if (strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip') {
3297 if (function_exists(
'gzinflate')) {
3301 $this->
debug(
'The gzinflate function exists');
3302 $datalen = strlen(
$data);
3303 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3304 if ($degzdata = @gzinflate(
$data)) {
3306 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3307 if (strlen(
$data) < $datalen) {
3309 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3310 if ($degzdata = @gzinflate(
$data)) {
3312 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3316 $this->
debug(
'Error using gzinflate to inflate the payload');
3317 $this->
setError(
'Error using gzinflate to inflate the payload');
3319 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3320 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3322 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3323 if (strlen(
$data) < $datalen) {
3325 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3326 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3328 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3332 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3333 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3339 $this->incoming_payload = $header_data . $lb . $lb .
$data;
3341 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3342 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3345 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3346 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3349 $this->
debug(
'No Content-Encoding header');
3352 if (strlen(
$data) == 0) {
3353 $this->
debug(
'no data after headers!');
3354 $this->
setError(
'no data present after HTTP headers');
3368 public function setContentType($type, $charset =
false)
3370 $this->setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3379 public function usePersistentConnection()
3381 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3384 $this->protocol_version =
'1.1';
3385 $this->persistentConnection =
true;
3386 $this->setHeader(
'Connection',
'Keep-Alive');
3400 public function parseCookie($cookie_str)
3402 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3405 $data = explode(
';', $cookie_str);
3406 $value_str =
$data[0];
3408 $cookie_param =
'domain=';
3409 $start = strpos($cookie_str, $cookie_param);
3411 $domain = substr($cookie_str, $start + strlen($cookie_param));
3412 $domain = substr($domain, 0, strpos($domain,
';'));
3417 $cookie_param =
'expires=';
3418 $start = strpos($cookie_str, $cookie_param);
3420 $expires = substr($cookie_str, $start + strlen($cookie_param));
3421 $expires = substr($expires, 0, strpos($expires,
';'));
3426 $cookie_param =
'path=';
3427 $start = strpos($cookie_str, $cookie_param);
3429 $path = substr($cookie_str, $start + strlen($cookie_param));
3435 $cookie_param =
';secure;';
3436 if (strpos($cookie_str, $cookie_param) !==
false) {
3442 $sep_pos = strpos($value_str,
'=');
3445 $name = substr($value_str, 0, $sep_pos);
3446 $value = substr($value_str, $sep_pos + 1);
3447 $cookie= array(
'name' =>
$name,
3449 'domain' => $domain,
3451 'expires' => $expires,
3467 public function getCookiesForRequest($cookies, $secure=
false)
3470 if ((! is_null($cookies)) && (is_array($cookies))) {
3471 foreach ($cookies as $cookie) {
3472 if (! is_array($cookie)) {
3475 $this->
debug(
"check cookie for validity: " . $cookie[
'name'] .
'=' . $cookie[
'value']);
3476 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3477 if (strtotime($cookie[
'expires']) <= time()) {
3478 $this->
debug(
'cookie has expired');
3482 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3483 $domain = preg_quote($cookie[
'domain']);
3484 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3485 $this->
debug(
'cookie has different domain');
3489 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3490 $path = preg_quote($cookie[
'path']);
3491 if (! preg_match(
"'^$path.*'i", $this->path)) {
3492 $this->
debug(
'cookie is for a different path');
3496 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3497 $this->
debug(
'cookie is secure, transport is not');
3500 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3501 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3529 public $headers = array();
3535 public $request =
'';
3541 public $requestHeaders =
'';
3547 public $requestHeader = null;
3553 public $document =
'';
3559 public $requestSOAP =
'';
3565 public $methodURI =
'';
3571 public $methodname =
'';
3577 public $methodparams = array();
3583 public $SOAPAction =
'';
3589 public $xml_encoding =
'';
3595 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) {
4288 header($hdr,
false);
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/');
4622 public $schemas = array();
4623 public $currentSchema;
4625 public $complexTypes = array();
4627 public $currentMessage;
4628 public $currentOperation;
4629 public $portTypes = array();
4630 public $currentPortType;
4631 public $bindings = array();
4632 public $currentBinding;
4633 public $ports = array();
4634 public $currentPort;
4635 public $opData = array();
4636 public $status =
'';
4637 public $documentation =
false;
4638 public $endpoint =
'';
4640 public $import = array();
4643 public $position = 0;
4645 public $depth_array = array();
4647 public $proxyhost =
'';
4648 public $proxyport =
'';
4649 public $proxyusername =
'';
4650 public $proxypassword =
'';
4651 public $timeout = 0;
4652 public $response_timeout = 30;
4653 public $curl_options = array();
4654 public $use_curl =
false;
4656 public $username =
'';
4657 public $password =
'';
4658 public $authtype =
'';
4659 public $certRequest = array();
4675 public function __construct($wsdl =
'', $proxyhost=
false, $proxyport=
false, $proxyusername=
false, $proxypassword=
false, $timeout=0, $response_timeout=30, $curl_options=null, $use_curl=
false)
4678 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4679 $this->proxyhost = $proxyhost;
4680 $this->proxyport = $proxyport;
4681 $this->proxyusername = $proxyusername;
4682 $this->proxypassword = $proxypassword;
4683 $this->timeout = $timeout;
4684 $this->response_timeout = $response_timeout;
4685 if (is_array($curl_options)) {
4686 $this->curl_options = $curl_options;
4688 $this->use_curl = $use_curl;
4689 $this->fetchWSDL($wsdl);
4697 public function fetchWSDL($wsdl)
4699 $this->
debug(
"parse and process WSDL path=$wsdl");
4700 $this->
wsdl = $wsdl;
4702 if ($this->
wsdl !=
"") {
4703 $this->parseWSDL($this->
wsdl);
4707 $imported_urls = array();
4709 while ($imported > 0) {
4712 foreach ($this->schemas as $ns => $list) {
4713 foreach ($list as $xs) {
4714 $wsdlparts = parse_url($this->
wsdl);
4715 foreach ($xs->imports as $ns2 => $list2) {
4716 for ($ii = 0; $ii < count($list2); $ii++) {
4717 if (! $list2[$ii][
'loaded']) {
4718 $this->schemas[$ns]->imports[$ns2][$ii][
'loaded'] =
true;
4719 $url = $list2[$ii][
'location'];
4721 $urlparts = parse_url($url);
4722 if (!isset($urlparts[
'host'])) {
4723 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4724 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4726 if (! in_array($url, $imported_urls)) {
4727 $this->parseWSDL($url);
4729 $imported_urls[] =
$url;
4732 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4740 $wsdlparts = parse_url($this->
wsdl);
4741 foreach ($this->
import as $ns => $list) {
4742 for ($ii = 0; $ii < count($list); $ii++) {
4743 if (! $list[$ii][
'loaded']) {
4744 $this->
import[$ns][$ii][
'loaded'] =
true;
4745 $url = $list[$ii][
'location'];
4747 $urlparts = parse_url($url);
4748 if (!isset($urlparts[
'host'])) {
4749 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4750 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4752 if (! in_array($url, $imported_urls)) {
4753 $this->parseWSDL($url);
4755 $imported_urls[] =
$url;
4758 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4765 foreach ($this->bindings as $binding => $bindingData) {
4766 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4767 foreach ($bindingData[
'operations'] as $operation =>
$data) {
4768 $this->
debug(
'post-parse data gathering for ' . $operation);
4769 $this->bindings[$binding][
'operations'][$operation][
'input'] =
4770 isset($this->bindings[$binding][
'operations'][$operation][
'input']) ?
4771 array_merge($this->bindings[$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4772 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4773 $this->bindings[$binding][
'operations'][$operation][
'output'] =
4774 isset($this->bindings[$binding][
'operations'][$operation][
'output']) ?
4775 array_merge($this->bindings[$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4776 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4777 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ])) {
4778 $this->bindings[$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ];
4780 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ])) {
4781 $this->bindings[$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ];
4784 if (isset($bindingData[
'style']) && !isset($this->bindings[$binding][
'operations'][$operation][
'style'])) {
4785 $this->bindings[$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4787 $this->bindings[$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4788 $this->bindings[$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4789 $this->bindings[$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4801 public function parseWSDL($wsdl =
'')
4803 $this->
debug(
"parse WSDL at path=$wsdl");
4806 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4807 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4812 $wsdl_props = parse_url($wsdl);
4814 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4815 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4818 $tr->request_method =
'GET';
4819 $tr->useSOAPAction =
false;
4820 if ($this->proxyhost && $this->proxyport) {
4821 $tr->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
4823 if ($this->authtype !=
'') {
4824 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4826 $tr->setEncoding(
'gzip, deflate');
4827 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4832 if ($err = $tr->getError()) {
4833 $errstr =
'HTTP ERROR: ' . $err;
4834 $this->
debug($errstr);
4840 $this->
debug(
"got WSDL URL");
4843 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4844 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4849 if ($fp = @fopen(
$path,
'r')) {
4851 while (
$data = fread($fp, 32768)) {
4852 $wsdl_string .=
$data;
4856 $errstr =
"Bad path to WSDL file $path";
4857 $this->
debug($errstr);
4862 $this->
debug(
'Parse WSDL');
4865 $this->parser = xml_parser_create();
4868 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4870 xml_set_object($this->parser, $this);
4872 xml_set_element_handler($this->parser,
'start_element',
'end_element');
4873 xml_set_character_data_handler($this->parser,
'character_data');
4875 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4878 'XML error parsing WSDL from %s on line %d: %s',
4880 xml_get_current_line_number($this->parser),
4881 xml_error_string(xml_get_error_code($this->parser))
4883 $this->
debug($errstr);
4884 $this->
debug(
"XML payload:\n" . $wsdl_string);
4889 xml_parser_free($this->parser);
4890 $this->
debug(
'Parsing WSDL done');
4906 public function start_element($parser,
$name, $attrs)
4908 if ($this->status ==
'schema') {
4909 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4910 $this->
appendDebug($this->currentSchema->getDebug());
4911 $this->currentSchema->clearDebug();
4912 } elseif (preg_match(
'/schema$/',
$name)) {
4913 $this->
debug(
'Parsing WSDL schema');
4915 $this->status =
'schema';
4917 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4918 $this->
appendDebug($this->currentSchema->getDebug());
4919 $this->currentSchema->clearDebug();
4922 $pos = $this->position++;
4923 $depth = $this->depth++;
4925 $this->depth_array[$depth] = $pos;
4926 $this->message[$pos] = array(
'cdata' =>
'');
4928 if (count($attrs) > 0) {
4930 foreach ($attrs as $k => $v) {
4931 if (preg_match(
'/^xmlns/', $k)) {
4932 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4933 $this->namespaces[$ns_prefix] = $v;
4935 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4937 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4938 $this->XMLSchemaVersion = $v;
4939 $this->namespaces[
'xsi'] = $v .
'-instance';
4944 foreach ($attrs as $k => $v) {
4945 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4946 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4947 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4956 if (preg_match(
'/:/',
$name)) {
4958 $prefix = substr(
$name, 0, strpos(
$name,
':'));
4960 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4966 switch ($this->status) {
4968 if (
$name ==
'part') {
4969 if (isset($attrs[
'type'])) {
4970 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4971 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4973 if (isset($attrs[
'element'])) {
4974 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4975 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4982 $this->currentPortOperation = $attrs[
'name'];
4983 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
4984 if (isset($attrs[
'parameterOrder'])) {
4985 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
4988 case 'documentation':
4989 $this->documentation =
true;
4993 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
4994 $this->portTypes[$this->currentPortType][$this->currentPortOperation][
$name][
'message'] = $m;
5002 if (isset($attrs[
'style'])) {
5003 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
5005 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
5008 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
5011 if (isset($attrs[
'soapAction'])) {
5012 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
5014 if (isset($attrs[
'style'])) {
5015 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
5017 if (isset($attrs[
'name'])) {
5018 $this->currentOperation = $attrs[
'name'];
5019 $this->
debug(
"current binding operation: $this->currentOperation");
5020 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
5021 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
5022 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
5026 $this->opStatus =
'input';
5029 $this->opStatus =
'output';
5032 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
5033 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
5035 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
5043 $this->currentPort = $attrs[
'name'];
5044 $this->
debug(
'current port: ' . $this->currentPort);
5045 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
5049 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
5050 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
5051 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
5052 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
5060 if (isset($attrs[
'location'])) {
5061 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
5062 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]) .
')');
5064 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
5066 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
5068 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - [no location] (' . count($this->
import[$attrs[
'namespace']]) .
')');
5076 $this->status =
'message';
5077 $this->messages[$attrs[
'name']] = array();
5078 $this->currentMessage = $attrs[
'name'];
5081 $this->status =
'portType';
5082 $this->portTypes[$attrs[
'name']] = array();
5083 $this->currentPortType = $attrs[
'name'];
5086 if (isset($attrs[
'name'])) {
5088 if (strpos($attrs[
'name'],
':')) {
5089 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
5091 $this->currentBinding = $attrs[
'name'];
5093 $this->status =
'binding';
5094 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
5095 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
5099 $this->serviceName = $attrs[
'name'];
5100 $this->status =
'service';
5101 $this->
debug(
'current service: ' . $this->serviceName);
5104 foreach ($attrs as
$name => $value) {
5105 $this->wsdl_info[
$name] = $value;
5119 public function end_element($parser,
$name)
5122 if ( preg_match(
'/schema$/',
$name)) {
5124 $this->
appendDebug($this->currentSchema->getDebug());
5125 $this->currentSchema->clearDebug();
5126 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5127 $this->
debug(
'Parsing WSDL schema done');
5129 if ($this->status ==
'schema') {
5130 $this->currentSchema->schemaEndElement($parser,
$name);
5136 if ($this->documentation) {
5139 $this->documentation =
false;
5150 public function character_data($parser,
$data)
5152 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5153 if (isset($this->message[$pos][
'cdata'])) {
5154 $this->message[$pos][
'cdata'] .=
$data;
5156 if ($this->documentation) {
5157 $this->documentation .=
$data;
5170 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
5172 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5174 $this->username = $username;
5175 $this->password = $password;
5176 $this->authtype = $authtype;
5177 $this->certRequest = $certRequest;
5180 public function getBindingData($binding)
5182 if (is_array($this->bindings[$binding])) {
5183 return $this->bindings[$binding];
5194 public function getOperations($bindingType =
'soap')
5197 if ($bindingType ==
'soap') {
5198 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5199 } elseif ($bindingType ==
'soap12') {
5200 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5203 foreach ($this->ports as $port => $portData) {
5205 if ($portData[
'bindingType'] == $bindingType) {
5210 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5211 $ops = array_merge($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5226 public function getOperationData($operation, $bindingType =
'soap')
5228 if ($bindingType ==
'soap') {
5229 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5230 } elseif ($bindingType ==
'soap12') {
5231 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5234 foreach ($this->ports as $port => $portData) {
5236 if ($portData[
'bindingType'] == $bindingType) {
5239 foreach (array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5241 if ($operation == $bOperation) {
5242 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5258 public function getOperationDataForSoapAction($soapAction, $bindingType =
'soap')
5260 if ($bindingType ==
'soap') {
5261 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5262 } elseif ($bindingType ==
'soap12') {
5263 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5266 foreach ($this->ports as $port => $portData) {
5268 if ($portData[
'bindingType'] == $bindingType) {
5270 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5271 if ($opData[
'soapAction'] == $soapAction) {
5297 public function getTypeDef($type, $ns)
5299 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5300 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5301 $ns = $this->namespaces[
'tns'];
5302 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5304 if (!isset($this->schemas[$ns])) {
5305 foreach ($this->schemas as $ns0 => $schema0) {
5306 if (strcasecmp($ns, $ns0) == 0) {
5307 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5313 if (isset($this->schemas[$ns])) {
5314 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5315 for (
$i = 0;
$i < count($this->schemas[$ns]);
$i++) {
5316 $xs = &$this->schemas[$ns][
$i];
5317 $t = $xs->getTypeDef($type);
5321 if (!isset($t[
'phpType'])) {
5323 $uqType = substr($t[
'type'], strrpos($t[
'type'],
':') + 1);
5324 $ns = substr($t[
'type'], 0, strrpos($t[
'type'],
':'));
5325 $etype = $this->getTypeDef($uqType, $ns);
5327 $this->
debug(
"found type for [element] $type:");
5329 if (isset($etype[
'phpType'])) {
5330 $t[
'phpType'] = $etype[
'phpType'];
5332 if (isset($etype[
'elements'])) {
5333 $t[
'elements'] = $etype[
'elements'];
5335 if (isset($etype[
'attrs'])) {
5336 $t[
'attrs'] = $etype[
'attrs'];
5344 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5354 public function webDescription()
5356 global $HTTP_SERVER_VARS;
5360 } elseif (isset($HTTP_SERVER_VARS)) {
5361 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5363 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5366 $PHP_SELF = filter_var($PHP_SELF, FILTER_SANITIZE_STRING);
5370 <html><head><title>NuSOAP: ' . $this->serviceName .
'</title> 5371 <style type="text/css"> 5372 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5373 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5374 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5375 ul { margin-top: 10px; margin-left: 20px; } 5376 li { list-style-type: none; margin-top: 10px; color: #000000; } 5378 margin-left: 0px; padding-bottom: 2em; } 5380 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5381 margin-top: 10px; margin-left: 0px; color: #000000; 5382 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5384 font-family: arial; font-size: 26px; color: #ffffff; 5385 background-color: #999999; width: 105%; margin-left: 0px; 5386 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5388 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5389 font-family: arial; overflow: hidden; width: 600; 5390 padding: 20px; font-size: 10px; background-color: #999999; 5391 layer-background-color:#FFFFFF; } 5392 a,a:active { color: charcoal; font-weight: bold; } 5393 a:visited { color: #666666; font-weight: bold; } 5394 a:hover { color: cc3300; font-weight: bold; } 5396 <script language="JavaScript" type="text/javascript"> 5398 // POP-UP CAPTIONS... 5399 function lib_bwcheck(){ //Browsercheck (needed) 5400 this.ver=navigator.appVersion 5401 this.agent=navigator.userAgent 5402 this.dom=document.getElementById?1:0 5403 this.opera5=this.agent.indexOf("Opera 5")>-1 5404 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5405 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5406 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5407 this.ie=this.ie4||this.ie5||this.ie6 5408 this.mac=this.agent.indexOf("Mac")>-1 5409 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5410 this.ns4=(document.layers && !this.dom)?1:0; 5411 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5414 var bw = new lib_bwcheck() 5415 //Makes crossbrowser object. 5416 function makeObj(obj){ 5417 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5418 if(!this.evnt) return false 5419 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5420 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5421 this.writeIt=b_writeIt; 5424 // A unit of measure that will be added when setting the position of a layer. 5425 //var px = bw.ns4||window.opera?"":"px"; 5426 function b_writeIt(text){ 5427 if (bw.ns4){this.wref.write(text);this.wref.close()} 5428 else this.wref.innerHTML = text 5430 //Shows the messages 5432 function popup(divid){ 5433 if(oDesc = new makeObj(divid)){ 5434 oDesc.css.visibility = "visible" 5437 function popout(){ // Hides message 5438 if(oDesc) oDesc.css.visibility = "hidden" 5446 <div class=title>' . $this->serviceName .
'</div> 5448 <p>View the <a href="' . $PHP_SELF .
'?wsdl">WSDL</a> for the service. 5449 Click on an operation name to view it's details.</p> 5451 foreach ($this->getOperations() as $op =>
$data) {
5453 if (isset(
$data[
'endpoint'])) {
5454 $data[
'endpoint'] = filter_var(
$data[
'endpoint'], FILTER_SANITIZE_STRING);
5457 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5459 $b .=
"<div id='$op' class='hidden'> 5460 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5461 foreach (
$data as $donnie => $marie) {
5462 if ($donnie ==
'input' || $donnie ==
'output') {
5463 $b .=
"<font color='white'>" . ucfirst($donnie) .
':</font><br>';
5464 foreach ($marie as $captain => $tenille) {
5465 if ($captain ==
'parts') {
5466 $b .=
" $captain:<br>";
5468 foreach ($tenille as $joanie => $chachi) {
5469 $b .=
" $joanie: $chachi<br>";
5473 $b .=
" $captain: $tenille<br>";
5477 $b .=
"<font color='white'>" . ucfirst($donnie) .
":</font> $marie<br>";
5485 </div></body></html>';
5498 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5499 $xml .=
"\n<definitions";
5500 foreach ($this->namespaces as $k => $v) {
5501 $xml .=
" xmlns:$k=\"$v\"";
5504 if (isset($this->namespaces[
'wsdl'])) {
5505 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5507 if (isset($this->namespaces[
'tns'])) {
5508 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5512 if (
sizeof($this->
import) > 0) {
5513 foreach ($this->
import as $ns => $list) {
5514 foreach ($list as $ii) {
5515 if ($ii[
'location'] !=
'') {
5516 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5518 $xml .=
'<import namespace="' . $ns .
'" />';
5524 if (count($this->schemas)>=1) {
5525 $xml .=
"\n<types>\n";
5526 foreach ($this->schemas as $ns => $list) {
5527 foreach ($list as $xs) {
5528 $xml .= $xs->serializeSchema();
5534 if (count($this->messages) >= 1) {
5535 foreach ($this->messages as $msgName => $msgParts) {
5536 $xml .=
"\n<message name=\"" . $msgName .
'">';
5537 if (is_array($msgParts)) {
5538 foreach ($msgParts as $partName => $partType) {
5540 if (strpos($partType,
':')) {
5542 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5544 $typePrefix =
'xsd';
5546 foreach ($this->typemap as $ns => $types) {
5547 if (isset($types[$partType])) {
5551 if (!isset($typePrefix)) {
5552 die(
"$partType has no namespace!");
5557 $typeDef = $this->getTypeDef($localPart, $ns);
5558 if (($typeDef[
'typeClass'] ??
'') ==
'element') {
5559 $elementortype =
'element';
5560 if (substr($localPart, -1) ==
'^') {
5561 $localPart = substr($localPart, 0, -1);
5564 $elementortype =
'type';
5566 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5569 $xml .=
'</message>';
5573 if (count($this->bindings) >= 1) {
5576 foreach ($this->bindings as $bindingName => $attrs) {
5577 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5578 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5579 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5580 foreach ($attrs[
'operations'] as $opName => $opParts) {
5581 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5582 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="' . $opParts[
'style'] .
'"/>';
5583 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5584 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5588 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5589 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5590 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5594 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5595 $binding_xml .=
"\n" .
' </operation>';
5596 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5597 if (isset($opParts[
'parameterOrder'])) {
5598 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5600 $portType_xml .=
'>';
5601 if (isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5602 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5604 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5605 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5606 $portType_xml .=
"\n" .
' </operation>';
5608 $portType_xml .=
"\n" .
'</portType>';
5609 $binding_xml .=
"\n" .
'</binding>';
5611 $xml .= $portType_xml . $binding_xml;
5614 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5615 $has_client = isset(
$_GET[
'client_id']);
5616 if (count($this->ports) >= 1) {
5617 foreach ($this->ports as $pName => $attrs) {
5618 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5619 $address = $attrs[
'location'] . ($debug || $has_client ?
"?" :
"")
5620 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5621 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5622 $xml .=
"\n" .
' <soap:address location="' . $address .
'"/>';
5623 $xml .=
"\n" .
' </port>';
5627 $xml .=
"\n" .
'</service>';
5628 return $xml .
"\n</definitions>";
5640 public function parametersMatchWrapped($type, &$parameters)
5642 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5646 if (strpos($type,
':')) {
5647 $uqType = substr($type, strrpos($type,
':') + 1);
5648 $ns = substr($type, 0, strrpos($type,
':'));
5649 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5652 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5657 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5663 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5664 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5667 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5669 if (substr($uqType, -1) ==
'^') {
5670 $uqType = substr($uqType, 0, -1);
5672 $phpType = $typeDef[
'phpType'];
5673 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5674 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5677 if ($phpType !=
'struct') {
5678 $this->
debug(
"in parametersMatchWrapped: not a struct");
5683 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5687 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5688 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5691 foreach ($typeDef[
'elements'] as
$name => $attrs) {
5693 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5694 $parameters[
$name] = $parameters[$elements];
5695 unset($parameters[$elements]);
5697 } elseif (isset($parameters[
$name])) {
5698 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5701 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5706 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5707 if ($matches == 0) {
5715 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5716 return count($parameters) == 0;
5734 public function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap')
5736 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5739 if ($direction !=
'input' && $direction !=
'output') {
5740 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5741 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5744 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5745 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5746 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5749 $this->
debug(
'in serializeRPCParameters: opData:');
5753 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5754 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5755 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5756 $enc_style = $encodingStyle;
5761 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5762 $parts = &$opData[$direction][
'parts'];
5763 $part_count =
sizeof(
$parts);
5764 $style = $opData[
'style'];
5765 $use = $opData[$direction][
'use'];
5766 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5767 if (is_array($parameters)) {
5769 $parameter_count = count($parameters);
5770 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5772 if ($style ==
'document' && $use ==
'literal' && $part_count == 1 && isset(
$parts[
'parameters'])) {
5773 $this->
debug(
'check whether the caller has wrapped the parameters');
5774 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5775 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5776 if ($this->parametersMatchWrapped(
$parts[
'parameters'], $parameters)) {
5777 $this->
debug(
'wrap the parameters for the caller');
5778 $parameters = array(
'parameters' => $parameters);
5779 $parameter_count = 1;
5784 $this->
debug(
"serializing part $name of type $type");
5786 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5787 $encodingStyle = $opData[$direction][
'encodingStyle'];
5788 $enc_style = $encodingStyle;
5794 if ($parametersArrayType ==
'arraySimple') {
5795 $p = array_shift($parameters);
5796 $this->
debug(
'calling serializeType w/indexed param');
5797 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5798 } elseif (isset($parameters[
$name])) {
5799 $this->
debug(
'calling serializeType w/named param');
5800 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5803 $this->
debug(
'calling serializeType w/null param');
5804 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5808 $this->
debug(
'no parameters passed.');
5811 $this->
debug(
"serializeRPCParameters returning: $xml");
5829 public function serializeParameters($operation, $direction, $parameters)
5831 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5834 if ($direction !=
'input' && $direction !=
'output') {
5835 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5836 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5839 if (!$opData = $this->getOperationData($operation)) {
5840 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5841 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5844 $this->
debug(
'opData:');
5848 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5849 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5850 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5851 $enc_style = $encodingStyle;
5856 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5857 $use = $opData[$direction][
'use'];
5858 $this->
debug(
"use=$use");
5859 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5860 if (is_array($parameters)) {
5862 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5863 foreach ($opData[$direction][
'parts'] as
$name => $type) {
5864 $this->
debug(
'serializing part "' .
$name .
'" of type "' . $type .
'"');
5866 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5867 $encodingStyle = $opData[$direction][
'encodingStyle'];
5868 $enc_style = $encodingStyle;
5874 if ($parametersArrayType ==
'arraySimple') {
5875 $p = array_shift($parameters);
5876 $this->
debug(
'calling serializeType w/indexed param');
5877 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5878 } elseif (isset($parameters[
$name])) {
5879 $this->
debug(
'calling serializeType w/named param');
5880 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5883 $this->
debug(
'calling serializeType w/null param');
5884 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5888 $this->
debug(
'no parameters passed.');
5891 $this->
debug(
"serializeParameters returning: $xml");
5907 public function serializeType(
$name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5909 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5911 if ($use ==
'encoded' && $encodingStyle) {
5912 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5916 if (is_object($value) && get_class($value) ==
'soapval') {
5917 if ($value->type_ns) {
5918 $type = $value->type_ns .
':' . $value->type;
5920 $this->
debug(
"in serializeType: soapval overrides type to $type");
5921 } elseif ($value->type) {
5922 $type = $value->type;
5924 $this->
debug(
"in serializeType: soapval overrides type to $type");
5927 $this->
debug(
"in serializeType: soapval does not override type");
5929 $attrs = $value->attributes;
5930 $value = $value->value;
5931 $this->
debug(
"in serializeType: soapval overrides value to $value");
5933 if (!is_array($value)) {
5934 $value[
'!'] = $value;
5936 foreach ($attrs as $n => $v) {
5937 $value[
'!' . $n] = $v;
5939 $this->
debug(
"in serializeType: soapval provides attributes");
5946 if (strpos($type,
':')) {
5947 $uqType = substr($type, strrpos($type,
':') + 1);
5948 $ns = substr($type, 0, strrpos($type,
':'));
5949 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5952 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5955 if ($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/') {
5956 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5957 if ($unqualified && $use ==
'literal') {
5958 $elementNS =
" xmlns=\"\"";
5962 if (is_null($value)) {
5963 if ($use ==
'literal') {
5965 $xml =
"<$name$elementNS/>";
5970 $this->
debug(
"in serializeType: returning: $xml");
5973 if ($uqType ==
'Array') {
5977 if ($uqType ==
'boolean') {
5978 if ((is_string($value) && $value ==
'false') || (! $value)) {
5984 if ($uqType ==
'string' && gettype($value) ==
'string') {
5987 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5988 $value = sprintf(
"%.0lf", $value);
5993 if (!$this->getTypeDef($uqType, $ns)) {
5994 if ($use ==
'literal') {
5998 $xml =
"<$name$elementNS>$value</$name>";
6003 $this->
debug(
"in serializeType: returning: $xml");
6006 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
6007 } elseif ($ns ==
'http://xml.apache.org/xml-soap') {
6008 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
6009 if ($uqType ==
'Map') {
6012 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
6013 $tt_prefix =
'ns' . rand(1000, 9999);
6014 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
6019 foreach ($value as $k => $v) {
6020 $this->
debug(
"serializing map element: key $k, value $v");
6021 $contents .=
'<item>';
6022 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false, $use);
6023 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false, $use);
6024 $contents .=
'</item>';
6026 if ($use ==
'literal') {
6028 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
6030 $xml =
"<$name>$contents</$name>";
6033 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
6035 $this->
debug(
"in serializeType: returning: $xml");
6038 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
6043 $this->
debug(
"in serializeType: No namespace for type $type");
6047 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
6048 $this->
setError(
"$type ($uqType) is not a supported type.");
6049 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
6052 $this->
debug(
"in serializeType: found typeDef");
6054 if (substr($uqType, -1) ==
'^') {
6055 $uqType = substr($uqType, 0, -1);
6058 $phpType = $typeDef[
'phpType'];
6059 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
''));
6061 if ($phpType ==
'struct') {
6062 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
6063 $elementName = $uqType;
6064 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6065 $elementNS =
" xmlns=\"$ns\"";
6067 $elementNS =
" xmlns=\"\"";
6070 $elementName =
$name;
6072 $elementNS =
" xmlns=\"\"";
6077 if (is_null($value)) {
6078 if ($use ==
'literal') {
6080 $xml =
"<$elementName$elementNS/>";
6084 $this->
debug(
"in serializeType: returning: $xml");
6087 if (is_object($value)) {
6088 $value = get_object_vars($value);
6090 if (is_array($value)) {
6091 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6092 if ($use ==
'literal') {
6096 $xml =
"<$elementName$elementNS$elementAttrs>";
6099 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
6102 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6103 $xml .=
"</$elementName>";
6105 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
6106 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
6109 } elseif ($phpType ==
'array') {
6110 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6111 $elementNS =
" xmlns=\"$ns\"";
6114 $elementNS =
" xmlns=\"\"";
6119 if (is_null($value)) {
6120 if ($use ==
'literal') {
6122 $xml =
"<$name$elementNS/>";
6124 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6131 $this->
getLocalPart($typeDef[
'arrayType']) .
"[0]\"/>";
6133 $this->
debug(
"in serializeType: returning: $xml");
6136 if (isset($typeDef[
'multidimensional'])) {
6138 foreach ($value as $v) {
6139 $cols =
',' .
sizeof($v);
6140 $nv = array_merge($nv, $v);
6146 if (is_array($value) &&
sizeof($value) >= 1) {
6147 $rows =
sizeof($value);
6149 foreach ($value as $k => $v) {
6150 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6152 if (!in_array($typeDef[
'arrayType'], $this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6153 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6155 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6164 if ($use ==
'literal') {
6165 $xml =
"<$name$elementNS>" 6169 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/') .
':Array" ' .
6173 .
":" . $this->
getLocalPart($typeDef[
'arrayType']) .
"[$rows$cols]\">" 6177 } elseif ($phpType ==
'scalar') {
6178 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6179 $elementNS =
" xmlns=\"$ns\"";
6182 $elementNS =
" xmlns=\"\"";
6187 if ($use ==
'literal') {
6191 $xml =
"<$name$elementNS>$value</$name>";
6197 $this->
debug(
"in serializeType: returning: $xml");
6211 public function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
6214 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6215 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6216 if (is_array($value)) {
6218 } elseif (is_object($value)) {
6219 $xvalue = get_object_vars($value);
6221 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6224 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6225 if (isset($xvalue[
'!' . $aName])) {
6226 $xname =
'!' . $aName;
6227 $this->
debug(
"value provided for attribute $aName with key $xname");
6228 } elseif (isset($xvalue[$aName])) {
6230 $this->
debug(
"value provided for attribute $aName with key $xname");
6231 } elseif (isset($attrs[
'default'])) {
6232 $xname =
'!' . $aName;
6233 $xvalue[$xname] = $attrs[
'default'];
6234 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6237 $this->
debug(
"no value provided for attribute $aName");
6244 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6246 if (isset($typeDef[
'extensionBase'])) {
6247 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6248 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6252 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6253 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6254 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6256 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6274 public function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false)
6277 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6278 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6279 if (is_array($value)) {
6281 } elseif (is_object($value)) {
6282 $xvalue = get_object_vars($value);
6284 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6288 if (count($typeDef[
'elements']) != count($xvalue)) {
6291 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6292 if (!isset($xvalue[$eName])) {
6293 if (isset($attrs[
'default'])) {
6294 $xvalue[$eName] = $attrs[
'default'];
6295 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6299 if (isset($optionals)
6300 && (!isset($xvalue[$eName]))
6301 && ((!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6303 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6304 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6307 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6310 if (isset($xvalue[$eName])) {
6311 $v = $xvalue[$eName];
6315 if (isset($attrs[
'form'])) {
6316 $unqualified = ($attrs[
'form'] ==
'unqualified');
6318 $unqualified =
false;
6320 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6322 foreach ($vv as $k => $v) {
6323 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6325 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6328 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6333 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6335 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6338 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6345 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6347 if (isset($typeDef[
'extensionBase'])) {
6348 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6349 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6353 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6354 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6355 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6357 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6377 public function addComplexType(
$name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
6379 if (count($elements) > 0) {
6380 $eElements = array();
6381 foreach ($elements as $n =>
$e) {
6384 foreach (
$e as $k => $v) {
6385 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6386 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6389 $eElements[$n] = $ee;
6391 $elements = $eElements;
6394 if (count($attrs) > 0) {
6395 foreach ($attrs as $n =>
$a) {
6397 foreach (
$a as $k => $v) {
6398 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6399 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6407 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6408 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6410 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6411 $this->schemas[$typens][0]->addComplexType(
$name, $typeClass, $phpType, $compositor, $restrictionBase, $elements, $attrs, $arrayType);
6425 public function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
6427 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6429 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6430 $this->schemas[$typens][0]->addSimpleType(
$name, $restrictionBase, $typeClass, $phpType, $enumeration);
6440 public function addElement($attrs)
6442 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6443 $this->schemas[$typens][0]->addElement($attrs);
6460 public function addOperation(
$name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false, $style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
'')
6462 if ($use ==
'encoded' && $encodingStyle ==
'') {
6463 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6466 if ($style ==
'document') {
6467 $elements = array();
6468 foreach ($in as $n => $t) {
6469 $elements[$n] = array(
'name' => $n,
'type' => $t);
6471 $this->addComplexType(
$name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6472 $this->addElement(array(
'name' =>
$name,
'type' =>
$name .
'RequestType'));
6473 $in = array(
'parameters' =>
'tns:' .
$name .
'^');
6475 $elements = array();
6476 foreach (
$out as $n => $t) {
6477 $elements[$n] = array(
'name' => $n,
'type' => $t);
6479 $this->addComplexType(
$name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6480 $this->addElement(array(
'name' =>
$name .
'Response',
'type' =>
$name .
'ResponseType',
'form' =>
'qualified'));
6481 $out = array(
'parameters' =>
'tns:' .
$name .
'Response' .
'^');
6485 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][
$name] =
6488 'binding' => $this->serviceName .
'Binding',
6489 'endpoint' => $this->endpoint,
6490 'soapAction' => $soapaction,
6495 'encodingStyle' => $encodingStyle,
6496 'message' =>
$name .
'Request',
6501 'encodingStyle' => $encodingStyle,
6502 'message' =>
$name .
'Response',
6505 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6506 'documentation' => $documentation);
6510 foreach ($in as $pName => $pType) {
6511 if (strpos($pType,
':')) {
6514 $this->messages[
$name .
'Request'][$pName] = $pType;
6517 $this->messages[
$name .
'Request']=
'0';
6520 foreach (
$out as $pName => $pType) {
6521 if (strpos($pType,
':')) {
6524 $this->messages[
$name .
'Response'][$pName] = $pType;
6527 $this->messages[
$name .
'Response']=
'0';
6548 public $xml_encoding =
'';
6549 public $method =
'';
6550 public $root_struct =
'';
6551 public $root_struct_name =
'';
6552 public $root_struct_namespace =
'';
6553 public $root_header =
'';
6554 public $document =
'';
6556 public $status =
'';
6557 public $position = 0;
6559 public $default_namespace =
'';
6562 public $parent =
'';
6563 public $fault =
false;
6564 public $fault_code =
'';
6565 public $fault_str =
'';
6566 public $fault_detail =
'';
6567 public $depth_array = array();
6568 public $debug_flag =
true;
6569 public $soapresponse = null;
6570 public $soapheader = null;
6571 public $responseHeaders =
'';
6572 public $body_position = 0;
6575 public $ids = array();
6577 public $multirefs = array();
6579 public $decode_utf8 =
true;
6590 public function __construct($xml, $encoding=
'UTF-8', $method=
'', $decode_utf8=
true)
6594 $this->xml_encoding = $encoding;
6595 $this->method = $method;
6596 $this->decode_utf8 = $decode_utf8;
6601 $pos_xml = strpos($xml,
'<?xml');
6602 if ($pos_xml !==
false) {
6603 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6604 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6605 $xml_encoding =
$res[1];
6606 if (strtoupper($xml_encoding) != $encoding) {
6607 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6609 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6615 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6618 $this->
debug(
'No encoding specified in XML declaration');
6621 $this->
debug(
'No XML declaration');
6623 $this->
debug(
'Entering nusoap_parser(), length=' . strlen($xml) .
', encoding=' . $encoding);
6625 $this->parser = xml_parser_create($this->xml_encoding);
6628 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6629 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6631 xml_set_object($this->parser, $this);
6633 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6634 xml_set_character_data_handler($this->parser,
'character_data');
6637 if (!xml_parse($this->parser, $xml,
true)) {
6640 'XML error parsing SOAP payload on line %d: %s',
6641 xml_get_current_line_number($this->parser),
6642 xml_error_string(xml_get_error_code($this->parser))
6645 $this->
debug(
"XML payload:\n" . $xml);
6648 $this->
debug(
'parsed successfully, found root struct: ' . $this->root_struct .
' of name ' . $this->root_struct_name);
6650 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6652 if ($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])) {
6653 $this->soapheader = $this->message[$this->root_header][
'result'];
6656 if (
sizeof($this->multirefs) > 0) {
6657 foreach ($this->multirefs as
$id => $hrefs) {
6658 $this->
debug(
'resolving multirefs for id: ' .
$id);
6659 $idVal = $this->buildVal($this->ids[
$id]);
6660 if (is_array($idVal) && isset($idVal[
'!id'])) {
6661 unset($idVal[
'!id']);
6663 foreach ($hrefs as $refPos => $ref) {
6664 $this->
debug(
'resolving href at pos ' . $refPos);
6665 $this->multirefs[
$id][$refPos] = $idVal;
6670 xml_parser_free($this->parser);
6672 $this->
debug(
'xml was empty, didn\'t parse!');
6673 $this->
setError(
'xml was empty, didn\'t parse!');
6685 public function start_element($parser,
$name, $attrs)
6689 $pos = $this->position++;
6691 $this->message[$pos] = array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6694 $this->message[$pos][
'depth'] = $this->depth++;
6698 $this->message[$this->parent][
'children'] .=
'|' . $pos;
6701 $this->message[$pos][
'parent'] = $this->parent;
6703 $this->parent = $pos;
6705 $this->depth_array[$this->depth] = $pos;
6707 if (strpos(
$name,
':')) {
6709 $prefix = substr(
$name, 0, strpos(
$name,
':'));
6714 if (
$name ==
'Envelope') {
6715 $this->status =
'envelope';
6716 } elseif (
$name ==
'Header' && $this->status =
'envelope') {
6717 $this->root_header = $pos;
6718 $this->status =
'header';
6719 } elseif (
$name ==
'Body' && $this->status =
'envelope') {
6720 $this->status =
'body';
6721 $this->body_position = $pos;
6723 } elseif ($this->status ==
'body' && $pos == ($this->body_position+1)) {
6724 $this->status =
'method';
6725 $this->root_struct_name =
$name;
6726 $this->root_struct = $pos;
6727 $this->message[$pos][
'type'] =
'struct';
6728 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6731 $this->message[$pos][
'status'] = $this->status;
6733 $this->message[$pos][
'name'] = htmlspecialchars(
$name);
6735 $this->message[$pos][
'attrs'] = $attrs;
6739 foreach ($attrs as
$key => $value) {
6743 if ($key_prefix ==
'xmlns') {
6744 if (preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/', $value)) {
6745 $this->XMLSchemaVersion = $value;
6747 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion .
'-instance';
6749 $this->namespaces[$key_localpart] = $value;
6751 if (
$name == $this->root_struct_name) {
6752 $this->methodNamespace = $value;
6755 } elseif ($key_localpart ==
'type') {
6756 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6759 $value_prefix = $this->
getPrefix($value);
6761 $this->message[$pos][
'type'] = $value_localpart;
6762 $this->message[$pos][
'typePrefix'] = $value_prefix;
6763 if (isset($this->namespaces[$value_prefix])) {
6764 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6765 } elseif (isset($attrs[
'xmlns:' . $value_prefix])) {
6766 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:' . $value_prefix];
6770 } elseif ($key_localpart ==
'arrayType') {
6771 $this->message[$pos][
'type'] =
'array';
6780 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6781 if (preg_match($expr, $value, $regs)) {
6782 $this->message[$pos][
'typePrefix'] = $regs[1];
6783 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6784 if (isset($this->namespaces[$regs[1]])) {
6785 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6786 } elseif (isset($attrs[
'xmlns:' . $regs[1]])) {
6787 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:' . $regs[1]];
6789 $this->message[$pos][
'arrayType'] = $regs[2];
6790 $this->message[$pos][
'arraySize'] = $regs[3];
6791 $this->message[$pos][
'arrayCols'] = $regs[4];
6794 } elseif ($key_localpart ==
'nil') {
6795 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6797 } elseif (
$key !=
'href' &&
$key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6798 $this->message[$pos][
'xattrs'][
'!' .
$key] = $value;
6801 if (
$key ==
'xmlns') {
6802 $this->default_namespace = $value;
6806 $this->ids[$value] = $pos;
6809 if ($key_localpart ==
'root' && $value == 1) {
6810 $this->status =
'method';
6811 $this->root_struct_name =
$name;
6812 $this->root_struct = $pos;
6813 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6816 $attstr .=
" $key=\"$value\"";
6819 if (isset($prefix)) {
6820 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6821 $this->default_namespace = $this->namespaces[$prefix];
6823 $this->message[$pos][
'namespace'] = $this->default_namespace;
6825 if ($this->status ==
'header') {
6826 if ($this->root_header != $pos) {
6827 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6829 } elseif ($this->root_struct_name !=
'') {
6830 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6841 public function end_element($parser,
$name)
6844 $pos = $this->depth_array[$this->depth--];
6847 if (strpos(
$name,
':')) {
6849 $prefix = substr(
$name, 0, strpos(
$name,
':'));
6855 if (isset($this->body_position) && $pos > $this->body_position) {
6857 if (isset($this->message[$pos][
'attrs'][
'href'])) {
6859 $id = substr($this->message[$pos][
'attrs'][
'href'], 1);
6861 $this->multirefs[
$id][$pos] =
'placeholder';
6863 $this->message[$pos][
'result'] =& $this->multirefs[
$id][$pos];
6865 } elseif ($this->message[$pos][
'children'] !=
'') {
6867 if (!isset($this->message[$pos][
'result'])) {
6868 $this->message[$pos][
'result'] = $this->buildVal($pos);
6871 } elseif (isset($this->message[$pos][
'xattrs'])) {
6872 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6873 $this->message[$pos][
'xattrs'][
'!'] = null;
6874 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6875 if (isset($this->message[$pos][
'type'])) {
6876 $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'] :
'');
6878 $parent = $this->message[$pos][
'parent'];
6879 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6880 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6882 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6886 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6890 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6891 $this->message[$pos][
'xattrs'][
'!'] = null;
6892 } elseif (isset($this->message[$pos][
'type'])) {
6893 $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'] :
'');
6895 $parent = $this->message[$pos][
'parent'];
6896 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6897 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6899 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6917 if ($this->status ==
'header') {
6918 if ($this->root_header != $pos) {
6919 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6921 } elseif ($pos >= $this->root_struct) {
6922 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6925 if ($pos == $this->root_struct) {
6926 $this->status =
'body';
6927 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6928 } elseif (
$name ==
'Body') {
6929 $this->status =
'envelope';
6930 } elseif (
$name ==
'Header') {
6931 $this->status =
'envelope';
6932 } elseif (
$name ==
'Envelope') {
6936 $this->parent = $this->message[$pos][
'parent'];
6946 public function character_data($parser,
$data)
6948 $pos = $this->depth_array[$this->depth];
6949 if ($this->xml_encoding==
'UTF-8') {
6953 if ($this->decode_utf8) {
6957 $this->message[$pos][
'cdata'] .=
$data;
6959 if ($this->status ==
'header') {
6960 $this->responseHeaders .=
$data;
6962 $this->document .=
$data;
6973 public function get_response()
6975 return $this->soapresponse;
6984 public function get_soapbody()
6986 return $this->soapresponse;
6995 public function get_soapheader()
6997 return $this->soapheader;
7006 public function getHeaders()
7008 return $this->responseHeaders;
7020 public function decodeSimple($value, $type, $typens)
7023 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
7024 return (
string) $value;
7026 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
7027 return (
int) $value;
7029 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
7030 return (
float) $value;
7032 if ($type ==
'boolean') {
7033 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
7036 return (
bool) $value;
7038 if ($type ==
'base64' || $type ==
'base64Binary') {
7039 $this->
debug(
'Decode base64 value');
7040 return base64_decode($value);
7043 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 7044 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 7045 || $type ==
'unsignedInt' 7046 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
7047 return (
int) $value;
7050 if ($type ==
'array') {
7054 return (
string) $value;
7065 public function buildVal($pos)
7067 if (!isset($this->message[$pos][
'type'])) {
7068 $this->message[$pos][
'type'] =
'';
7070 $this->
debug(
'in buildVal() for ' . $this->message[$pos][
'name'] .
"(pos $pos) of type " . $this->message[$pos][
'type']);
7072 if ($this->message[$pos][
'children'] !=
'') {
7073 $this->
debug(
'in buildVal, there are children');
7074 $children = explode(
'|', $this->message[$pos][
'children']);
7075 array_shift($children);
7077 if (isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
'') {
7080 foreach ($children as $child_pos) {
7081 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
7082 $params[$r][] = $this->message[$child_pos][
'result'];
7084 if (
$c == $this->message[$pos][
'arrayCols']) {
7090 } elseif ($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array') {
7091 $this->
debug(
'in buildVal, adding array ' . $this->message[$pos][
'name']);
7092 foreach ($children as $child_pos) {
7093 $params[] = &$this->message[$child_pos][
'result'];
7096 } elseif ($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7097 $this->
debug(
'in buildVal, Java Map ' . $this->message[$pos][
'name']);
7098 foreach ($children as $child_pos) {
7099 $kv = explode(
"|", $this->message[$child_pos][
'children']);
7100 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
7106 $this->
debug(
'in buildVal, adding Java Vector or generic compound type ' . $this->message[$pos][
'name']);
7107 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7113 foreach ($children as $child_pos) {
7115 $params[] = &$this->message[$child_pos][
'result'];
7117 if (isset(
$params[$this->message[$child_pos][
'name']])) {
7119 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
7120 $params[$this->message[$child_pos][
'name']] = array(
$params[$this->message[$child_pos][
'name']]);
7122 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
7124 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
7129 if (isset($this->message[$pos][
'xattrs'])) {
7130 $this->
debug(
'in buildVal, handling attributes');
7131 foreach ($this->message[$pos][
'xattrs'] as $n => $v) {
7136 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7137 $this->
debug(
'in buildVal, handling simpleContent');
7138 if (isset($this->message[$pos][
'type'])) {
7139 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7141 $parent = $this->message[$pos][
'parent'];
7142 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7143 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7145 $params[
'!'] = $this->message[$pos][
'cdata'];
7150 $this->
debug(
'in buildVal, return:');
7154 $this->
debug(
'in buildVal, no children, building scalar');
7155 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7156 if (isset($this->message[$pos][
'type'])) {
7157 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7158 $this->
debug(
"in buildVal, return: $ret");
7161 $parent = $this->message[$pos][
'parent'];
7162 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7163 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7164 $this->
debug(
"in buildVal, return: $ret");
7167 $ret = $this->message[$pos][
'cdata'];
7168 $this->
debug(
"in buildVal, return: $ret");
7207 public $username =
'';
7208 public $password =
'';
7209 public $authtype =
'';
7210 public $certRequest = array();
7211 public $requestHeaders =
false;
7212 public $responseHeaders =
'';
7213 public $responseHeader = null;
7214 public $document =
'';
7216 public $forceEndpoint =
'';
7217 public $proxyhost =
'';
7218 public $proxyport =
'';
7219 public $proxyusername =
'';
7220 public $proxypassword =
'';
7221 public $xml_encoding =
'';
7222 public $http_encoding =
false;
7223 public $timeout = 0;
7224 public $response_timeout = 30;
7225 public $endpointType =
'';
7226 public $persistentConnection =
false;
7227 public $defaultRpcParams =
false;
7228 public $request =
'';
7231 public $cookies = array();
7232 public $decode_utf8 =
true;
7233 public $operations = array();
7234 public $curl_options = array();
7235 public $bindingType =
'';
7236 public $use_curl =
false;
7276 public function __construct($endpoint, $wsdl =
false, $proxyhost =
false, $proxyport =
false, $proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30)
7279 $this->endpoint = $endpoint;
7280 $this->proxyhost = $proxyhost;
7281 $this->proxyport = $proxyport;
7282 $this->proxyusername = $proxyusername;
7283 $this->proxypassword = $proxypassword;
7284 $this->timeout = $timeout;
7285 $this->response_timeout = $response_timeout;
7287 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7292 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7293 $this->
wsdl = $endpoint;
7294 $this->endpoint = $this->
wsdl->wsdl;
7295 $this->wsdlFile = $this->endpoint;
7296 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7299 $this->wsdlFile = $this->endpoint;
7301 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7303 $this->endpointType =
'wsdl';
7305 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7306 $this->endpointType =
'soap';
7335 public function call($operation,
$params=array(),
$namespace=
'http://tempuri.org', $soapAction=
'', $headers=
false, $rpcParams=null, $style=
'rpc', $use=
'encoded')
7337 $this->operation = $operation;
7338 $this->fault =
false;
7340 $this->request =
'';
7341 $this->response =
'';
7342 $this->responseData =
'';
7343 $this->faultstring =
'';
7344 $this->faultcode =
'';
7345 $this->opData = array();
7347 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7351 $this->requestHeaders = $headers;
7353 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7360 if ($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)) {
7362 $this->opData = $opData;
7363 $this->
debug(
"found operation");
7365 if (isset($opData[
'soapAction'])) {
7366 $soapAction = $opData[
'soapAction'];
7368 if (! $this->forceEndpoint) {
7369 $this->endpoint = $opData[
'endpoint'];
7371 $this->endpoint = $this->forceEndpoint;
7373 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7374 $style = $opData[
'style'];
7375 $use = $opData[
'input'][
'use'];
7378 $nsPrefix =
'ns' . rand(1000, 9999);
7384 $this->
debug(
"serializing param string for WSDL operation $operation");
7386 } elseif (is_array(
$params)) {
7387 $this->
debug(
"serializing param array for WSDL operation $operation");
7390 $this->
debug(
'params must be array or string');
7391 $this->
setError(
'params must be array or string');
7395 if (isset($opData[
'input'][
'encodingStyle'])) {
7396 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7398 $encodingStyle =
'';
7403 $this->
debug(
'got wsdl error: ' . $errstr);
7404 $this->
setError(
'wsdl error: ' . $errstr);
7407 } elseif ($this->endpointType ==
'wsdl') {
7411 $this->
setError(
'operation ' . $operation .
' not present.');
7412 $this->
debug(
"operation '$operation' not present.");
7417 $nsPrefix =
'ns' . rand(1000, 9999);
7421 $this->
debug(
"serializing param string for operation $operation");
7423 } elseif (is_array(
$params)) {
7424 $this->
debug(
"serializing param array for operation $operation");
7425 foreach (
$params as $k => $v) {
7429 $this->
debug(
'params must be array or string');
7430 $this->
setError(
'params must be array or string');
7434 if ($use ==
'encoded') {
7435 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7437 $encodingStyle =
'';
7441 if ($style ==
'rpc') {
7442 if ($use ==
'literal') {
7443 $this->
debug(
"wrapping RPC request with literal method element");
7446 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7448 "</$nsPrefix:$operation>";
7453 $this->
debug(
"wrapping RPC request with encoded method element");
7455 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7457 "</$nsPrefix:$operation>";
7467 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7468 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7470 $return = $this->
send($this->getHTTPBody($soapmsg), $soapAction, $this->timeout, $this->response_timeout);
7472 $this->
debug(
'Error: ' . $errstr);
7475 $this->
return = $return;
7476 $this->
debug(
'sent message successfully and got a(n) ' . gettype($return));
7480 if (is_array($return) && isset($return[
'faultcode'])) {
7481 $this->
debug(
'got fault');
7482 $this->
setError($return[
'faultcode'] .
': ' . $return[
'faultstring']);
7483 $this->fault =
true;
7484 foreach ($return as $k => $v) {
7486 $this->
debug(
"$k = $v<br>");
7489 } elseif ($style ==
'document') {
7495 if (is_array($return)) {
7498 if (
sizeof($return) > 1) {
7502 $return = array_shift($return);
7503 $this->
debug(
'return shifted value: ');
7519 public function checkWSDL()
7523 $this->
debug(
'checkWSDL');
7526 $this->
debug(
'got wsdl error: ' . $errstr);
7527 $this->
setError(
'wsdl error: ' . $errstr);
7529 $this->bindingType =
'soap';
7530 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7532 $this->bindingType =
'soap12';
7533 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7534 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7536 $this->
debug(
'getOperations returned false');
7537 $this->
setError(
'no operations defined in the WSDL document!');
7546 public function loadWSDL()
7548 $this->
debug(
'instantiating wsdl class with doc: ' . $this->wsdlFile);
7549 $this->
wsdl =
new wsdl(
'', $this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword, $this->timeout, $this->response_timeout, $this->curl_options, $this->use_curl);
7550 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7562 public function getOperationData($operation)
7564 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7570 if (isset($this->operations[$operation])) {
7571 return $this->operations[$operation];
7573 $this->
debug(
"No data for operation: $operation");
7590 public function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30)
7592 $this->checkCookies();
7596 case preg_match(
'/^http/', $this->endpoint):
7597 $this->
debug(
'transporting via HTTP');
7598 if ($this->persistentConnection ==
true && is_object($this->persistentConnection)) {
7599 $http =& $this->persistentConnection;
7602 if ($this->persistentConnection) {
7603 $http->usePersistentConnection();
7606 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7607 $http->setSOAPAction($soapaction);
7608 if ($this->proxyhost && $this->proxyport) {
7609 $http->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
7611 if ($this->authtype !=
'') {
7612 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7614 if ($this->http_encoding !=
'') {
7615 $http->setEncoding($this->http_encoding);
7617 $this->
debug(
'sending message, length=' . strlen($msg));
7618 if (preg_match(
'/^http:/', $this->endpoint)) {
7620 $this->responseData =
$http->send($msg, $timeout, $response_timeout, $this->cookies);
7621 } elseif (preg_match(
'/^https/', $this->endpoint)) {
7628 $this->responseData =
$http->sendHTTPS($msg, $timeout, $response_timeout, $this->cookies);
7630 $this->
setError(
'no http/s in endpoint url');
7632 $this->request =
$http->outgoing_payload;
7633 $this->response =
$http->incoming_payload;
7635 $this->UpdateCookies(
$http->incoming_cookies);
7638 if ($this->persistentConnection) {
7639 $http->clearDebug();
7640 if (!is_object($this->persistentConnection)) {
7641 $this->persistentConnection =
$http;
7645 if ($err =
$http->getError()) {
7646 $this->
setError(
'HTTP Error: ' . $err);
7651 $this->
debug(
'got response, length=' . strlen($this->responseData) .
' type=' .
$http->incoming_headers[
'content-type']);
7652 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7656 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7670 public function parseResponse($headers,
$data)
7672 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7674 if (!strstr($headers[
'content-type'],
'text/xml')) {
7675 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7678 if (strpos($headers[
'content-type'],
'=')) {
7679 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7680 $this->
debug(
'Got response encoding: ' . $enc);
7681 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
7682 $this->xml_encoding = strtoupper($enc);
7684 $this->xml_encoding =
'US-ASCII';
7688 $this->xml_encoding =
'ISO-8859-1';
7690 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7691 $parser =
new nusoap_parser(
$data, $this->xml_encoding, $this->operation, $this->decode_utf8);
7695 if ($errstr = $parser->getError()) {
7702 $this->responseHeaders = $parser->getHeaders();
7704 $this->responseHeader = $parser->get_soapheader();
7706 $return = $parser->get_soapbody();
7708 $this->document = $parser->document;
7723 public function setCurlOption($option, $value)
7725 $this->
debug(
"setCurlOption option=$option, value=");
7727 $this->curl_options[$option] = $value;
7736 public function setEndpoint($endpoint)
7738 $this->
debug(
"setEndpoint(\"$endpoint\")");
7739 $this->forceEndpoint = $endpoint;
7748 public function setHeaders($headers)
7750 $this->
debug(
"setHeaders headers=");
7752 $this->requestHeaders = $headers;
7761 public function getHeaders()
7763 return $this->responseHeaders;
7772 public function getHeader()
7774 return $this->responseHeader;
7786 public function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'')
7788 $this->proxyhost = $proxyhost;
7789 $this->proxyport = $proxyport;
7790 $this->proxyusername = $proxyusername;
7791 $this->proxypassword = $proxypassword;
7803 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
7805 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7807 $this->username = $username;
7808 $this->password = $password;
7809 $this->authtype = $authtype;
7810 $this->certRequest = $certRequest;
7819 public function setHTTPEncoding($enc=
'gzip, deflate')
7821 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7822 $this->http_encoding = $enc;
7831 public function setUseCURL($use)
7833 $this->
debug(
"setUseCURL($use)");
7834 $this->use_curl = $use;
7842 public function useHTTPPersistentConnection()
7844 $this->
debug(
"useHTTPPersistentConnection");
7845 $this->persistentConnection =
true;
7859 public function getDefaultRpcParams()
7861 return $this->defaultRpcParams;
7875 public function setDefaultRpcParams($rpcParams)
7877 $this->defaultRpcParams = $rpcParams;
7887 public function getProxy()
7890 $evalStr = $this->_getProxyClassCode($r);
7893 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7899 eval(
"\$proxy = new nusoap_proxy_$r('');");
7901 $proxy->endpointType =
'wsdl';
7902 $proxy->wsdlFile = $this->wsdlFile;
7903 $proxy->wsdl = $this->wsdl;
7904 $proxy->operations = $this->operations;
7905 $proxy->defaultRpcParams = $this->defaultRpcParams;
7908 $proxy->username = $this->username;
7909 $proxy->password = $this->password;
7910 $proxy->authtype = $this->authtype;
7911 $proxy->certRequest = $this->certRequest;
7912 $proxy->requestHeaders = $this->requestHeaders;
7913 $proxy->endpoint = $this->endpoint;
7914 $proxy->forceEndpoint = $this->forceEndpoint;
7915 $proxy->proxyhost = $this->proxyhost;
7916 $proxy->proxyport = $this->proxyport;
7917 $proxy->proxyusername = $this->proxyusername;
7918 $proxy->proxypassword = $this->proxypassword;
7919 $proxy->http_encoding = $this->http_encoding;
7920 $proxy->timeout = $this->timeout;
7921 $proxy->response_timeout = $this->response_timeout;
7922 $proxy->persistentConnection = &$this->persistentConnection;
7923 $proxy->decode_utf8 = $this->decode_utf8;
7924 $proxy->curl_options = $this->curl_options;
7925 $proxy->bindingType = $this->bindingType;
7926 $proxy->use_curl = $this->use_curl;
7936 public function _getProxyClassCode($r)
7938 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7940 if ($this->endpointType !=
'wsdl') {
7941 $evalStr =
'A proxy can only be created for a WSDL client';
7943 $evalStr =
"echo \"$evalStr\";";
7946 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7949 return "echo \"" . $this->
getError() .
"\";";
7953 foreach ($this->operations as $operation => $opData) {
7954 if ($operation !=
'') {
7956 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7958 $paramArrayStr =
'';
7959 $paramCommentStr =
'';
7960 foreach ($opData[
'input'][
'parts'] as
$name => $type) {
7961 $paramStr .=
"\$$name, ";
7962 $paramArrayStr .=
"'$name' => \$$name, ";
7963 $paramCommentStr .=
"$type \$$name, ";
7965 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7966 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7967 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7970 $paramArrayStr =
'';
7971 $paramCommentStr =
'void';
7973 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7974 $evalStr .=
"// $paramCommentStr 7975 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7976 \$params = array($paramArrayStr); 7977 return \$this->call('$operation', \$params, '" . $opData[
'namespace'] .
"', '" . (isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'') .
"'); 7981 unset($paramCommentStr);
7984 $evalStr =
'class nusoap_proxy_' . $r .
' extends nusoap_client { 7996 public function getProxyClassCode()
7999 return $this->_getProxyClassCode($r);
8009 public function getHTTPBody($soapmsg)
8022 public function getHTTPContentType()
8036 public function getHTTPContentTypeCharset()
8047 public function decodeUTF8($bool)
8049 $this->decode_utf8 = $bool;
8061 public function setCookie(
$name, $value)
8063 if (strlen(
$name) == 0) {
8066 $this->cookies[] = array(
'name' =>
$name,
'value' => $value);
8076 public function getCookies()
8078 return $this->cookies;
8087 public function checkCookies()
8089 if (
sizeof($this->cookies) == 0) {
8092 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
8093 $curr_cookies = $this->cookies;
8094 $this->cookies = array();
8095 foreach ($curr_cookies as $cookie) {
8096 if (! is_array($cookie)) {
8097 $this->
debug(
'Remove cookie that is not an array');
8100 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
8101 if (strtotime($cookie[
'expires']) > time()) {
8102 $this->cookies[] = $cookie;
8104 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
8107 $this->cookies[] = $cookie;
8110 $this->
debug(
'checkCookie: ' .
sizeof($this->cookies) .
' cookies left in array');
8121 public function UpdateCookies($cookies)
8123 if (
sizeof($this->cookies) == 0) {
8125 if (
sizeof($cookies) > 0) {
8126 $this->
debug(
'Setting new cookie(s)');
8127 $this->cookies = $cookies;
8131 if (
sizeof($cookies) == 0) {
8136 foreach ($cookies as $newCookie) {
8137 if (!is_array($newCookie)) {
8140 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
8143 $newName = $newCookie[
'name'];
8146 for (
$i = 0;
$i < count($this->cookies);
$i++) {
8147 $cookie = $this->cookies[
$i];
8148 if (!is_array($cookie)) {
8151 if (!isset($cookie[
'name'])) {
8154 if ($newName != $cookie[
'name']) {
8157 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
8158 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
8159 if ($newDomain != $domain) {
8162 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
8163 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
8164 if ($newPath !=
$path) {
8167 $this->cookies[
$i] = $newCookie;
8169 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8173 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8174 $this->cookies[] = $newCookie;
8181 if (!extension_loaded(
'soap')) {
if($err=$client->getError()) $namespace
appendDebug($string)
adds debug data to the instance debug string without formatting
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
setError($str)
sets error string
Contains information for a SOAP fault.
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
& getDebug()
gets the current debug data for this instance
if(empty($path)) $serviceName
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
parses a WSDL file, allows access to it's data, other utility methods.
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
if(count($parts) !=3) $payload
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed ...
serialize($debug=0)
serialize the parsed wsdl
For creating serializable abstractions of native PHP types.
catch(\Exception $e) $req
getError()
returns error string if present
debug($string)
adds debug data to the instance debug string with formatting
$messages
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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
__construct(Container $dic, ilPlugin $plugin)
expandEntities($val)
expands entities, e.g.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
$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)