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 =
'';
1138 public $attributes = array();
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');
1199 public function parseFile($xml, $type)
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)
1231 $this->parser = xml_parser_create();
1233 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1236 xml_set_object($this->parser, $this);
1239 if ($type ==
"schema") {
1240 xml_set_element_handler($this->parser,
'schemaStartElement',
'schemaEndElement');
1241 xml_set_character_data_handler($this->parser,
'schemaCharacterData');
1242 } elseif ($type ==
"xml") {
1243 xml_set_element_handler($this->parser,
'xmlStartElement',
'xmlEndElement');
1244 xml_set_character_data_handler($this->parser,
'xmlCharacterData');
1248 if (!xml_parse($this->parser, $xml,
true)) {
1251 'XML error parsing XML schema on line %d: %s',
1252 xml_get_current_line_number($this->parser),
1253 xml_error_string(xml_get_error_code($this->parser))
1255 $this->
debug($errstr);
1256 $this->
debug(
"XML payload:\n" . $xml);
1260 xml_parser_free($this->parser);
1262 $this->
debug(
'no xml passed to parseString()!!');
1263 $this->
setError(
'no xml passed to parseString()!!');
1274 public function CreateTypeName($ename)
1277 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1278 $scope .= $this->complexTypeStack[$i] .
'_';
1280 return $scope . $ename .
'_ContainedType';
1291 public function schemaStartElement($parser, $name, $attrs)
1295 $pos = $this->position++;
1296 $depth = $this->depth++;
1298 $this->depth_array[$depth] = $pos;
1299 $this->message[$pos] = array(
'cdata' =>
'');
1301 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1303 $this->defaultNamespace[$pos] =
false;
1307 if ($prefix = $this->
getPrefix($name)) {
1315 if (count($attrs) > 0) {
1316 foreach ($attrs as $k => $v) {
1318 if (preg_match(
'/^xmlns/', $k)) {
1321 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
1323 $this->namespaces[$ns_prefix] = $v;
1325 $this->defaultNamespace[$pos] = $v;
1327 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $v;
1330 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
1331 $this->XMLSchemaVersion = $v;
1332 $this->namespaces[
'xsi'] = $v .
'-instance';
1336 foreach ($attrs as $k => $v) {
1338 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1339 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1353 $this->complexTypes[$this->currentComplexType][
'compositor'] = $name;
1360 $this->xdebug(
"parsing attribute:");
1362 if (!isset($attrs[
'form'])) {
1363 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1365 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1366 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1367 if (!strpos($v,
':')) {
1369 if ($this->defaultNamespace[$pos]) {
1371 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1375 if (isset($attrs[
'name'])) {
1376 $this->attributes[$attrs[
'name']] = $attrs;
1377 $aname = $attrs[
'name'];
1378 } elseif (isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
1379 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1380 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1384 } elseif (isset($attrs[
'ref'])) {
1385 $aname = $attrs[
'ref'];
1386 $this->attributes[$attrs[
'ref']] = $attrs;
1389 if ($this->currentComplexType) {
1390 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1393 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType') {
1394 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1396 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1397 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1401 if (strpos($v,
'[,]')) {
1402 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1404 $v = substr($v, 0, strpos($v,
'['));
1405 if (!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
1406 $v = $this->XMLSchemaVersion .
':' . $v;
1408 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1411 case 'complexContent':
1414 array_push($this->complexTypeStack, $this->currentComplexType);
1415 if (isset($attrs[
'name'])) {
1418 $this->xdebug(
'processing named complexType ' . $attrs[
'name']);
1420 $this->currentComplexType = $attrs[
'name'];
1421 $this->complexTypes[$this->currentComplexType] = $attrs;
1422 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1430 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1431 $this->xdebug(
'complexType is unusual array');
1432 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1434 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1437 $name = $this->CreateTypeName($this->currentElement);
1438 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' . $name);
1439 $this->currentComplexType = $name;
1441 $this->complexTypes[$this->currentComplexType] = $attrs;
1442 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1450 if (isset($attrs[
'base']) && preg_match(
'/:Array$/', $attrs[
'base'])) {
1451 $this->xdebug(
'complexType is unusual array');
1452 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1454 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1459 array_push($this->elementStack, $this->currentElement);
1460 if (!isset($attrs[
'form'])) {
1461 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1463 if (isset($attrs[
'type'])) {
1464 $this->xdebug(
"processing typed element " . $attrs[
'name'] .
" of type " . $attrs[
'type']);
1465 if (! $this->
getPrefix($attrs[
'type'])) {
1466 if ($this->defaultNamespace[$pos]) {
1467 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1468 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1478 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1479 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1480 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1482 $this->currentElement = $attrs[
'name'];
1483 $ename = $attrs[
'name'];
1484 } elseif (isset($attrs[
'ref'])) {
1485 $this->xdebug(
"processing element as ref to " . $attrs[
'ref']);
1486 $this->currentElement =
"ref to " . $attrs[
'ref'];
1489 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1490 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' . $type);
1491 $this->currentElement = $attrs[
'name'];
1492 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $type;
1493 $ename = $attrs[
'name'];
1495 if (isset($ename) && $this->currentComplexType) {
1496 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1497 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1498 } elseif (!isset($attrs[
'ref'])) {
1499 $this->xdebug(
"add element $ename to elements array");
1500 $this->elements[ $attrs[
'name'] ] = $attrs;
1501 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1505 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1506 if ($this->currentSimpleType) {
1507 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1508 } elseif ($this->currentComplexType) {
1509 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1513 $this->xdebug(
'extension ' . $attrs[
'base']);
1514 if ($this->currentComplexType) {
1515 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1519 if (isset($attrs[
'schemaLocation'])) {
1521 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1524 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1526 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
1533 $this->xdebug(
'restriction ' . $attrs[
'base']);
1534 if ($this->currentSimpleType) {
1535 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1536 } elseif ($this->currentComplexType) {
1537 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1538 if (strstr($attrs[
'base'],
':') ==
':Array') {
1539 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1544 $this->schemaInfo = $attrs;
1546 if (isset($attrs[
'targetNamespace'])) {
1547 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1549 if (!isset($attrs[
'elementFormDefault'])) {
1550 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1552 if (!isset($attrs[
'attributeFormDefault'])) {
1553 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1556 case 'simpleContent':
1559 array_push($this->simpleTypeStack, $this->currentSimpleType);
1560 if (isset($attrs[
'name'])) {
1561 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1562 $this->currentSimpleType = $attrs[
'name'];
1563 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1564 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1565 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1567 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1568 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' . $name);
1569 $this->currentSimpleType = $name;
1571 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1572 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1589 public function schemaEndElement($parser, $name)
1594 if (isset($this->depth_array[$this->depth])) {
1595 $pos = $this->depth_array[$this->depth];
1598 if ($prefix = $this->
getPrefix($name)) {
1605 if ($name ==
'complexType') {
1606 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1607 $this->currentComplexType = array_pop($this->complexTypeStack);
1610 if ($name ==
'element') {
1611 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1612 $this->currentElement = array_pop($this->elementStack);
1614 if ($name ==
'simpleType') {
1615 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1616 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1627 public function schemaCharacterData($parser,
$data)
1629 $pos = $this->depth_array[$this->depth - 1];
1630 $this->message[$pos][
'cdata'] .=
$data;
1638 public function serializeSchema()
1643 if (
sizeof($this->imports) > 0) {
1644 foreach ($this->imports as $ns => $list) {
1645 foreach ($list as $ii) {
1646 if ($ii[
'location'] !=
'') {
1647 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1649 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1655 foreach ($this->complexTypes as $typeName => $attrs) {
1658 if (isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)) {
1659 foreach ($attrs[
'elements'] as $element => $eParts) {
1660 if (isset($eParts[
'ref'])) {
1661 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1663 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1664 foreach ($eParts as $aName => $aValue) {
1666 if ($aName !=
'name' && $aName !=
'type') {
1667 $contentStr .=
" $aName=\"$aValue\"";
1670 $contentStr .=
"/>\n";
1674 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1675 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n" . $contentStr .
" </$schemaPrefix:$attrs[compositor]>\n";
1679 if (isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)) {
1680 foreach ($attrs[
'attrs'] as $attr => $aParts) {
1681 $contentStr .=
" <$schemaPrefix:attribute";
1682 foreach ($aParts as
$a => $v) {
1683 if (
$a ==
'ref' ||
$a ==
'type') {
1684 $contentStr .=
" $a=\"" . $this->contractQName($v) .
'"';
1685 } elseif (
$a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1686 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1687 $contentStr .=
' wsdl:arrayType="' . $this->contractQName($v) .
'"';
1689 $contentStr .=
" $a=\"$v\"";
1692 $contentStr .=
"/>\n";
1696 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
'') {
1697 $contentStr =
" <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs[
'restrictionBase']) .
"\">\n" . $contentStr .
" </$schemaPrefix:restriction>\n";
1699 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)) {
1700 $contentStr =
" <$schemaPrefix:complexContent>\n" . $contentStr .
" </$schemaPrefix:complexContent>\n";
1704 if ($contentStr !=
'') {
1705 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr .
" </$schemaPrefix:complexType>\n";
1707 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1709 $xml .= $contentStr;
1712 if (isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
1713 foreach ($this->simpleTypes as $typeName => $eParts) {
1714 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts[
'type']) .
"\">\n";
1715 if (isset($eParts[
'enumeration'])) {
1716 foreach ($eParts[
'enumeration'] as
$e) {
1717 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1720 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1724 if (isset($this->elements) && count($this->elements) > 0) {
1725 foreach ($this->elements as $element => $eParts) {
1726 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"/>\n";
1730 if (isset($this->attributes) && count($this->attributes) > 0) {
1731 foreach ($this->attributes as $attr => $aParts) {
1732 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts[
'type']) .
"\"\n/>";
1737 foreach ($this->schemaInfo as $k => $v) {
1738 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1739 $attr .=
" $k=\"$v\"";
1742 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1743 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1744 $el .=
" xmlns:$nsp=\"$ns\"";
1746 $xml = $el .
">\n" . $xml .
"</$schemaPrefix:schema>\n";
1756 public function xdebug($string)
1758 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> ' . $string);
1773 public function getPHPType($type, $ns)
1775 if (isset($this->typemap[$ns][$type])) {
1777 return $this->typemap[$ns][$type];
1778 } elseif (isset($this->complexTypes[$type])) {
1780 return $this->complexTypes[$type][
'phpType'];
1807 public function getTypeDef($type)
1810 if (substr($type, -1) ==
'^') {
1812 $type = substr($type, 0, -1);
1817 if ((! $is_element) && isset($this->complexTypes[$type])) {
1818 $this->xdebug(
"in getTypeDef, found complexType $type");
1819 return $this->complexTypes[$type];
1820 } elseif ((! $is_element) && isset($this->simpleTypes[$type])) {
1821 $this->xdebug(
"in getTypeDef, found simpleType $type");
1822 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1825 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1826 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1827 $etype = $this->getTypeDef($uqType);
1829 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1830 $this->xdebug($this->
varDump($etype));
1831 if (isset($etype[
'phpType'])) {
1832 $this->simpleTypes[$type][
'phpType'] = $etype[
'phpType'];
1834 if (isset($etype[
'elements'])) {
1835 $this->simpleTypes[$type][
'elements'] = $etype[
'elements'];
1839 return $this->simpleTypes[$type];
1840 } elseif (isset($this->elements[$type])) {
1841 $this->xdebug(
"in getTypeDef, found element $type");
1842 if (!isset($this->elements[$type][
'phpType'])) {
1844 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1845 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1846 $etype = $this->getTypeDef($uqType);
1848 $this->xdebug(
"in getTypeDef, found type for element $type:");
1849 $this->xdebug($this->
varDump($etype));
1850 if (isset($etype[
'phpType'])) {
1851 $this->elements[$type][
'phpType'] = $etype[
'phpType'];
1853 if (isset($etype[
'elements'])) {
1854 $this->elements[$type][
'elements'] = $etype[
'elements'];
1856 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1857 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1858 $this->elements[$type][
'phpType'] =
'scalar';
1861 return $this->elements[$type];
1862 } elseif (isset($this->attributes[$type])) {
1863 $this->xdebug(
"in getTypeDef, found attribute $type");
1864 return $this->attributes[$type];
1865 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1866 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1867 $typeDef[
'typeClass'] =
'simpleType';
1868 $typeDef[
'phpType'] =
'scalar';
1869 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1872 $this->xdebug(
"in getTypeDef, did not find $type");
1884 public function serializeTypeDef($type)
1887 if ($typeDef = $this->getTypeDef($type)) {
1888 $str .=
'<' . $type;
1889 if (is_array($typeDef[
'attrs'])) {
1890 foreach ($typeDef[
'attrs'] as $attName =>
$data) {
1891 $str .=
" $attName=\"{type = " .
$data[
'type'] .
"}\"";
1894 $str .=
" xmlns=\"" . $this->schema[
'targetNamespace'] .
"\"";
1895 if (count($typeDef[
'elements']) > 0) {
1897 foreach ($typeDef[
'elements'] as $element => $eData) {
1898 $str .= $this->serializeTypeDef($element);
1901 } elseif ($typeDef[
'typeClass'] ==
'element') {
1902 $str .=
"></$type>";
1921 public function typeToForm($name, $type)
1924 if ($typeDef = $this->getTypeDef($type)) {
1926 if ($typeDef[
'phpType'] ==
'struct') {
1927 $buffer .=
'<table>';
1928 foreach ($typeDef[
'elements'] as $child => $childDef) {
1930 <tr><td align='right'>$childDef[name] (type: " . $this->
getLocalPart($childDef[
'type']) .
"):</td> 1931 <td><input type='text' name='parameters[" . $name .
"][$childDef[name]]'></td></tr>";
1933 $buffer .=
'</table>';
1935 } elseif ($typeDef[
'phpType'] ==
'array') {
1936 $buffer .=
'<table>';
1937 for ($i=0;$i < 3; $i++) {
1939 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1940 <td><input type='text' name='parameters[" . $name .
"][]'></td></tr>";
1942 $buffer .=
'</table>';
1945 $buffer .=
"<input type='text' name='parameters[$name]'>";
1948 $buffer .=
"<input type='text' name='parameters[$name]'>";
1994 public function addComplexType($name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
1996 $this->complexTypes[$name] = array(
1998 'typeClass' => $typeClass,
1999 'phpType' => $phpType,
2000 'compositor'=> $compositor,
2001 'restrictionBase' => $restrictionBase,
2002 'elements' => $elements,
2004 'arrayType' => $arrayType
2007 $this->xdebug(
"addComplexType $name:");
2023 public function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
2025 $this->simpleTypes[$name] = array(
2027 'typeClass' => $typeClass,
2028 'phpType' => $phpType,
2029 'type' => $restrictionBase,
2030 'enumeration' => $enumeration
2033 $this->xdebug(
"addSimpleType $name:");
2044 public function addElement($attrs)
2046 if (! $this->
getPrefix($attrs[
'type'])) {
2047 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
2049 $this->elements[ $attrs[
'name'] ] = $attrs;
2050 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
2052 $this->xdebug(
"addElement " . $attrs[
'name']);
2135 public function __construct($name=
'soapval', $type=
false, $value=-1, $element_ns=
false, $type_ns=
false, $attributes=
false)
2138 $this->name = $name;
2139 $this->type = $type;
2140 $this->value = $value;
2141 $this->element_ns = $element_ns;
2142 $this->type_ns = $type_ns;
2143 $this->attributes = $attributes;
2153 public function serialize($use=
'encoded')
2155 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2164 public function decode()
2166 return $this->value;
2189 public $digest_uri =
'';
2190 public $scheme =
'';
2194 public $request_method =
'POST';
2195 public $protocol_version =
'1.0';
2196 public $encoding =
'';
2197 public $outgoing_headers = array();
2198 public $incoming_headers = array();
2199 public $incoming_cookies = array();
2200 public $outgoing_payload =
'';
2201 public $incoming_payload =
'';
2202 public $response_status_line;
2203 public $useSOAPAction =
true;
2204 public $persistentConnection =
false;
2206 public $ch_options = array();
2207 public $use_curl =
false;
2208 public $proxy = null;
2209 public $username =
'';
2210 public $password =
'';
2211 public $authtype =
'';
2212 public $digestRequest = array();
2213 public $certRequest = array();
2230 public function __construct($url, $curl_options = null, $use_curl =
false)
2233 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2235 $this->setURL($url);
2236 if (is_array($curl_options)) {
2237 $this->ch_options = $curl_options;
2239 $this->use_curl = $use_curl;
2240 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2242 $this->setHeader(
'User-Agent', $this->title .
'/' . $this->version .
' (' . ($rev[1] ??
'1.1') .
')');
2252 public function setCurlOption($option, $value)
2254 $this->
debug(
"setCurlOption option=$option, value=");
2256 curl_setopt($this->ch, $option, $value);
2266 public function setHeader($name, $value)
2268 $this->outgoing_headers[$name] = $value;
2269 $this->
debug(
"set header $name: $value");
2278 public function unsetHeader($name)
2280 if (isset($this->outgoing_headers[$name])) {
2281 $this->
debug(
"unset header $name");
2282 unset($this->outgoing_headers[$name]);
2292 public function setURL($url)
2296 $u = parse_url($url);
2297 foreach ($u as $k => $v) {
2298 $this->
debug(
"parsed URL $k = $v");
2303 if (isset($u[
'query']) && $u[
'query'] !=
'') {
2304 $this->path .=
'?' . $u[
'query'];
2308 if (!isset($u[
'port'])) {
2309 if ($u[
'scheme'] ==
'https') {
2317 $this->digest_uri = $this->uri;
2320 if (!isset($u[
'port'])) {
2321 $this->setHeader(
'Host', $this->host);
2323 $this->setHeader(
'Host', $this->host .
':' . $this->port);
2326 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2327 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2337 public function io_method()
2339 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm')) {
2342 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm')) {
2356 public function connect($connection_timeout=0, $response_timeout=30)
2370 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2371 if ($this->io_method() ==
'socket') {
2372 if (!is_array($this->proxy)) {
2373 $host = $this->host;
2374 $port = $this->port;
2376 $host = $this->proxy[
'host'];
2377 $port = $this->proxy[
'port'];
2381 if ($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
2382 if (!feof($this->fp)) {
2383 $this->
debug(
'Re-use persistent connection');
2387 $this->
debug(
'Closed persistent connection at EOF');
2391 if ($this->scheme ==
'ssl') {
2392 $host =
'ssl://' . $host;
2394 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2397 if ($connection_timeout > 0) {
2398 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2400 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
2405 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2409 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2417 $this->
debug(
'set response timeout to ' . $response_timeout);
2418 socket_set_timeout($this->fp, $response_timeout);
2420 $this->
debug(
'socket connected');
2422 } elseif ($this->io_method() ==
'curl') {
2423 if (!extension_loaded(
'curl')) {
2425 $this->
setError(
'The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to included cURL.');
2429 if (defined(
'CURLOPT_CONNECTIONTIMEOUT')) {
2430 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2432 $CURLOPT_CONNECTIONTIMEOUT = 78;
2434 if (defined(
'CURLOPT_HTTPAUTH')) {
2435 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2437 $CURLOPT_HTTPAUTH = 107;
2439 if (defined(
'CURLOPT_PROXYAUTH')) {
2440 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2442 $CURLOPT_PROXYAUTH = 111;
2444 if (defined(
'CURLAUTH_BASIC')) {
2445 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2447 $CURLAUTH_BASIC = 1;
2449 if (defined(
'CURLAUTH_DIGEST')) {
2450 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2452 $CURLAUTH_DIGEST = 2;
2454 if (defined(
'CURLAUTH_NTLM')) {
2455 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2460 $this->
debug(
'connect using cURL');
2462 $this->ch = curl_init();
2464 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2467 $this->setCurlOption(CURLOPT_URL, $hostURL);
2469 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2470 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2471 $this->
debug(
'safe_mode = ');
2473 $this->
debug(
'open_basedir = ');
2476 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2479 $this->setCurlOption(CURLOPT_HEADER, 1);
2481 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2488 if ($this->persistentConnection) {
2494 $this->persistentConnection =
false;
2495 $this->setHeader(
'Connection',
'close');
2498 if ($connection_timeout != 0) {
2499 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2501 if ($response_timeout != 0) {
2502 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2505 if ($this->scheme ==
'https') {
2506 $this->
debug(
'set cURL SSL verify options');
2511 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2512 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2515 if ($this->authtype ==
'certificate') {
2516 $this->
debug(
'set cURL certificate options');
2517 if (isset($this->certRequest[
'cainfofile'])) {
2518 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2520 if (isset($this->certRequest[
'verifypeer'])) {
2521 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2523 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2525 if (isset($this->certRequest[
'verifyhost'])) {
2526 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2528 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2530 if (isset($this->certRequest[
'sslcertfile'])) {
2531 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2533 if (isset($this->certRequest[
'sslkeyfile'])) {
2534 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2536 if (isset($this->certRequest[
'passphrase'])) {
2537 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2539 if (isset($this->certRequest[
'certpassword'])) {
2540 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2544 if ($this->authtype && ($this->authtype !=
'certificate')) {
2545 if ($this->username) {
2546 $this->
debug(
'set cURL username/password');
2547 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2549 if ($this->authtype ==
'basic') {
2550 $this->
debug(
'set cURL for Basic authentication');
2551 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2553 if ($this->authtype ==
'digest') {
2554 $this->
debug(
'set cURL for digest authentication');
2555 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2557 if ($this->authtype ==
'ntlm') {
2558 $this->
debug(
'set cURL for NTLM authentication');
2559 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2562 if (is_array($this->proxy)) {
2563 $this->
debug(
'set cURL proxy options');
2564 if ($this->proxy[
'port'] !=
'') {
2565 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'] .
':' . $this->proxy[
'port']);
2567 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2569 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2570 $this->
debug(
'set cURL proxy authentication options');
2571 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'] .
':' . $this->proxy[
'password']);
2572 if ($this->proxy[
'authtype'] ==
'basic') {
2573 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2575 if ($this->proxy[
'authtype'] ==
'ntlm') {
2576 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2580 $this->
debug(
'cURL connection set up');
2583 $this->
setError(
'Unknown scheme ' . $this->scheme);
2584 $this->
debug(
'Unknown scheme ' . $this->scheme);
2599 public function send(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2601 $this->
debug(
'entered send() with data of length: ' . strlen(
$data));
2603 $this->tryagain =
true;
2605 while ($this->tryagain) {
2606 $this->tryagain =
false;
2609 if (!$this->connect($timeout, $response_timeout)) {
2614 if (!$this->sendRequest(
$data, $cookies)) {
2619 $respdata = $this->getResponse();
2621 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2624 $this->
debug(
'end of send()');
2640 public function sendHTTPS(
$data, $timeout=0, $response_timeout=30, $cookies=null)
2642 return $this->
send(
$data, $timeout, $response_timeout, $cookies);
2655 public function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array())
2657 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2659 $this->
debug(
"certRequest=");
2662 if ($authtype ==
'basic') {
2663 $this->setHeader(
'Authorization',
'Basic ' . base64_encode(str_replace(
':',
'', $username) .
':' . $password));
2664 } elseif ($authtype ==
'digest') {
2665 if (isset($digestRequest[
'nonce'])) {
2666 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2671 $A1 = $username .
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2677 $A2 = $this->request_method .
':' . $this->digest_uri;
2693 $unhashedDigest =
'';
2694 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2696 if ($digestRequest[
'qop'] !=
'') {
2697 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2699 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2702 $hashedDigest = md5($unhashedDigest);
2705 if (isset($digestRequest[
'opaque'])) {
2706 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2709 $this->setHeader(
'Authorization',
'Digest username="' . $username .
'", realm="' . $digestRequest[
'realm'] .
'", nonce="' . $nonce .
'", uri="' . $this->digest_uri . $opaque .
'", cnonce="' . $cnonce .
'", nc=' . sprintf(
"%08x", $digestRequest[
'nc']) .
', qop="' . $digestRequest[
'qop'] .
'", response="' . $hashedDigest .
'"');
2711 } elseif ($authtype ==
'certificate') {
2712 $this->certRequest = $certRequest;
2713 $this->
debug(
'Authorization header not set for certificate');
2714 } elseif ($authtype ==
'ntlm') {
2716 $this->
debug(
'Authorization header not set for ntlm');
2718 $this->username = $username;
2719 $this->password = $password;
2720 $this->authtype = $authtype;
2721 $this->digestRequest = $digestRequest;
2730 public function setSOAPAction($soapaction)
2732 $this->setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2741 public function setEncoding($enc=
'gzip, deflate')
2743 if (function_exists(
'gzdeflate')) {
2744 $this->protocol_version =
'1.1';
2745 $this->setHeader(
'Accept-Encoding', $enc);
2746 if (!isset($this->outgoing_headers[
'Connection'])) {
2747 $this->setHeader(
'Connection',
'close');
2748 $this->persistentConnection =
false;
2750 #set_magic_quotes_runtime(0); 2752 $this->encoding = $enc;
2766 public function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic')
2769 $this->proxy = array(
2770 'host' => $proxyhost,
2771 'port' => $proxyport,
2772 'username' => $proxyusername,
2773 'password' => $proxypassword,
2774 'authtype' => $proxyauthtype
2776 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2777 $this->setHeader(
'Proxy-Authorization',
' Basic ' . base64_encode($proxyusername .
':' . $proxypassword));
2780 $this->
debug(
'remove proxy');
2782 unsetHeader(
'Proxy-Authorization');
2795 public function isSkippableCurlHeader(&
$data)
2797 $skipHeaders = array(
'HTTP/1.1 100',
2804 'HTTP/1.0 200 Connection established');
2805 foreach ($skipHeaders as $hd) {
2806 $prefix = substr(
$data, 0, strlen($hd));
2807 if ($prefix == $hd) {
2825 public function decodeChunked($buffer, $lb)
2833 $chunkend = strpos($buffer, $lb);
2834 if ($chunkend ==
false) {
2835 $this->
debug(
'no linebreak found in decodeChunked');
2838 $temp = substr($buffer, 0, $chunkend);
2839 $chunk_size = hexdec(trim($temp));
2840 $chunkstart = $chunkend + strlen($lb);
2842 while ($chunk_size > 0) {
2843 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2844 $chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
2847 if ($chunkend ==
false) {
2848 $chunk = substr($buffer, $chunkstart);
2851 $length += strlen($chunk);
2856 $chunk = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2860 $length += strlen($chunk);
2862 $chunkstart = $chunkend + strlen($lb);
2864 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2865 if ($chunkend ==
false) {
2868 $temp = substr($buffer, $chunkstart, $chunkend-$chunkstart);
2869 $chunk_size = hexdec(trim($temp));
2870 $chunkstart = $chunkend;
2883 public function buildPayload(
$data, $cookie_str =
'')
2890 $this->setHeader(
'Content-Length', strlen(
$data));
2898 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2899 $this->
debug(
"HTTP request: $req");
2900 $this->outgoing_payload =
"$req\r\n";
2903 foreach ($this->outgoing_headers as $k => $v) {
2904 $hdr = $k .
': ' . $v;
2905 $this->
debug(
"HTTP header: $hdr");
2906 $this->outgoing_payload .=
"$hdr\r\n";
2910 if ($cookie_str !=
'') {
2911 $hdr =
'Cookie: ' . $cookie_str;
2912 $this->
debug(
"HTTP header: $hdr");
2913 $this->outgoing_payload .=
"$hdr\r\n";
2917 $this->outgoing_payload .=
"\r\n";
2920 $this->outgoing_payload .=
$data;
2931 public function sendRequest(
$data, $cookies = null)
2934 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2937 $this->buildPayload(
$data, $cookie_str);
2939 if ($this->io_method() ==
'socket') {
2941 if (!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2942 $this->
setError(
'couldn\'t write message data to socket');
2943 $this->
debug(
'couldn\'t write message data to socket');
2946 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2948 } elseif ($this->io_method() ==
'curl') {
2954 $curl_headers = array();
2955 foreach ($this->outgoing_headers as $k => $v) {
2956 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2957 $this->
debug(
"Skip cURL header $k: $v");
2959 $curl_headers[] =
"$k: $v";
2962 if ($cookie_str !=
'') {
2963 $curl_headers[] =
'Cookie: ' . $cookie_str;
2965 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2966 $this->
debug(
'set cURL HTTP headers');
2967 if ($this->request_method ==
"POST") {
2968 $this->setCurlOption(CURLOPT_POST, 1);
2969 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2970 $this->
debug(
'set cURL POST data');
2974 foreach ($this->ch_options as
$key => $val) {
2975 $this->setCurlOption(
$key, $val);
2978 $this->
debug(
'set cURL payload');
2989 public function getResponse()
2991 $this->incoming_payload =
'';
2993 if ($this->io_method() ==
'socket') {
2996 while (!isset($lb)) {
2998 if (feof($this->fp)) {
2999 $this->incoming_payload =
$data;
3000 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
3001 $this->
debug(
"received before EOF:\n" .
$data);
3002 $this->
setError(
'server failed to send headers');
3006 $tmp = fgets($this->fp, 256);
3007 $tmplen = strlen($tmp);
3008 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
3011 $this->incoming_payload =
$data;
3012 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
3013 $this->
debug(
"read before timeout: " .
$data);
3014 $this->
setError(
'socket read of headers timed out');
3019 $pos = strpos(
$data,
"\r\n\r\n");
3023 $pos = strpos(
$data,
"\n\n");
3029 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3035 $this->incoming_payload .=
$data;
3036 $this->
debug(
'found end of headers after length ' . strlen(
$data));
3038 $header_data = trim(substr(
$data, 0, $pos));
3039 $header_array = explode($lb, $header_data);
3040 $this->incoming_headers = array();
3041 $this->incoming_cookies = array();
3042 foreach ($header_array as $header_line) {
3043 $arr = explode(
':', $header_line, 2);
3044 if (count($arr) > 1) {
3045 $header_name = strtolower(trim($arr[0]));
3046 $this->incoming_headers[$header_name] = trim($arr[1]);
3047 if ($header_name ==
'set-cookie') {
3049 $cookie = $this->parseCookie(trim($arr[1]));
3051 $this->incoming_cookies[] = $cookie;
3052 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3054 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3057 } elseif (isset($header_name)) {
3059 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3064 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
3065 $content_length = 2147483647;
3067 $this->
debug(
"want to read chunked content");
3068 } elseif (isset($this->incoming_headers[
'content-length'])) {
3069 $content_length = $this->incoming_headers[
'content-length'];
3071 $this->
debug(
"want to read content of length $content_length");
3073 $content_length = 2147483647;
3075 $this->
debug(
"want to read content to EOF");
3080 $tmp = fgets($this->fp, 256);
3081 $tmplen = strlen($tmp);
3082 $this->
debug(
"read chunk line of $tmplen bytes");
3084 $this->incoming_payload =
$data;
3085 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3086 $this->
debug(
"read before timeout:\n" .
$data);
3087 $this->
setError(
'socket read of chunk length timed out');
3090 $content_length = hexdec(trim($tmp));
3091 $this->
debug(
"chunk length $content_length");
3094 while (($strlen < $content_length) && (!feof($this->fp))) {
3095 $readlen = min(8192, $content_length - $strlen);
3096 $tmp = fread($this->fp, $readlen);
3097 $tmplen = strlen($tmp);
3098 $this->
debug(
"read buffer of $tmplen bytes");
3099 if (($tmplen == 0) && (!feof($this->fp))) {
3100 $this->incoming_payload =
$data;
3101 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3102 $this->
debug(
"read before timeout:\n" .
$data);
3103 $this->
setError(
'socket read of body timed out');
3109 if ($chunked && ($content_length > 0)) {
3110 $tmp = fgets($this->fp, 256);
3111 $tmplen = strlen($tmp);
3112 $this->
debug(
"read chunk terminator of $tmplen bytes");
3114 $this->incoming_payload =
$data;
3115 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3116 $this->
debug(
"read before timeout:\n" .
$data);
3117 $this->
setError(
'socket read of chunk terminator timed out');
3121 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3122 if (feof($this->fp)) {
3123 $this->
debug(
'read to EOF');
3125 $this->
debug(
'read body of length ' . strlen(
$data));
3126 $this->incoming_payload .=
$data;
3127 $this->
debug(
'received a total of ' . strlen($this->incoming_payload) .
' bytes of data from server');
3131 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3132 (! $this->persistentConnection) || feof($this->fp)) {
3135 $this->
debug(
'closed socket');
3139 if ($this->incoming_payload ==
'') {
3140 $this->
setError(
'no response from server');
3154 } elseif ($this->io_method() ==
'curl') {
3156 $this->
debug(
'send and receive with cURL');
3157 $this->incoming_payload = curl_exec($this->ch);
3158 $data = $this->incoming_payload;
3160 $cErr = curl_error($this->ch);
3162 $err =
'cURL ERROR: ' . curl_errno($this->ch) .
': ' . $cErr .
'<br>';
3164 foreach (curl_getinfo($this->ch) as $k => $v) {
3165 $err .=
"$k: $v<br>";
3169 curl_close($this->ch);
3177 $this->
debug(
'No cURL error, closing cURL');
3178 curl_close($this->ch);
3182 while ($this->isSkippableCurlHeader(
$data)) {
3183 $this->
debug(
"Found HTTP header to skip");
3184 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3186 } elseif ($pos = strpos(
$data,
"\n\n")) {
3194 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3195 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3197 } elseif ($pos = strpos(
$data,
"\n\n")) {
3204 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3206 } elseif ($pos = strpos(
$data,
"\n\n")) {
3209 $this->
debug(
'no proper separation of headers and document');
3210 $this->
setError(
'no proper separation of headers and document');
3213 $header_data = trim(substr(
$data, 0, $pos));
3214 $header_array = explode($lb, $header_data);
3216 $this->
debug(
'found proper separation of headers and document');
3217 $this->
debug(
'cleaned data, stringlen: ' . strlen(
$data));
3219 foreach ($header_array as $header_line) {
3220 $arr = explode(
':', $header_line, 2);
3221 if (count($arr) > 1) {
3222 $header_name = strtolower(trim($arr[0]));
3223 $this->incoming_headers[$header_name] = trim($arr[1]);
3224 if ($header_name ==
'set-cookie') {
3226 $cookie = $this->parseCookie(trim($arr[1]));
3228 $this->incoming_cookies[] = $cookie;
3229 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3231 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3234 } elseif (isset($header_name)) {
3236 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3241 $this->response_status_line = $header_array[0];
3242 $arr = explode(
' ', $this->response_status_line, 3);
3243 $http_version = $arr[0];
3244 $http_status = intval($arr[1]);
3245 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3248 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3249 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3250 $this->setURL($this->incoming_headers[
'location']);
3251 $this->tryagain =
true;
3256 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3257 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3258 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3259 $this->
debug(
'Server wants digest authentication');
3261 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3264 $digestElements = explode(
',', $digestString);
3265 foreach ($digestElements as $val) {
3266 $tempElement = explode(
'=', trim($val), 2);
3267 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3271 if (isset($digestRequest[
'nonce'])) {
3272 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3273 $this->tryagain =
true;
3277 $this->
debug(
'HTTP authentication failed');
3278 $this->
setError(
'HTTP authentication failed');
3283 ($http_status >= 300 && $http_status <= 307) ||
3284 ($http_status >= 400 && $http_status <= 417) ||
3285 ($http_status >= 501 && $http_status <= 505)
3287 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3292 if (isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
'') {
3293 if (strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip') {
3295 if (function_exists(
'gzinflate')) {
3299 $this->
debug(
'The gzinflate function exists');
3300 $datalen = strlen(
$data);
3301 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3302 if ($degzdata = @gzinflate(
$data)) {
3304 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3305 if (strlen(
$data) < $datalen) {
3307 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3308 if ($degzdata = @gzinflate(
$data)) {
3310 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3314 $this->
debug(
'Error using gzinflate to inflate the payload');
3315 $this->
setError(
'Error using gzinflate to inflate the payload');
3317 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3318 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3320 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3321 if (strlen(
$data) < $datalen) {
3323 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3324 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3326 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3330 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3331 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3337 $this->incoming_payload = $header_data . $lb . $lb .
$data;
3339 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3340 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3343 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3344 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3347 $this->
debug(
'No Content-Encoding header');
3350 if (strlen(
$data) == 0) {
3351 $this->
debug(
'no data after headers!');
3352 $this->
setError(
'no data present after HTTP headers');
3366 public function setContentType($type, $charset =
false)
3368 $this->setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3377 public function usePersistentConnection()
3379 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3382 $this->protocol_version =
'1.1';
3383 $this->persistentConnection =
true;
3384 $this->setHeader(
'Connection',
'Keep-Alive');
3398 public function parseCookie($cookie_str)
3400 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3403 $data = explode(
';', $cookie_str);
3404 $value_str =
$data[0];
3406 $cookie_param =
'domain=';
3407 $start = strpos($cookie_str, $cookie_param);
3409 $domain = substr($cookie_str, $start + strlen($cookie_param));
3410 $domain = substr($domain, 0, strpos($domain,
';'));
3415 $cookie_param =
'expires=';
3416 $start = strpos($cookie_str, $cookie_param);
3418 $expires = substr($cookie_str, $start + strlen($cookie_param));
3419 $expires = substr($expires, 0, strpos($expires,
';'));
3424 $cookie_param =
'path=';
3425 $start = strpos($cookie_str, $cookie_param);
3427 $path = substr($cookie_str, $start + strlen($cookie_param));
3433 $cookie_param =
';secure;';
3434 if (strpos($cookie_str, $cookie_param) !==
false) {
3440 $sep_pos = strpos($value_str,
'=');
3443 $name = substr($value_str, 0, $sep_pos);
3444 $value = substr($value_str, $sep_pos + 1);
3445 $cookie= array(
'name' => $name,
3447 'domain' => $domain,
3449 'expires' => $expires,
3465 public function getCookiesForRequest($cookies, $secure=
false)
3468 if ((! is_null($cookies)) && (is_array($cookies))) {
3469 foreach ($cookies as $cookie) {
3470 if (! is_array($cookie)) {
3473 $this->
debug(
"check cookie for validity: " . $cookie[
'name'] .
'=' . $cookie[
'value']);
3474 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3475 if (strtotime($cookie[
'expires']) <= time()) {
3476 $this->
debug(
'cookie has expired');
3480 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3481 $domain = preg_quote($cookie[
'domain']);
3482 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3483 $this->
debug(
'cookie has different domain');
3487 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3488 $path = preg_quote($cookie[
'path']);
3489 if (! preg_match(
"'^$path.*'i", $this->path)) {
3490 $this->
debug(
'cookie is for a different path');
3494 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3495 $this->
debug(
'cookie is secure, transport is not');
3498 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3499 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3527 public $headers = array();
3533 public $request =
'';
3539 public $requestHeaders =
'';
3545 public $requestHeader = null;
3551 public $document =
'';
3557 public $requestSOAP =
'';
3563 public $methodURI =
'';
3569 public $methodname =
'';
3575 public $methodparams = array();
3581 public $SOAPAction =
'';
3587 public $xml_encoding =
'';
3593 public $decode_utf8 =
true;
3600 public $outgoing_headers = array();
3612 public $responseHeaders =
'';
3618 public $responseSOAP =
'';
3624 public $methodreturn =
false;
3630 public $methodreturnisliteralxml =
false;
3636 public $fault =
false;
3642 public $result =
'successful';
3650 public $operations = array();
3656 public $wsdl =
false;
3662 public $externalWSDLURL =
false;
3668 public $debug_flag =
false;
3683 global $HTTP_SERVER_VARS;
3686 $this->
debug(
"_SERVER is defined:");
3688 } elseif (isset($HTTP_SERVER_VARS)) {
3689 $this->
debug(
"HTTP_SERVER_VARS is defined:");
3692 $this->
debug(
"Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3695 if (isset($debug)) {
3696 $this->
debug(
"In nusoap_server, set debug_flag=$debug based on global flag");
3697 $this->debug_flag = $debug;
3698 } elseif (isset(
$_SERVER[
'QUERY_STRING'])) {
3699 $qs = explode(
'&',
$_SERVER[
'QUERY_STRING']);
3700 foreach ($qs as $v) {
3701 if (substr($v, 0, 6) ==
'debug=') {
3702 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #1");
3703 $this->debug_flag = substr($v, 6);
3706 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3707 $qs = explode(
'&', $HTTP_SERVER_VARS[
'QUERY_STRING']);
3708 foreach ($qs as $v) {
3709 if (substr($v, 0, 6) ==
'debug=') {
3710 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #2");
3711 $this->debug_flag = substr($v, 6);
3718 $this->
debug(
"In nusoap_server, WSDL is specified");
3719 if (is_object($wsdl) && (get_class($wsdl) ==
'wsdl')) {
3720 $this->
wsdl = $wsdl;
3721 $this->externalWSDLURL = $this->
wsdl->wsdl;
3722 $this->
debug(
'Use existing wsdl instance from ' . $this->externalWSDLURL);
3724 $this->
debug(
'Create wsdl from ' . $wsdl);
3726 $this->externalWSDLURL = $wsdl;
3731 die(
'WSDL ERROR: ' . $err);
3742 public function service(
$data)
3744 global $HTTP_SERVER_VARS;
3746 if (isset(
$_SERVER[
'QUERY_STRING'])) {
3748 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3749 $qs = $HTTP_SERVER_VARS[
'QUERY_STRING'];
3753 $this->
debug(
"In service, query string=$qs");
3755 if (preg_match(
'/wsdl/', $qs)) {
3756 $this->
debug(
"In service, this is a request for WSDL");
3757 if ($this->externalWSDLURL) {
3758 if (strpos($this->externalWSDLURL,
"://")!==
false) {
3759 header(
'Location: ' . $this->externalWSDLURL);
3761 header(
"Content-Type: text/xml\r\n");
3762 $fp = fopen($this->externalWSDLURL,
'r');
3765 } elseif ($this->
wsdl) {
3766 header(
"Content-Type: text/xml; charset=ISO-8859-1\r\n");
3768 if ($this->debug_flag) {
3769 $this->
debug(
'wsdl:');
3774 header(
"Content-Type: text/html; charset=ISO-8859-1\r\n");
3775 print
"This service does not provide WSDL";
3778 $this->
debug(
"In service, there is no data, so return Web description");
3781 $this->
debug(
"In service, invoke the request");
3782 $this->parse_request(
$data);
3783 if (! $this->fault) {
3784 $this->invoke_method();
3786 if (! $this->fault) {
3787 $this->serialize_return();
3789 $this->send_response();
3805 public function parse_http_headers()
3807 global $HTTP_SERVER_VARS;
3809 $this->request =
'';
3810 $this->SOAPAction =
'';
3811 if (function_exists(
'getallheaders')) {
3812 $this->
debug(
"In parse_http_headers, use getallheaders");
3813 $headers = getallheaders();
3814 foreach ($headers as $k=>$v) {
3815 $k = strtolower($k);
3816 $this->headers[$k] = $v;
3817 $this->request .=
"$k: $v\r\n";
3818 $this->
debug(
"$k: $v");
3821 if (isset($this->headers[
'soapaction'])) {
3822 $this->SOAPAction = str_replace(
'"',
'', $this->headers[
'soapaction']);
3825 if (isset($this->headers[
'content-type']) && strpos($this->headers[
'content-type'],
'=')) {
3826 $enc = str_replace(
'"',
'', substr(strstr($this->headers[
"content-type"],
'='), 1));
3827 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3828 $this->xml_encoding = strtoupper($enc);
3830 $this->xml_encoding =
'US-ASCII';
3834 $this->xml_encoding =
'ISO-8859-1';
3837 $this->
debug(
"In parse_http_headers, use _SERVER");
3839 if (substr($k, 0, 5) ==
'HTTP_') {
3840 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3842 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3844 if ($k ==
'soapaction') {
3847 $v = str_replace(
'"',
'', $v);
3848 $v = str_replace(
'\\',
'', $v);
3849 $this->SOAPAction = $v;
3850 } elseif ($k ==
'content-type') {
3852 if (strpos($v,
'=')) {
3853 $enc = substr(strstr($v,
'='), 1);
3854 $enc = str_replace(
'"',
'', $enc);
3855 $enc = str_replace(
'\\',
'', $enc);
3856 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3857 $this->xml_encoding = strtoupper($enc);
3859 $this->xml_encoding =
'US-ASCII';
3863 $this->xml_encoding =
'ISO-8859-1';
3866 $this->headers[$k] = $v;
3867 $this->request .=
"$k: $v\r\n";
3868 $this->
debug(
"$k: $v");
3870 } elseif (is_array($HTTP_SERVER_VARS)) {
3871 $this->
debug(
"In parse_http_headers, use HTTP_SERVER_VARS");
3872 foreach ($HTTP_SERVER_VARS as $k => $v) {
3873 if (substr($k, 0, 5) ==
'HTTP_') {
3874 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3875 $k = strtolower(substr($k, 5));
3877 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3878 $k = strtolower($k);
3880 if ($k ==
'soapaction') {
3883 $v = str_replace(
'"',
'', $v);
3884 $v = str_replace(
'\\',
'', $v);
3885 $this->SOAPAction = $v;
3886 } elseif ($k ==
'content-type') {
3888 if (strpos($v,
'=')) {
3889 $enc = substr(strstr($v,
'='), 1);
3890 $enc = str_replace(
'"',
'', $enc);
3891 $enc = str_replace(
'\\',
'', $enc);
3892 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3893 $this->xml_encoding = strtoupper($enc);
3895 $this->xml_encoding =
'US-ASCII';
3899 $this->xml_encoding =
'ISO-8859-1';
3902 $this->headers[$k] = $v;
3903 $this->request .=
"$k: $v\r\n";
3904 $this->
debug(
"$k: $v");
3907 $this->
debug(
"In parse_http_headers, HTTP headers not accessible");
3908 $this->
setError(
"HTTP headers not accessible");
3934 public function parse_request(
$data=
'')
3936 $this->
debug(
'entering parse_request()');
3937 $this->parse_http_headers();
3938 $this->
debug(
'got character encoding: ' . $this->xml_encoding);
3940 if (isset($this->headers[
'content-encoding']) && $this->headers[
'content-encoding'] !=
'') {
3941 $this->
debug(
'got content encoding: ' . $this->headers[
'content-encoding']);
3942 if ($this->headers[
'content-encoding'] ==
'deflate' || $this->headers[
'content-encoding'] ==
'gzip') {
3944 if (function_exists(
'gzuncompress')) {
3945 if ($this->headers[
'content-encoding'] ==
'deflate' && $degzdata = @gzuncompress(
$data)) {
3947 } elseif ($this->headers[
'content-encoding'] ==
'gzip' && $degzdata = gzinflate(substr(
$data, 10))) {
3950 $this->fault(
'SOAP-ENV:Client',
'Errors occurred when trying to decode the data');
3954 $this->fault(
'SOAP-ENV:Client',
'This Server does not support compressed data');
3959 $this->request .=
"\r\n" .
$data;
3960 $data = $this->parseRequest($this->headers,
$data);
3961 $this->requestSOAP =
$data;
3962 $this->
debug(
'leaving parse_request');
3982 public function invoke_method()
3984 $this->
debug(
'in invoke_method, methodname=' . $this->methodname .
' methodURI=' . $this->methodURI .
' SOAPAction=' . $this->SOAPAction);
3988 $this->
debug(
'in invoke_method, found WSDL operation=' . $this->methodname);
3992 $this->
debug(
'in invoke_method, found WSDL soapAction=' . $this->SOAPAction .
' for operation=' . $this->opData[
'name']);
3994 $this->methodname = $this->opData[
'name'];
3996 $this->
debug(
'in invoke_method, no WSDL for operation=' . $this->methodname);
3997 $this->fault(
'SOAP-ENV:Client',
"Operation '" . $this->methodname .
"' is not defined in the WSDL for this service");
4001 $this->
debug(
'in invoke_method, no WSDL to validate method');
4009 if (strpos($this->methodname,
'..') > 0) {
4011 } elseif (strpos($this->methodname,
'.') > 0) {
4017 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
4018 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
4020 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
4021 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
4022 $this->
debug(
"in invoke_method, class=$class method=$method delim=$delim");
4026 if ($class ==
'' && $this->
class !=
'') {
4027 $class = $this->class;
4029 $method = $this->methodname;
4034 if (!function_exists($this->methodname)) {
4035 $this->
debug(
"in invoke_method, function '$this->methodname' not found!");
4036 $this->result =
'fault: method not found';
4037 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4041 $method_to_compare = (substr(phpversion(), 0, 2) ==
'4.') ? strtolower($method) : $method;
4042 if (!in_array($method_to_compare, get_class_methods($class))) {
4043 $this->
debug(
"in invoke_method, method '$this->methodname' not found in class '$class'!");
4044 $this->result =
'fault: method not found';
4045 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
4052 if (! $this->verify_method($this->methodname, $this->methodparams)) {
4054 $this->
debug(
'ERROR: request not verified against method signature');
4055 $this->result =
'fault: request failed validation against method signature';
4057 $this->fault(
'SOAP-ENV:Client',
"Operation '$this->methodname' not defined in service.");
4062 $this->
debug(
'in invoke_method, params:');
4064 $this->
debug(
"in invoke_method, calling '$this->methodname'");
4065 if (!function_exists(
'call_user_func_array')) {
4067 $this->
debug(
'in invoke_method, calling function using eval()');
4068 $funcCall =
"\$this->methodreturn = $this->methodname(";
4070 if ($delim ==
'..') {
4071 $this->
debug(
'in invoke_method, calling class method using eval()');
4072 $funcCall =
"\$this->methodreturn = " . $class .
"::" . $method .
"(";
4074 $this->
debug(
'in invoke_method, calling instance method using eval()');
4076 $instname =
"\$inst_" . time();
4077 $funcCall = $instname .
" = new " . $class .
"(); ";
4078 $funcCall .=
"\$this->methodreturn = " . $instname .
"->" . $method .
"(";
4081 if ($this->methodparams) {
4082 foreach ($this->methodparams as
$param) {
4083 if (is_array($param) || is_object($param)) {
4084 $this->fault(
'SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
4087 $funcCall .=
"\"$param\",";
4089 $funcCall = substr($funcCall, 0, -1);
4092 $this->
debug(
'in invoke_method, function call: ' . $funcCall);
4096 $this->
debug(
'in invoke_method, calling function using call_user_func_array()');
4097 $call_arg =
"$this->methodname";
4098 } elseif ($delim ==
'..') {
4099 $this->
debug(
'in invoke_method, calling class method using call_user_func_array()');
4100 $call_arg = array($class, $method);
4102 $this->
debug(
'in invoke_method, calling instance method using call_user_func_array()');
4103 $instance =
new $class();
4104 $call_arg = array(&$instance, $method);
4106 if (is_array($this->methodparams)) {
4107 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4109 $this->methodreturn = call_user_func_array($call_arg, array());
4112 $this->
debug(
'in invoke_method, methodreturn:');
4114 $this->
debug(
"in invoke_method, called method $this->methodname, received data of type " . gettype($this->methodreturn));
4128 public function serialize_return()
4130 $this->
debug(
'Entering serialize_return methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4132 if (isset($this->methodreturn) && ((get_class((
object)$this->methodreturn) ==
'soap_fault') || (get_class((
object)$this->methodreturn) ==
'nusoap_fault'))) {
4133 $this->
debug(
'got a fault object from method');
4134 $this->fault = $this->methodreturn;
4136 } elseif ($this->methodreturnisliteralxml) {
4137 $return_val = $this->methodreturn;
4140 $this->
debug(
'got a(n) ' . gettype($this->methodreturn) .
' from method');
4141 $this->
debug(
'serializing return value');
4143 if (
sizeof($this->opData[
'output'][
'parts']) > 1) {
4144 $this->
debug(
'more than one output part, so use the method return unchanged');
4145 $opParams = $this->methodreturn;
4146 } elseif (
sizeof($this->opData[
'output'][
'parts']) == 1) {
4147 $this->
debug(
'exactly one output part, so wrap the method return in a simple array');
4152 $opParams = array($this->methodreturn);
4158 $this->
debug(
'got wsdl error: ' . $errstr);
4159 $this->fault(
'SOAP-ENV:Server',
'unable to serialize result');
4163 if (isset($this->methodreturn)) {
4164 $return_val = $this->
serialize_val($this->methodreturn,
'return');
4167 $this->
debug(
'in absence of WSDL, assume void return for backward compatibility');
4171 $this->
debug(
'return value:');
4174 $this->
debug(
'serializing response');
4176 $this->
debug(
'have WSDL for serialization: style is ' . $this->opData[
'style']);
4177 if ($this->opData[
'style'] ==
'rpc') {
4178 $this->
debug(
'style is rpc for serialization: use is ' . $this->opData[
'output'][
'use']);
4179 if ($this->opData[
'output'][
'use'] ==
'literal') {
4181 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4183 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4186 $this->
debug(
'style is not rpc for serialization: assume document');
4190 $this->
debug(
'do not have WSDL for serialization: assume rpc/encoded');
4191 $payload =
'<ns1:' . $this->methodname .
'Response xmlns:ns1="' . $this->methodURI .
'">' . $return_val .
'</ns1:' . $this->methodname .
"Response>";
4193 $this->result =
'successful';
4198 if (isset($opData[
'output'][
'encodingStyle'])) {
4199 $encodingStyle = $opData[
'output'][
'encodingStyle'];
4201 $encodingStyle =
'';
4204 $this->responseSOAP = $this->
serializeEnvelope(
$payload, $this->responseHeaders, $this->
wsdl->usedNamespaces, $this->opData[
'style'], $this->opData[
'output'][
'use'], $encodingStyle);
4208 $this->
debug(
"Leaving serialize_return");
4221 public function send_response()
4223 $this->
debug(
'Enter send_response');
4225 $payload = $this->fault->serialize();
4226 $this->outgoing_headers[] =
"HTTP/1.0 500 Internal Server Error";
4227 $this->outgoing_headers[] =
"Status: 500 Internal Server Error";
4237 if (isset($this->debug_flag) && $this->debug_flag) {
4240 $this->outgoing_headers[] =
"Server: $this->title Server v$this->version";
4241 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
4242 $this->outgoing_headers[] =
"X-SOAP-Server: $this->title/$this->version (" . $rev[1] .
")";
4246 $type = $this->getHTTPContentType();
4247 $charset = $this->getHTTPContentTypeCharset();
4248 $this->outgoing_headers[] =
"Content-Type: $type" . ($charset ?
'; charset=' . $charset :
'');
4252 if (strlen(
$payload) > 1024 && isset($this->headers) && isset($this->headers[
'accept-encoding'])) {
4253 if (strstr($this->headers[
'accept-encoding'],
'gzip')) {
4254 if (function_exists(
'gzencode')) {
4255 if (isset($this->debug_flag) && $this->debug_flag) {
4256 $payload .=
"<!-- Content being gzipped -->";
4258 $this->outgoing_headers[] =
"Content-Encoding: gzip";
4261 if (isset($this->debug_flag) && $this->debug_flag) {
4262 $payload .=
"<!-- Content will not be gzipped: no gzencode -->";
4265 } elseif (strstr($this->headers[
'accept-encoding'],
'deflate')) {
4269 if (function_exists(
'gzdeflate')) {
4270 if (isset($this->debug_flag) && $this->debug_flag) {
4271 $payload .=
"<!-- Content being deflated -->";
4273 $this->outgoing_headers[] =
"Content-Encoding: deflate";
4276 if (isset($this->debug_flag) && $this->debug_flag) {
4277 $payload .=
"<!-- Content will not be deflated: no gzcompress -->";
4283 $this->outgoing_headers[] =
"Content-Length: " . strlen(
$payload);
4284 reset($this->outgoing_headers);
4285 foreach ($this->outgoing_headers as $hdr) {
4289 $this->response = join(
"\r\n", $this->outgoing_headers) .
"\r\n\r\n" .
$payload;
4301 public function verify_method($operation, $request)
4303 if (isset($this->
wsdl) && is_object($this->
wsdl)) {
4307 } elseif (isset($this->operations[$operation])) {
4321 public function parseRequest($headers,
$data)
4323 $this->
debug(
'Entering parseRequest() for data of length ' . strlen(
$data) .
' and type ' . $headers[
'content-type']);
4324 if (!strstr($headers[
'content-type'],
'text/xml')) {
4325 $this->
setError(
'Request not of type text/xml');
4328 if (strpos($headers[
'content-type'],
'=')) {
4329 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
4330 $this->
debug(
'Got response encoding: ' . $enc);
4331 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
4332 $this->xml_encoding = strtoupper($enc);
4334 $this->xml_encoding =
'US-ASCII';
4338 $this->xml_encoding =
'ISO-8859-1';
4340 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
4344 $this->
debug(
"parser debug: \n" . $parser->getDebug());
4346 if ($err = $parser->getError()) {
4347 $this->result =
'fault: error in msg parsing: ' . $err;
4348 $this->fault(
'SOAP-ENV:Client',
"error in msg parsing:\n" . $err);
4352 $this->methodURI = $parser->root_struct_namespace;
4353 $this->methodname = $parser->root_struct_name;
4354 $this->
debug(
'methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4355 $this->
debug(
'calling parser->get_soapbody()');
4356 $this->methodparams = $parser->get_soapbody();
4358 $this->requestHeaders = $parser->getHeaders();
4360 $this->requestHeader = $parser->get_soapheader();
4362 $this->document = $parser->document;
4373 public function getHTTPBody($soapmsg)
4386 public function getHTTPContentType()
4400 public function getHTTPContentTypeCharset()
4414 public function add_to_map($methodname, $in,
$out)
4416 $this->operations[$methodname] = array(
'name' => $methodname,
'in' => $in,
'out' =>
$out);
4433 public function register($name, $in=array(),
$out=array(),
$namespace=
false, $soapaction=
false, $style=
false, $use=
false, $documentation=
'', $encodingStyle=
'')
4435 global $HTTP_SERVER_VARS;
4437 if ($this->externalWSDLURL) {
4438 die(
'You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4441 die(
'You must specify a name when you register an operation');
4443 if (!is_array($in)) {
4444 die(
'You must provide an array for operation inputs');
4446 if (!is_array(
$out)) {
4447 die(
'You must provide an array for operation outputs');
4451 if (
false == $soapaction) {
4453 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4455 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4456 } elseif (isset($HTTP_SERVER_VARS)) {
4457 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4458 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4459 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4461 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4463 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4468 $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4470 if (
false == $style) {
4473 if (
false == $use) {
4476 if ($use ==
'encoded' && $encodingStyle =
'') {
4477 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
4480 $this->operations[$name] = array(
4485 'soapaction' => $soapaction,
4523 public function configureWSDL(
$serviceName,
$namespace =
false, $endpoint =
false, $style=
'rpc', $transport =
'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace =
false)
4525 global $HTTP_SERVER_VARS;
4528 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4529 $SERVER_PORT =
$_SERVER[
'SERVER_PORT'];
4531 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4532 } elseif (isset($HTTP_SERVER_VARS)) {
4533 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4534 $SERVER_PORT = $HTTP_SERVER_VARS[
'SERVER_PORT'];
4535 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4536 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4538 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4541 $colon = strpos($SERVER_NAME,
":");
4543 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4545 if ($SERVER_PORT == 80) {
4548 $SERVER_PORT =
':' . $SERVER_PORT;
4551 $namespace =
"http://$SERVER_NAME/soap/$serviceName";
4554 if (
false == $endpoint) {
4555 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4560 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4563 if (
false == $schemaTargetNamespace) {
4569 $this->
wsdl->endpoint = $endpoint;
4571 $this->
wsdl->namespaces[
'soap'] =
'http://schemas.xmlsoap.org/wsdl/soap/';
4572 $this->
wsdl->namespaces[
'wsdl'] =
'http://schemas.xmlsoap.org/wsdl/';
4574 $this->
wsdl->namespaces[
'types'] = $schemaTargetNamespace;
4577 if ($style ==
'document') {
4578 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo[
'elementFormDefault'] =
'qualified';
4580 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4581 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4582 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4586 'transport'=>$transport,
4590 'location'=>$endpoint,
4591 'bindingType'=>
'http://schemas.xmlsoap.org/wsdl/soap/');
4620 public $schemas = array();
4621 public $currentSchema;
4623 public $complexTypes = array();
4625 public $currentMessage;
4626 public $currentOperation;
4627 public $portTypes = array();
4628 public $currentPortType;
4629 public $bindings = array();
4630 public $currentBinding;
4631 public $ports = array();
4632 public $currentPort;
4633 public $opData = array();
4634 public $status =
'';
4635 public $documentation =
false;
4636 public $endpoint =
'';
4638 public $import = array();
4641 public $position = 0;
4643 public $depth_array = array();
4645 public $proxyhost =
'';
4646 public $proxyport =
'';
4647 public $proxyusername =
'';
4648 public $proxypassword =
'';
4649 public $timeout = 0;
4650 public $response_timeout = 30;
4651 public $curl_options = array();
4652 public $use_curl =
false;
4654 public $username =
'';
4655 public $password =
'';
4656 public $authtype =
'';
4657 public $certRequest = array();
4673 public function __construct($wsdl =
'', $proxyhost=
false, $proxyport=
false, $proxyusername=
false, $proxypassword=
false, $timeout=0, $response_timeout=30, $curl_options=null, $use_curl=
false)
4676 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4677 $this->proxyhost = $proxyhost;
4678 $this->proxyport = $proxyport;
4679 $this->proxyusername = $proxyusername;
4680 $this->proxypassword = $proxypassword;
4681 $this->timeout = $timeout;
4682 $this->response_timeout = $response_timeout;
4683 if (is_array($curl_options)) {
4684 $this->curl_options = $curl_options;
4686 $this->use_curl = $use_curl;
4687 $this->fetchWSDL($wsdl);
4695 public function fetchWSDL($wsdl)
4697 $this->
debug(
"parse and process WSDL path=$wsdl");
4698 $this->
wsdl = $wsdl;
4700 if ($this->
wsdl !=
"") {
4701 $this->parseWSDL($this->
wsdl);
4705 $imported_urls = array();
4707 while ($imported > 0) {
4710 foreach ($this->schemas as $ns => $list) {
4711 foreach ($list as $xs) {
4712 $wsdlparts = parse_url($this->
wsdl);
4713 foreach ($xs->imports as $ns2 => $list2) {
4714 for ($ii = 0; $ii < count($list2); $ii++) {
4715 if (! $list2[$ii][
'loaded']) {
4716 $this->schemas[$ns]->imports[$ns2][$ii][
'loaded'] =
true;
4717 $url = $list2[$ii][
'location'];
4719 $urlparts = parse_url($url);
4720 if (!isset($urlparts[
'host'])) {
4721 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4722 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4724 if (! in_array($url, $imported_urls)) {
4725 $this->parseWSDL($url);
4727 $imported_urls[] =
$url;
4730 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4738 $wsdlparts = parse_url($this->
wsdl);
4739 foreach ($this->
import as $ns => $list) {
4740 for ($ii = 0; $ii < count($list); $ii++) {
4741 if (! $list[$ii][
'loaded']) {
4742 $this->
import[$ns][$ii][
'loaded'] =
true;
4743 $url = $list[$ii][
'location'];
4745 $urlparts = parse_url($url);
4746 if (!isset($urlparts[
'host'])) {
4747 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4748 substr($wsdlparts[
'path'], 0, strrpos($wsdlparts[
'path'],
'/') + 1) . $urlparts[
'path'];
4750 if (! in_array($url, $imported_urls)) {
4751 $this->parseWSDL($url);
4753 $imported_urls[] =
$url;
4756 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4763 foreach ($this->bindings as $binding => $bindingData) {
4764 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4765 foreach ($bindingData[
'operations'] as $operation =>
$data) {
4766 $this->
debug(
'post-parse data gathering for ' . $operation);
4767 $this->bindings[$binding][
'operations'][$operation][
'input'] =
4768 isset($this->bindings[$binding][
'operations'][$operation][
'input']) ?
4769 array_merge($this->bindings[$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4770 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4771 $this->bindings[$binding][
'operations'][$operation][
'output'] =
4772 isset($this->bindings[$binding][
'operations'][$operation][
'output']) ?
4773 array_merge($this->bindings[$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4774 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4775 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ])) {
4776 $this->bindings[$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'input'][
'message'] ];
4778 if (isset($this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ])) {
4779 $this->bindings[$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[$binding][
'operations'][$operation][
'output'][
'message'] ];
4782 if (isset($bindingData[
'style']) && !isset($this->bindings[$binding][
'operations'][$operation][
'style'])) {
4783 $this->bindings[$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4785 $this->bindings[$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4786 $this->bindings[$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4787 $this->bindings[$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4799 public function parseWSDL($wsdl =
'')
4801 $this->
debug(
"parse WSDL at path=$wsdl");
4804 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4805 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4810 $wsdl_props = parse_url($wsdl);
4812 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4813 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4816 $tr->request_method =
'GET';
4817 $tr->useSOAPAction =
false;
4818 if ($this->proxyhost && $this->proxyport) {
4819 $tr->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
4821 if ($this->authtype !=
'') {
4822 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4824 $tr->setEncoding(
'gzip, deflate');
4825 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4830 if ($err = $tr->getError()) {
4831 $errstr =
'HTTP ERROR: ' . $err;
4832 $this->
debug($errstr);
4838 $this->
debug(
"got WSDL URL");
4841 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4842 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4847 if ($fp = @fopen(
$path,
'r')) {
4849 while (
$data = fread($fp, 32768)) {
4850 $wsdl_string .=
$data;
4854 $errstr =
"Bad path to WSDL file $path";
4855 $this->
debug($errstr);
4860 $this->
debug(
'Parse WSDL');
4863 $this->parser = xml_parser_create();
4866 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4868 xml_set_object($this->parser, $this);
4870 xml_set_element_handler($this->parser,
'start_element',
'end_element');
4871 xml_set_character_data_handler($this->parser,
'character_data');
4873 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4876 'XML error parsing WSDL from %s on line %d: %s',
4878 xml_get_current_line_number($this->parser),
4879 xml_error_string(xml_get_error_code($this->parser))
4881 $this->
debug($errstr);
4882 $this->
debug(
"XML payload:\n" . $wsdl_string);
4887 xml_parser_free($this->parser);
4888 $this->
debug(
'Parsing WSDL done');
4904 public function start_element($parser, $name, $attrs)
4906 if ($this->status ==
'schema') {
4907 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4908 $this->
appendDebug($this->currentSchema->getDebug());
4909 $this->currentSchema->clearDebug();
4910 } elseif (preg_match(
'/schema$/', $name)) {
4911 $this->
debug(
'Parsing WSDL schema');
4913 $this->status =
'schema';
4915 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4916 $this->
appendDebug($this->currentSchema->getDebug());
4917 $this->currentSchema->clearDebug();
4920 $pos = $this->position++;
4921 $depth = $this->depth++;
4923 $this->depth_array[$depth] = $pos;
4924 $this->message[$pos] = array(
'cdata' =>
'');
4926 if (count($attrs) > 0) {
4928 foreach ($attrs as $k => $v) {
4929 if (preg_match(
'/^xmlns/', $k)) {
4930 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4931 $this->namespaces[$ns_prefix] = $v;
4933 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4935 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4936 $this->XMLSchemaVersion = $v;
4937 $this->namespaces[
'xsi'] = $v .
'-instance';
4942 foreach ($attrs as $k => $v) {
4943 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4944 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4945 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4954 if (preg_match(
'/:/', $name)) {
4956 $prefix = substr($name, 0, strpos($name,
':'));
4958 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4960 $name = substr(strstr($name,
':'), 1);
4964 switch ($this->status) {
4966 if ($name ==
'part') {
4967 if (isset($attrs[
'type'])) {
4968 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4969 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4971 if (isset($attrs[
'element'])) {
4972 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4973 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4980 $this->currentPortOperation = $attrs[
'name'];
4981 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
4982 if (isset($attrs[
'parameterOrder'])) {
4983 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
4986 case 'documentation':
4987 $this->documentation =
true;
4991 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
4992 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name][
'message'] = $m;
5000 if (isset($attrs[
'style'])) {
5001 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
5003 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
5006 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
5009 if (isset($attrs[
'soapAction'])) {
5010 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
5012 if (isset($attrs[
'style'])) {
5013 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
5015 if (isset($attrs[
'name'])) {
5016 $this->currentOperation = $attrs[
'name'];
5017 $this->
debug(
"current binding operation: $this->currentOperation");
5018 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
5019 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
5020 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
5024 $this->opStatus =
'input';
5027 $this->opStatus =
'output';
5030 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
5031 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
5033 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
5041 $this->currentPort = $attrs[
'name'];
5042 $this->
debug(
'current port: ' . $this->currentPort);
5043 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
5047 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
5048 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
5049 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
5050 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
5058 if (isset($attrs[
'location'])) {
5059 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
5060 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]) .
')');
5062 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
5064 $this->namespaces[
'ns' . (count($this->namespaces)+1)] = $attrs[
'namespace'];
5066 $this->
debug(
'parsing import ' . $attrs[
'namespace'] .
' - [no location] (' . count($this->
import[$attrs[
'namespace']]) .
')');
5074 $this->status =
'message';
5075 $this->messages[$attrs[
'name']] = array();
5076 $this->currentMessage = $attrs[
'name'];
5079 $this->status =
'portType';
5080 $this->portTypes[$attrs[
'name']] = array();
5081 $this->currentPortType = $attrs[
'name'];
5084 if (isset($attrs[
'name'])) {
5086 if (strpos($attrs[
'name'],
':')) {
5087 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
5089 $this->currentBinding = $attrs[
'name'];
5091 $this->status =
'binding';
5092 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
5093 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
5097 $this->serviceName = $attrs[
'name'];
5098 $this->status =
'service';
5099 $this->
debug(
'current service: ' . $this->serviceName);
5102 foreach ($attrs as $name => $value) {
5103 $this->wsdl_info[$name] = $value;
5117 public function end_element($parser, $name)
5120 if ( preg_match(
'/schema$/', $name)) {
5122 $this->
appendDebug($this->currentSchema->getDebug());
5123 $this->currentSchema->clearDebug();
5124 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5125 $this->
debug(
'Parsing WSDL schema done');
5127 if ($this->status ==
'schema') {
5128 $this->currentSchema->schemaEndElement($parser, $name);
5134 if ($this->documentation) {
5137 $this->documentation =
false;
5148 public function character_data($parser,
$data)
5150 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5151 if (isset($this->message[$pos][
'cdata'])) {
5152 $this->message[$pos][
'cdata'] .=
$data;
5154 if ($this->documentation) {
5155 $this->documentation .=
$data;
5168 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
5170 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5172 $this->username = $username;
5173 $this->password = $password;
5174 $this->authtype = $authtype;
5175 $this->certRequest = $certRequest;
5178 public function getBindingData($binding)
5180 if (is_array($this->bindings[$binding])) {
5181 return $this->bindings[$binding];
5192 public function getOperations($bindingType =
'soap')
5195 if ($bindingType ==
'soap') {
5196 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5197 } elseif ($bindingType ==
'soap12') {
5198 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5201 foreach ($this->ports as $port => $portData) {
5203 if ($portData[
'bindingType'] == $bindingType) {
5208 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5209 $ops = array_merge($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5224 public function getOperationData($operation, $bindingType =
'soap')
5226 if ($bindingType ==
'soap') {
5227 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5228 } elseif ($bindingType ==
'soap12') {
5229 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5232 foreach ($this->ports as $port => $portData) {
5234 if ($portData[
'bindingType'] == $bindingType) {
5237 foreach (array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5239 if ($operation == $bOperation) {
5240 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5256 public function getOperationDataForSoapAction($soapAction, $bindingType =
'soap')
5258 if ($bindingType ==
'soap') {
5259 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5260 } elseif ($bindingType ==
'soap12') {
5261 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5264 foreach ($this->ports as $port => $portData) {
5266 if ($portData[
'bindingType'] == $bindingType) {
5268 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5269 if ($opData[
'soapAction'] == $soapAction) {
5295 public function getTypeDef($type, $ns)
5297 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5298 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5299 $ns = $this->namespaces[
'tns'];
5300 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5302 if (!isset($this->schemas[$ns])) {
5303 foreach ($this->schemas as $ns0 => $schema0) {
5304 if (strcasecmp($ns, $ns0) == 0) {
5305 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5311 if (isset($this->schemas[$ns])) {
5312 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5313 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5314 $xs = &$this->schemas[$ns][$i];
5315 $t = $xs->getTypeDef($type);
5319 if (!isset($t[
'phpType'])) {
5321 $uqType = substr($t[
'type'], strrpos($t[
'type'],
':') + 1);
5322 $ns = substr($t[
'type'], 0, strrpos($t[
'type'],
':'));
5323 $etype = $this->getTypeDef($uqType, $ns);
5325 $this->
debug(
"found type for [element] $type:");
5327 if (isset($etype[
'phpType'])) {
5328 $t[
'phpType'] = $etype[
'phpType'];
5330 if (isset($etype[
'elements'])) {
5331 $t[
'elements'] = $etype[
'elements'];
5333 if (isset($etype[
'attrs'])) {
5334 $t[
'attrs'] = $etype[
'attrs'];
5342 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5352 public function webDescription()
5354 global $HTTP_SERVER_VARS;
5358 } elseif (isset($HTTP_SERVER_VARS)) {
5359 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5361 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5364 $PHP_SELF = filter_var($PHP_SELF, FILTER_SANITIZE_STRING);
5368 <html><head><title>NuSOAP: ' . $this->serviceName .
'</title> 5369 <style type="text/css"> 5370 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5371 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5372 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5373 ul { margin-top: 10px; margin-left: 20px; } 5374 li { list-style-type: none; margin-top: 10px; color: #000000; } 5376 margin-left: 0px; padding-bottom: 2em; } 5378 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5379 margin-top: 10px; margin-left: 0px; color: #000000; 5380 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5382 font-family: arial; font-size: 26px; color: #ffffff; 5383 background-color: #999999; width: 105%; margin-left: 0px; 5384 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5386 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5387 font-family: arial; overflow: hidden; width: 600; 5388 padding: 20px; font-size: 10px; background-color: #999999; 5389 layer-background-color:#FFFFFF; } 5390 a,a:active { color: charcoal; font-weight: bold; } 5391 a:visited { color: #666666; font-weight: bold; } 5392 a:hover { color: cc3300; font-weight: bold; } 5394 <script language="JavaScript" type="text/javascript"> 5396 // POP-UP CAPTIONS... 5397 function lib_bwcheck(){ //Browsercheck (needed) 5398 this.ver=navigator.appVersion 5399 this.agent=navigator.userAgent 5400 this.dom=document.getElementById?1:0 5401 this.opera5=this.agent.indexOf("Opera 5")>-1 5402 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5403 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5404 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5405 this.ie=this.ie4||this.ie5||this.ie6 5406 this.mac=this.agent.indexOf("Mac")>-1 5407 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5408 this.ns4=(document.layers && !this.dom)?1:0; 5409 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5412 var bw = new lib_bwcheck() 5413 //Makes crossbrowser object. 5414 function makeObj(obj){ 5415 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5416 if(!this.evnt) return false 5417 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5418 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5419 this.writeIt=b_writeIt; 5422 // A unit of measure that will be added when setting the position of a layer. 5423 //var px = bw.ns4||window.opera?"":"px"; 5424 function b_writeIt(text){ 5425 if (bw.ns4){this.wref.write(text);this.wref.close()} 5426 else this.wref.innerHTML = text 5428 //Shows the messages 5430 function popup(divid){ 5431 if(oDesc = new makeObj(divid)){ 5432 oDesc.css.visibility = "visible" 5435 function popout(){ // Hides message 5436 if(oDesc) oDesc.css.visibility = "hidden" 5444 <div class=title>' . $this->serviceName .
'</div> 5446 <p>View the <a href="' . $PHP_SELF .
'?wsdl">WSDL</a> for the service. 5447 Click on an operation name to view it's details.</p> 5449 foreach ($this->getOperations() as $op =>
$data) {
5451 if (isset(
$data[
'endpoint'])) {
5452 $data[
'endpoint'] = filter_var(
$data[
'endpoint'], FILTER_SANITIZE_STRING);
5455 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5457 $b .=
"<div id='$op' class='hidden'> 5458 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5459 foreach (
$data as $donnie => $marie) {
5460 if ($donnie ==
'input' || $donnie ==
'output') {
5461 $b .=
"<font color='white'>" . ucfirst($donnie) .
':</font><br>';
5462 foreach ($marie as $captain => $tenille) {
5463 if ($captain ==
'parts') {
5464 $b .=
" $captain:<br>";
5466 foreach ($tenille as $joanie => $chachi) {
5467 $b .=
" $joanie: $chachi<br>";
5471 $b .=
" $captain: $tenille<br>";
5475 $b .=
"<font color='white'>" . ucfirst($donnie) .
":</font> $marie<br>";
5483 </div></body></html>';
5496 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5497 $xml .=
"\n<definitions";
5498 foreach ($this->namespaces as $k => $v) {
5499 $xml .=
" xmlns:$k=\"$v\"";
5502 if (isset($this->namespaces[
'wsdl'])) {
5503 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5505 if (isset($this->namespaces[
'tns'])) {
5506 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5510 if (
sizeof($this->
import) > 0) {
5511 foreach ($this->
import as $ns => $list) {
5512 foreach ($list as $ii) {
5513 if ($ii[
'location'] !=
'') {
5514 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5516 $xml .=
'<import namespace="' . $ns .
'" />';
5522 if (count($this->schemas)>=1) {
5523 $xml .=
"\n<types>\n";
5524 foreach ($this->schemas as $ns => $list) {
5525 foreach ($list as $xs) {
5526 $xml .= $xs->serializeSchema();
5532 if (count($this->messages) >= 1) {
5533 foreach ($this->messages as $msgName => $msgParts) {
5534 $xml .=
"\n<message name=\"" . $msgName .
'">';
5535 if (is_array($msgParts)) {
5536 foreach ($msgParts as $partName => $partType) {
5538 if (strpos($partType,
':')) {
5540 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5542 $typePrefix =
'xsd';
5544 foreach ($this->typemap as $ns => $types) {
5545 if (isset($types[$partType])) {
5549 if (!isset($typePrefix)) {
5550 die(
"$partType has no namespace!");
5555 $typeDef = $this->getTypeDef($localPart, $ns);
5556 if (($typeDef[
'typeClass'] ??
'') ==
'element') {
5557 $elementortype =
'element';
5558 if (substr($localPart, -1) ==
'^') {
5559 $localPart = substr($localPart, 0, -1);
5562 $elementortype =
'type';
5564 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5567 $xml .=
'</message>';
5571 if (count($this->bindings) >= 1) {
5574 foreach ($this->bindings as $bindingName => $attrs) {
5575 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5576 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5577 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5578 foreach ($attrs[
'operations'] as $opName => $opParts) {
5579 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5580 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="' . $opParts[
'style'] .
'"/>';
5581 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5582 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5586 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5587 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5588 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5592 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5593 $binding_xml .=
"\n" .
' </operation>';
5594 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5595 if (isset($opParts[
'parameterOrder'])) {
5596 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5598 $portType_xml .=
'>';
5599 if (isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5600 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5602 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5603 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5604 $portType_xml .=
"\n" .
' </operation>';
5606 $portType_xml .=
"\n" .
'</portType>';
5607 $binding_xml .=
"\n" .
'</binding>';
5609 $xml .= $portType_xml . $binding_xml;
5612 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5613 $has_client = isset(
$_GET[
'client_id']);
5614 if (count($this->ports) >= 1) {
5615 foreach ($this->ports as $pName => $attrs) {
5616 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5617 $address = $attrs[
'location'] . ($debug || $has_client ?
"?" :
"")
5618 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5619 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5620 $xml .=
"\n" .
' <soap:address location="' . $address .
'"/>';
5621 $xml .=
"\n" .
' </port>';
5625 $xml .=
"\n" .
'</service>';
5626 return $xml .
"\n</definitions>";
5638 public function parametersMatchWrapped($type, &$parameters)
5640 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5644 if (strpos($type,
':')) {
5645 $uqType = substr($type, strrpos($type,
':') + 1);
5646 $ns = substr($type, 0, strrpos($type,
':'));
5647 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5650 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5655 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5661 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5662 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5665 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5667 if (substr($uqType, -1) ==
'^') {
5668 $uqType = substr($uqType, 0, -1);
5670 $phpType = $typeDef[
'phpType'];
5671 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5672 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5675 if ($phpType !=
'struct') {
5676 $this->
debug(
"in parametersMatchWrapped: not a struct");
5681 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5685 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5686 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5689 foreach ($typeDef[
'elements'] as $name => $attrs) {
5691 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5692 $parameters[$name] = $parameters[$elements];
5693 unset($parameters[$elements]);
5695 } elseif (isset($parameters[$name])) {
5696 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5699 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5704 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5705 if ($matches == 0) {
5713 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5714 return count($parameters) == 0;
5732 public function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap')
5734 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5737 if ($direction !=
'input' && $direction !=
'output') {
5738 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5739 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5742 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5743 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5744 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5747 $this->
debug(
'in serializeRPCParameters: opData:');
5751 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5752 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5753 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5754 $enc_style = $encodingStyle;
5759 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5760 $parts = &$opData[$direction][
'parts'];
5761 $part_count =
sizeof(
$parts);
5762 $style = $opData[
'style'];
5763 $use = $opData[$direction][
'use'];
5764 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5765 if (is_array($parameters)) {
5767 $parameter_count = count($parameters);
5768 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5770 if ($style ==
'document' && $use ==
'literal' && $part_count == 1 && isset(
$parts[
'parameters'])) {
5771 $this->
debug(
'check whether the caller has wrapped the parameters');
5772 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5773 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5774 if ($this->parametersMatchWrapped(
$parts[
'parameters'], $parameters)) {
5775 $this->
debug(
'wrap the parameters for the caller');
5776 $parameters = array(
'parameters' => $parameters);
5777 $parameter_count = 1;
5781 foreach (
$parts as $name => $type) {
5782 $this->
debug(
"serializing part $name of type $type");
5784 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5785 $encodingStyle = $opData[$direction][
'encodingStyle'];
5786 $enc_style = $encodingStyle;
5792 if ($parametersArrayType ==
'arraySimple') {
5793 $p = array_shift($parameters);
5794 $this->
debug(
'calling serializeType w/indexed param');
5795 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5796 } elseif (isset($parameters[$name])) {
5797 $this->
debug(
'calling serializeType w/named param');
5798 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5801 $this->
debug(
'calling serializeType w/null param');
5802 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5806 $this->
debug(
'no parameters passed.');
5809 $this->
debug(
"serializeRPCParameters returning: $xml");
5827 public function serializeParameters($operation, $direction, $parameters)
5829 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5832 if ($direction !=
'input' && $direction !=
'output') {
5833 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5834 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5837 if (!$opData = $this->getOperationData($operation)) {
5838 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5839 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5842 $this->
debug(
'opData:');
5846 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5847 if (($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5848 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5849 $enc_style = $encodingStyle;
5854 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5855 $use = $opData[$direction][
'use'];
5856 $this->
debug(
"use=$use");
5857 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5858 if (is_array($parameters)) {
5860 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5861 foreach ($opData[$direction][
'parts'] as $name => $type) {
5862 $this->
debug(
'serializing part "' . $name .
'" of type "' . $type .
'"');
5864 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5865 $encodingStyle = $opData[$direction][
'encodingStyle'];
5866 $enc_style = $encodingStyle;
5872 if ($parametersArrayType ==
'arraySimple') {
5873 $p = array_shift($parameters);
5874 $this->
debug(
'calling serializeType w/indexed param');
5875 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5876 } elseif (isset($parameters[$name])) {
5877 $this->
debug(
'calling serializeType w/named param');
5878 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5881 $this->
debug(
'calling serializeType w/null param');
5882 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5886 $this->
debug(
'no parameters passed.');
5889 $this->
debug(
"serializeParameters returning: $xml");
5905 public function serializeType($name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5907 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5909 if ($use ==
'encoded' && $encodingStyle) {
5910 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5914 if (is_object($value) && get_class($value) ==
'soapval') {
5915 if ($value->type_ns) {
5916 $type = $value->type_ns .
':' . $value->type;
5918 $this->
debug(
"in serializeType: soapval overrides type to $type");
5919 } elseif ($value->type) {
5920 $type = $value->type;
5922 $this->
debug(
"in serializeType: soapval overrides type to $type");
5925 $this->
debug(
"in serializeType: soapval does not override type");
5927 $attrs = $value->attributes;
5928 $value = $value->value;
5929 $this->
debug(
"in serializeType: soapval overrides value to $value");
5931 if (!is_array($value)) {
5932 $value[
'!'] = $value;
5934 foreach ($attrs as $n => $v) {
5935 $value[
'!' . $n] = $v;
5937 $this->
debug(
"in serializeType: soapval provides attributes");
5944 if (strpos($type,
':')) {
5945 $uqType = substr($type, strrpos($type,
':') + 1);
5946 $ns = substr($type, 0, strrpos($type,
':'));
5947 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5950 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5953 if ($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/') {
5954 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5955 if ($unqualified && $use ==
'literal') {
5956 $elementNS =
" xmlns=\"\"";
5960 if (is_null($value)) {
5961 if ($use ==
'literal') {
5963 $xml =
"<$name$elementNS/>";
5966 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5968 $this->
debug(
"in serializeType: returning: $xml");
5971 if ($uqType ==
'Array') {
5973 return $this->
serialize_val($value, $name,
false,
false,
false,
false, $use);
5975 if ($uqType ==
'boolean') {
5976 if ((is_string($value) && $value ==
'false') || (! $value)) {
5982 if ($uqType ==
'string' && gettype($value) ==
'string') {
5985 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5986 $value = sprintf(
"%.0lf", $value);
5991 if (!$this->getTypeDef($uqType, $ns)) {
5992 if ($use ==
'literal') {
5994 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
5996 $xml =
"<$name$elementNS>$value</$name>";
5999 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6001 $this->
debug(
"in serializeType: returning: $xml");
6004 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
6005 } elseif ($ns ==
'http://xml.apache.org/xml-soap') {
6006 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
6007 if ($uqType ==
'Map') {
6010 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
6011 $tt_prefix =
'ns' . rand(1000, 9999);
6012 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
6017 foreach ($value as $k => $v) {
6018 $this->
debug(
"serializing map element: key $k, value $v");
6019 $contents .=
'<item>';
6020 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false, $use);
6021 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false, $use);
6022 $contents .=
'</item>';
6024 if ($use ==
'literal') {
6026 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
6028 $xml =
"<$name>$contents</$name>";
6031 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
6033 $this->
debug(
"in serializeType: returning: $xml");
6036 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
6041 $this->
debug(
"in serializeType: No namespace for type $type");
6045 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
6046 $this->
setError(
"$type ($uqType) is not a supported type.");
6047 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
6050 $this->
debug(
"in serializeType: found typeDef");
6052 if (substr($uqType, -1) ==
'^') {
6053 $uqType = substr($uqType, 0, -1);
6056 $phpType = $typeDef[
'phpType'];
6057 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
''));
6059 if ($phpType ==
'struct') {
6060 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
6061 $elementName = $uqType;
6062 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6063 $elementNS =
" xmlns=\"$ns\"";
6065 $elementNS =
" xmlns=\"\"";
6068 $elementName = $name;
6070 $elementNS =
" xmlns=\"\"";
6075 if (is_null($value)) {
6076 if ($use ==
'literal') {
6078 $xml =
"<$elementName$elementNS/>";
6080 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
6082 $this->
debug(
"in serializeType: returning: $xml");
6085 if (is_object($value)) {
6086 $value = get_object_vars($value);
6088 if (is_array($value)) {
6089 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6090 if ($use ==
'literal') {
6092 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
6094 $xml =
"<$elementName$elementNS$elementAttrs>";
6097 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
6100 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6101 $xml .=
"</$elementName>";
6103 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
6104 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
6107 } elseif ($phpType ==
'array') {
6108 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6109 $elementNS =
" xmlns=\"$ns\"";
6112 $elementNS =
" xmlns=\"\"";
6117 if (is_null($value)) {
6118 if ($use ==
'literal') {
6120 $xml =
"<$name$elementNS/>";
6122 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6129 $this->
getLocalPart($typeDef[
'arrayType']) .
"[0]\"/>";
6131 $this->
debug(
"in serializeType: returning: $xml");
6134 if (isset($typeDef[
'multidimensional'])) {
6136 foreach ($value as $v) {
6137 $cols =
',' .
sizeof($v);
6138 $nv = array_merge($nv, $v);
6144 if (is_array($value) &&
sizeof($value) >= 1) {
6145 $rows =
sizeof($value);
6147 foreach ($value as $k => $v) {
6148 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6150 if (!in_array($typeDef[
'arrayType'], $this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6151 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6153 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6162 if ($use ==
'literal') {
6163 $xml =
"<$name$elementNS>" 6167 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/') .
':Array" ' .
6171 .
":" . $this->
getLocalPart($typeDef[
'arrayType']) .
"[$rows$cols]\">" 6175 } elseif ($phpType ==
'scalar') {
6176 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6177 $elementNS =
" xmlns=\"$ns\"";
6180 $elementNS =
" xmlns=\"\"";
6185 if ($use ==
'literal') {
6187 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6189 $xml =
"<$name$elementNS>$value</$name>";
6192 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6195 $this->
debug(
"in serializeType: returning: $xml");
6209 public function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
6212 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6213 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6214 if (is_array($value)) {
6216 } elseif (is_object($value)) {
6217 $xvalue = get_object_vars($value);
6219 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6222 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6223 if (isset($xvalue[
'!' . $aName])) {
6224 $xname =
'!' . $aName;
6225 $this->
debug(
"value provided for attribute $aName with key $xname");
6226 } elseif (isset($xvalue[$aName])) {
6228 $this->
debug(
"value provided for attribute $aName with key $xname");
6229 } elseif (isset($attrs[
'default'])) {
6230 $xname =
'!' . $aName;
6231 $xvalue[$xname] = $attrs[
'default'];
6232 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6235 $this->
debug(
"no value provided for attribute $aName");
6238 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6242 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6244 if (isset($typeDef[
'extensionBase'])) {
6245 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6246 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6250 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6251 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6252 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6254 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6272 public function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false)
6275 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6276 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6277 if (is_array($value)) {
6279 } elseif (is_object($value)) {
6280 $xvalue = get_object_vars($value);
6282 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6286 if (count($typeDef[
'elements']) != count($xvalue)) {
6289 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6290 if (!isset($xvalue[$eName])) {
6291 if (isset($attrs[
'default'])) {
6292 $xvalue[$eName] = $attrs[
'default'];
6293 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6297 if (isset($optionals)
6298 && (!isset($xvalue[$eName]))
6299 && ((!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6301 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6302 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6305 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6308 if (isset($xvalue[$eName])) {
6309 $v = $xvalue[$eName];
6313 if (isset($attrs[
'form'])) {
6314 $unqualified = ($attrs[
'form'] ==
'unqualified');
6316 $unqualified =
false;
6318 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6320 foreach ($vv as $k => $v) {
6321 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6323 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6326 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6327 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6331 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6333 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6336 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6337 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6343 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6345 if (isset($typeDef[
'extensionBase'])) {
6346 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6347 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6351 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6352 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6353 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6355 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6375 public function addComplexType($name, $typeClass=
'complexType', $phpType=
'array', $compositor=
'', $restrictionBase=
'', $elements=array(), $attrs=array(), $arrayType=
'')
6377 if (count($elements) > 0) {
6378 $eElements = array();
6379 foreach ($elements as $n =>
$e) {
6382 foreach (
$e as $k => $v) {
6383 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6384 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6387 $eElements[$n] = $ee;
6389 $elements = $eElements;
6392 if (count($attrs) > 0) {
6393 foreach ($attrs as $n =>
$a) {
6395 foreach (
$a as $k => $v) {
6396 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6397 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6405 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6406 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6408 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6409 $this->schemas[$typens][0]->addComplexType($name, $typeClass, $phpType, $compositor, $restrictionBase, $elements, $attrs, $arrayType);
6423 public function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array())
6425 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6427 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6428 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6438 public function addElement($attrs)
6440 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6441 $this->schemas[$typens][0]->addElement($attrs);
6458 public function addOperation($name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false, $style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
'')
6460 if ($use ==
'encoded' && $encodingStyle ==
'') {
6461 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6464 if ($style ==
'document') {
6465 $elements = array();
6466 foreach ($in as $n => $t) {
6467 $elements[$n] = array(
'name' => $n,
'type' => $t);
6469 $this->addComplexType($name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6470 $this->addElement(array(
'name' => $name,
'type' => $name .
'RequestType'));
6471 $in = array(
'parameters' =>
'tns:' . $name .
'^');
6473 $elements = array();
6474 foreach (
$out as $n => $t) {
6475 $elements[$n] = array(
'name' => $n,
'type' => $t);
6477 $this->addComplexType($name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6478 $this->addElement(array(
'name' => $name .
'Response',
'type' => $name .
'ResponseType',
'form' =>
'qualified'));
6479 $out = array(
'parameters' =>
'tns:' . $name .
'Response' .
'^');
6483 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][$name] =
6486 'binding' => $this->serviceName .
'Binding',
6487 'endpoint' => $this->endpoint,
6488 'soapAction' => $soapaction,
6493 'encodingStyle' => $encodingStyle,
6494 'message' => $name .
'Request',
6499 'encodingStyle' => $encodingStyle,
6500 'message' => $name .
'Response',
6503 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6504 'documentation' => $documentation);
6508 foreach ($in as $pName => $pType) {
6509 if (strpos($pType,
':')) {
6512 $this->messages[$name .
'Request'][$pName] = $pType;
6515 $this->messages[$name .
'Request']=
'0';
6518 foreach (
$out as $pName => $pType) {
6519 if (strpos($pType,
':')) {
6522 $this->messages[$name .
'Response'][$pName] = $pType;
6525 $this->messages[$name .
'Response']=
'0';
6546 public $xml_encoding =
'';
6547 public $method =
'';
6548 public $root_struct =
'';
6549 public $root_struct_name =
'';
6550 public $root_struct_namespace =
'';
6551 public $root_header =
'';
6552 public $document =
'';
6554 public $status =
'';
6555 public $position = 0;
6557 public $default_namespace =
'';
6560 public $parent =
'';
6561 public $fault =
false;
6562 public $fault_code =
'';
6563 public $fault_str =
'';
6564 public $fault_detail =
'';
6565 public $depth_array = array();
6566 public $debug_flag =
true;
6567 public $soapresponse = null;
6568 public $soapheader = null;
6569 public $responseHeaders =
'';
6570 public $body_position = 0;
6573 public $ids = array();
6575 public $multirefs = array();
6577 public $decode_utf8 =
true;
6588 public function __construct($xml, $encoding=
'UTF-8', $method=
'', $decode_utf8=
true)
6592 $this->xml_encoding = $encoding;
6593 $this->method = $method;
6594 $this->decode_utf8 = $decode_utf8;
6599 $pos_xml = strpos($xml,
'<?xml');
6600 if ($pos_xml !==
false) {
6601 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6602 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6603 $xml_encoding =
$res[1];
6604 if (strtoupper($xml_encoding) != $encoding) {
6605 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6607 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6613 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6616 $this->
debug(
'No encoding specified in XML declaration');
6619 $this->
debug(
'No XML declaration');
6621 $this->
debug(
'Entering nusoap_parser(), length=' . strlen($xml) .
', encoding=' . $encoding);
6623 $this->parser = xml_parser_create($this->xml_encoding);
6626 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6627 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6629 xml_set_object($this->parser, $this);
6631 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6632 xml_set_character_data_handler($this->parser,
'character_data');
6635 if (!xml_parse($this->parser, $xml,
true)) {
6638 'XML error parsing SOAP payload on line %d: %s',
6639 xml_get_current_line_number($this->parser),
6640 xml_error_string(xml_get_error_code($this->parser))
6643 $this->
debug(
"XML payload:\n" . $xml);
6646 $this->
debug(
'parsed successfully, found root struct: ' . $this->root_struct .
' of name ' . $this->root_struct_name);
6648 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6650 if ($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])) {
6651 $this->soapheader = $this->message[$this->root_header][
'result'];
6654 if (
sizeof($this->multirefs) > 0) {
6655 foreach ($this->multirefs as
$id => $hrefs) {
6656 $this->
debug(
'resolving multirefs for id: ' .
$id);
6657 $idVal = $this->buildVal($this->ids[
$id]);
6658 if (is_array($idVal) && isset($idVal[
'!id'])) {
6659 unset($idVal[
'!id']);
6661 foreach ($hrefs as $refPos => $ref) {
6662 $this->
debug(
'resolving href at pos ' . $refPos);
6663 $this->multirefs[
$id][$refPos] = $idVal;
6668 xml_parser_free($this->parser);
6670 $this->
debug(
'xml was empty, didn\'t parse!');
6671 $this->
setError(
'xml was empty, didn\'t parse!');
6683 public function start_element($parser, $name, $attrs)
6687 $pos = $this->position++;
6689 $this->message[$pos] = array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6692 $this->message[$pos][
'depth'] = $this->depth++;
6696 $this->message[$this->parent][
'children'] .=
'|' . $pos;
6699 $this->message[$pos][
'parent'] = $this->parent;
6701 $this->parent = $pos;
6703 $this->depth_array[$this->depth] = $pos;
6705 if (strpos($name,
':')) {
6707 $prefix = substr($name, 0, strpos($name,
':'));
6709 $name = substr(strstr($name,
':'), 1);
6712 if ($name ==
'Envelope') {
6713 $this->status =
'envelope';
6714 } elseif ($name ==
'Header' && $this->status =
'envelope') {
6715 $this->root_header = $pos;
6716 $this->status =
'header';
6717 } elseif ($name ==
'Body' && $this->status =
'envelope') {
6718 $this->status =
'body';
6719 $this->body_position = $pos;
6721 } elseif ($this->status ==
'body' && $pos == ($this->body_position+1)) {
6722 $this->status =
'method';
6723 $this->root_struct_name = $name;
6724 $this->root_struct = $pos;
6725 $this->message[$pos][
'type'] =
'struct';
6726 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6729 $this->message[$pos][
'status'] = $this->status;
6731 $this->message[$pos][
'name'] = htmlspecialchars($name);
6733 $this->message[$pos][
'attrs'] = $attrs;
6737 foreach ($attrs as
$key => $value) {
6741 if ($key_prefix ==
'xmlns') {
6742 if (preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/', $value)) {
6743 $this->XMLSchemaVersion = $value;
6745 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion .
'-instance';
6747 $this->namespaces[$key_localpart] = $value;
6749 if ($name == $this->root_struct_name) {
6750 $this->methodNamespace = $value;
6753 } elseif ($key_localpart ==
'type') {
6754 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6757 $value_prefix = $this->
getPrefix($value);
6759 $this->message[$pos][
'type'] = $value_localpart;
6760 $this->message[$pos][
'typePrefix'] = $value_prefix;
6761 if (isset($this->namespaces[$value_prefix])) {
6762 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6763 } elseif (isset($attrs[
'xmlns:' . $value_prefix])) {
6764 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:' . $value_prefix];
6768 } elseif ($key_localpart ==
'arrayType') {
6769 $this->message[$pos][
'type'] =
'array';
6778 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6779 if (preg_match($expr, $value, $regs)) {
6780 $this->message[$pos][
'typePrefix'] = $regs[1];
6781 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6782 if (isset($this->namespaces[$regs[1]])) {
6783 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6784 } elseif (isset($attrs[
'xmlns:' . $regs[1]])) {
6785 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:' . $regs[1]];
6787 $this->message[$pos][
'arrayType'] = $regs[2];
6788 $this->message[$pos][
'arraySize'] = $regs[3];
6789 $this->message[$pos][
'arrayCols'] = $regs[4];
6792 } elseif ($key_localpart ==
'nil') {
6793 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6795 } elseif (
$key !=
'href' &&
$key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6796 $this->message[$pos][
'xattrs'][
'!' .
$key] = $value;
6799 if (
$key ==
'xmlns') {
6800 $this->default_namespace = $value;
6804 $this->ids[$value] = $pos;
6807 if ($key_localpart ==
'root' && $value == 1) {
6808 $this->status =
'method';
6809 $this->root_struct_name = $name;
6810 $this->root_struct = $pos;
6811 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6814 $attstr .=
" $key=\"$value\"";
6817 if (isset($prefix)) {
6818 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6819 $this->default_namespace = $this->namespaces[$prefix];
6821 $this->message[$pos][
'namespace'] = $this->default_namespace;
6823 if ($this->status ==
'header') {
6824 if ($this->root_header != $pos) {
6825 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6827 } elseif ($this->root_struct_name !=
'') {
6828 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6839 public function end_element($parser, $name)
6842 $pos = $this->depth_array[$this->depth--];
6845 if (strpos($name,
':')) {
6847 $prefix = substr($name, 0, strpos($name,
':'));
6849 $name = substr(strstr($name,
':'), 1);
6853 if (isset($this->body_position) && $pos > $this->body_position) {
6855 if (isset($this->message[$pos][
'attrs'][
'href'])) {
6857 $id = substr($this->message[$pos][
'attrs'][
'href'], 1);
6859 $this->multirefs[
$id][$pos] =
'placeholder';
6861 $this->message[$pos][
'result'] =& $this->multirefs[
$id][$pos];
6863 } elseif ($this->message[$pos][
'children'] !=
'') {
6865 if (!isset($this->message[$pos][
'result'])) {
6866 $this->message[$pos][
'result'] = $this->buildVal($pos);
6869 } elseif (isset($this->message[$pos][
'xattrs'])) {
6870 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6871 $this->message[$pos][
'xattrs'][
'!'] = null;
6872 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6873 if (isset($this->message[$pos][
'type'])) {
6874 $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'] :
'');
6876 $parent = $this->message[$pos][
'parent'];
6877 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6878 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6880 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6884 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6888 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6889 $this->message[$pos][
'xattrs'][
'!'] = null;
6890 } elseif (isset($this->message[$pos][
'type'])) {
6891 $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'] :
'');
6893 $parent = $this->message[$pos][
'parent'];
6894 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6895 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6897 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6915 if ($this->status ==
'header') {
6916 if ($this->root_header != $pos) {
6917 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6919 } elseif ($pos >= $this->root_struct) {
6920 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6923 if ($pos == $this->root_struct) {
6924 $this->status =
'body';
6925 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6926 } elseif ($name ==
'Body') {
6927 $this->status =
'envelope';
6928 } elseif ($name ==
'Header') {
6929 $this->status =
'envelope';
6930 } elseif ($name ==
'Envelope') {
6934 $this->parent = $this->message[$pos][
'parent'];
6944 public function character_data($parser,
$data)
6946 $pos = $this->depth_array[$this->depth];
6947 if ($this->xml_encoding==
'UTF-8') {
6951 if ($this->decode_utf8) {
6955 $this->message[$pos][
'cdata'] .=
$data;
6957 if ($this->status ==
'header') {
6958 $this->responseHeaders .=
$data;
6960 $this->document .=
$data;
6971 public function get_response()
6973 return $this->soapresponse;
6982 public function get_soapbody()
6984 return $this->soapresponse;
6993 public function get_soapheader()
6995 return $this->soapheader;
7004 public function getHeaders()
7006 return $this->responseHeaders;
7018 public function decodeSimple($value, $type, $typens)
7021 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
7022 return (
string) $value;
7024 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
7025 return (
int) $value;
7027 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
7028 return (
float) $value;
7030 if ($type ==
'boolean') {
7031 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
7034 return (
bool) $value;
7036 if ($type ==
'base64' || $type ==
'base64Binary') {
7037 $this->
debug(
'Decode base64 value');
7038 return base64_decode($value);
7041 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 7042 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 7043 || $type ==
'unsignedInt' 7044 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
7045 return (
int) $value;
7048 if ($type ==
'array') {
7052 return (
string) $value;
7063 public function buildVal($pos)
7065 if (!isset($this->message[$pos][
'type'])) {
7066 $this->message[$pos][
'type'] =
'';
7068 $this->
debug(
'in buildVal() for ' . $this->message[$pos][
'name'] .
"(pos $pos) of type " . $this->message[$pos][
'type']);
7070 if ($this->message[$pos][
'children'] !=
'') {
7071 $this->
debug(
'in buildVal, there are children');
7072 $children = explode(
'|', $this->message[$pos][
'children']);
7073 array_shift($children);
7075 if (isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
'') {
7078 foreach ($children as $child_pos) {
7079 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
7080 $params[
$r][] = $this->message[$child_pos][
'result'];
7082 if (
$c == $this->message[$pos][
'arrayCols']) {
7088 } elseif ($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array') {
7089 $this->
debug(
'in buildVal, adding array ' . $this->message[$pos][
'name']);
7090 foreach ($children as $child_pos) {
7091 $params[] = &$this->message[$child_pos][
'result'];
7094 } elseif ($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7095 $this->
debug(
'in buildVal, Java Map ' . $this->message[$pos][
'name']);
7096 foreach ($children as $child_pos) {
7097 $kv = explode(
"|", $this->message[$child_pos][
'children']);
7098 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
7104 $this->
debug(
'in buildVal, adding Java Vector or generic compound type ' . $this->message[$pos][
'name']);
7105 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
7111 foreach ($children as $child_pos) {
7113 $params[] = &$this->message[$child_pos][
'result'];
7115 if (isset(
$params[$this->message[$child_pos][
'name']])) {
7117 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
7118 $params[$this->message[$child_pos][
'name']] = array(
$params[$this->message[$child_pos][
'name']]);
7120 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
7122 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
7127 if (isset($this->message[$pos][
'xattrs'])) {
7128 $this->
debug(
'in buildVal, handling attributes');
7129 foreach ($this->message[$pos][
'xattrs'] as $n => $v) {
7134 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7135 $this->
debug(
'in buildVal, handling simpleContent');
7136 if (isset($this->message[$pos][
'type'])) {
7137 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7139 $parent = $this->message[$pos][
'parent'];
7140 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7141 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7143 $params[
'!'] = $this->message[$pos][
'cdata'];
7148 $this->
debug(
'in buildVal, return:');
7152 $this->
debug(
'in buildVal, no children, building scalar');
7153 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7154 if (isset($this->message[$pos][
'type'])) {
7155 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7156 $this->
debug(
"in buildVal, return: $ret");
7159 $parent = $this->message[$pos][
'parent'];
7160 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7161 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7162 $this->
debug(
"in buildVal, return: $ret");
7165 $ret = $this->message[$pos][
'cdata'];
7166 $this->
debug(
"in buildVal, return: $ret");
7205 public $username =
'';
7206 public $password =
'';
7207 public $authtype =
'';
7208 public $certRequest = array();
7209 public $requestHeaders =
false;
7210 public $responseHeaders =
'';
7211 public $responseHeader = null;
7212 public $document =
'';
7214 public $forceEndpoint =
'';
7215 public $proxyhost =
'';
7216 public $proxyport =
'';
7217 public $proxyusername =
'';
7218 public $proxypassword =
'';
7219 public $xml_encoding =
'';
7220 public $http_encoding =
false;
7221 public $timeout = 0;
7222 public $response_timeout = 30;
7223 public $endpointType =
'';
7224 public $persistentConnection =
false;
7225 public $defaultRpcParams =
false;
7226 public $request =
'';
7229 public $cookies = array();
7230 public $decode_utf8 =
true;
7231 public $operations = array();
7232 public $curl_options = array();
7233 public $bindingType =
'';
7234 public $use_curl =
false;
7274 public function __construct($endpoint, $wsdl =
false, $proxyhost =
false, $proxyport =
false, $proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30)
7277 $this->endpoint = $endpoint;
7278 $this->proxyhost = $proxyhost;
7279 $this->proxyport = $proxyport;
7280 $this->proxyusername = $proxyusername;
7281 $this->proxypassword = $proxypassword;
7282 $this->timeout = $timeout;
7283 $this->response_timeout = $response_timeout;
7285 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7290 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7291 $this->
wsdl = $endpoint;
7292 $this->endpoint = $this->
wsdl->wsdl;
7293 $this->wsdlFile = $this->endpoint;
7294 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7297 $this->wsdlFile = $this->endpoint;
7299 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7301 $this->endpointType =
'wsdl';
7303 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7304 $this->endpointType =
'soap';
7333 public function call($operation,
$params=array(),
$namespace=
'http://tempuri.org', $soapAction=
'', $headers=
false, $rpcParams=null, $style=
'rpc', $use=
'encoded')
7335 $this->operation = $operation;
7336 $this->fault =
false;
7338 $this->request =
'';
7339 $this->response =
'';
7340 $this->responseData =
'';
7341 $this->faultstring =
'';
7342 $this->faultcode =
'';
7343 $this->opData = array();
7345 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7349 $this->requestHeaders = $headers;
7351 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7358 if ($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)) {
7360 $this->opData = $opData;
7361 $this->
debug(
"found operation");
7363 if (isset($opData[
'soapAction'])) {
7364 $soapAction = $opData[
'soapAction'];
7366 if (! $this->forceEndpoint) {
7367 $this->endpoint = $opData[
'endpoint'];
7369 $this->endpoint = $this->forceEndpoint;
7371 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7372 $style = $opData[
'style'];
7373 $use = $opData[
'input'][
'use'];
7376 $nsPrefix =
'ns' . rand(1000, 9999);
7382 $this->
debug(
"serializing param string for WSDL operation $operation");
7384 } elseif (is_array(
$params)) {
7385 $this->
debug(
"serializing param array for WSDL operation $operation");
7388 $this->
debug(
'params must be array or string');
7389 $this->
setError(
'params must be array or string');
7393 if (isset($opData[
'input'][
'encodingStyle'])) {
7394 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7396 $encodingStyle =
'';
7401 $this->
debug(
'got wsdl error: ' . $errstr);
7402 $this->
setError(
'wsdl error: ' . $errstr);
7405 } elseif ($this->endpointType ==
'wsdl') {
7409 $this->
setError(
'operation ' . $operation .
' not present.');
7410 $this->
debug(
"operation '$operation' not present.");
7415 $nsPrefix =
'ns' . rand(1000, 9999);
7419 $this->
debug(
"serializing param string for operation $operation");
7421 } elseif (is_array(
$params)) {
7422 $this->
debug(
"serializing param array for operation $operation");
7423 foreach (
$params as $k => $v) {
7427 $this->
debug(
'params must be array or string');
7428 $this->
setError(
'params must be array or string');
7432 if ($use ==
'encoded') {
7433 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7435 $encodingStyle =
'';
7439 if ($style ==
'rpc') {
7440 if ($use ==
'literal') {
7441 $this->
debug(
"wrapping RPC request with literal method element");
7444 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7446 "</$nsPrefix:$operation>";
7451 $this->
debug(
"wrapping RPC request with encoded method element");
7453 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7455 "</$nsPrefix:$operation>";
7465 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7466 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7468 $return = $this->
send($this->getHTTPBody($soapmsg), $soapAction, $this->timeout, $this->response_timeout);
7470 $this->
debug(
'Error: ' . $errstr);
7473 $this->
return = $return;
7474 $this->
debug(
'sent message successfully and got a(n) ' . gettype($return));
7478 if (is_array($return) && isset($return[
'faultcode'])) {
7479 $this->
debug(
'got fault');
7480 $this->
setError($return[
'faultcode'] .
': ' . $return[
'faultstring']);
7481 $this->fault =
true;
7482 foreach ($return as $k => $v) {
7484 $this->
debug(
"$k = $v<br>");
7487 } elseif ($style ==
'document') {
7493 if (is_array($return)) {
7496 if (
sizeof($return) > 1) {
7500 $return = array_shift($return);
7501 $this->
debug(
'return shifted value: ');
7517 public function checkWSDL()
7521 $this->
debug(
'checkWSDL');
7524 $this->
debug(
'got wsdl error: ' . $errstr);
7525 $this->
setError(
'wsdl error: ' . $errstr);
7527 $this->bindingType =
'soap';
7528 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7530 $this->bindingType =
'soap12';
7531 $this->
debug(
'got ' . count($this->operations) .
' operations from wsdl ' . $this->wsdlFile .
' for binding type ' . $this->bindingType);
7532 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7534 $this->
debug(
'getOperations returned false');
7535 $this->
setError(
'no operations defined in the WSDL document!');
7544 public function loadWSDL()
7546 $this->
debug(
'instantiating wsdl class with doc: ' . $this->wsdlFile);
7547 $this->
wsdl =
new wsdl(
'', $this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword, $this->timeout, $this->response_timeout, $this->curl_options, $this->use_curl);
7548 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7560 public function getOperationData($operation)
7562 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7568 if (isset($this->operations[$operation])) {
7569 return $this->operations[$operation];
7571 $this->
debug(
"No data for operation: $operation");
7588 public function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30)
7590 $this->checkCookies();
7594 case preg_match(
'/^http/', $this->endpoint):
7595 $this->
debug(
'transporting via HTTP');
7596 if ($this->persistentConnection ==
true && is_object($this->persistentConnection)) {
7597 $http =& $this->persistentConnection;
7600 if ($this->persistentConnection) {
7601 $http->usePersistentConnection();
7604 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7605 $http->setSOAPAction($soapaction);
7606 if ($this->proxyhost && $this->proxyport) {
7607 $http->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
7609 if ($this->authtype !=
'') {
7610 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7612 if ($this->http_encoding !=
'') {
7613 $http->setEncoding($this->http_encoding);
7615 $this->
debug(
'sending message, length=' . strlen($msg));
7616 if (preg_match(
'/^http:/', $this->endpoint)) {
7618 $this->responseData =
$http->send($msg, $timeout, $response_timeout, $this->cookies);
7619 } elseif (preg_match(
'/^https/', $this->endpoint)) {
7626 $this->responseData =
$http->sendHTTPS($msg, $timeout, $response_timeout, $this->cookies);
7628 $this->
setError(
'no http/s in endpoint url');
7630 $this->request =
$http->outgoing_payload;
7631 $this->response =
$http->incoming_payload;
7633 $this->UpdateCookies(
$http->incoming_cookies);
7636 if ($this->persistentConnection) {
7637 $http->clearDebug();
7638 if (!is_object($this->persistentConnection)) {
7639 $this->persistentConnection =
$http;
7643 if ($err =
$http->getError()) {
7644 $this->
setError(
'HTTP Error: ' . $err);
7649 $this->
debug(
'got response, length=' . strlen($this->responseData) .
' type=' .
$http->incoming_headers[
'content-type']);
7650 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7654 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7668 public function parseResponse($headers,
$data)
7670 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7672 if (!strstr($headers[
'content-type'],
'text/xml')) {
7673 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7676 if (strpos($headers[
'content-type'],
'=')) {
7677 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7678 $this->
debug(
'Got response encoding: ' . $enc);
7679 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
7680 $this->xml_encoding = strtoupper($enc);
7682 $this->xml_encoding =
'US-ASCII';
7686 $this->xml_encoding =
'ISO-8859-1';
7688 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7689 $parser =
new nusoap_parser(
$data, $this->xml_encoding, $this->operation, $this->decode_utf8);
7693 if ($errstr = $parser->getError()) {
7700 $this->responseHeaders = $parser->getHeaders();
7702 $this->responseHeader = $parser->get_soapheader();
7704 $return = $parser->get_soapbody();
7706 $this->document = $parser->document;
7721 public function setCurlOption($option, $value)
7723 $this->
debug(
"setCurlOption option=$option, value=");
7725 $this->curl_options[$option] = $value;
7734 public function setEndpoint($endpoint)
7736 $this->
debug(
"setEndpoint(\"$endpoint\")");
7737 $this->forceEndpoint = $endpoint;
7746 public function setHeaders($headers)
7748 $this->
debug(
"setHeaders headers=");
7750 $this->requestHeaders = $headers;
7759 public function getHeaders()
7761 return $this->responseHeaders;
7770 public function getHeader()
7772 return $this->responseHeader;
7784 public function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'')
7786 $this->proxyhost = $proxyhost;
7787 $this->proxyport = $proxyport;
7788 $this->proxyusername = $proxyusername;
7789 $this->proxypassword = $proxypassword;
7801 public function setCredentials($username, $password, $authtype =
'basic', $certRequest = array())
7803 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7805 $this->username = $username;
7806 $this->password = $password;
7807 $this->authtype = $authtype;
7808 $this->certRequest = $certRequest;
7817 public function setHTTPEncoding($enc=
'gzip, deflate')
7819 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7820 $this->http_encoding = $enc;
7829 public function setUseCURL($use)
7831 $this->
debug(
"setUseCURL($use)");
7832 $this->use_curl = $use;
7840 public function useHTTPPersistentConnection()
7842 $this->
debug(
"useHTTPPersistentConnection");
7843 $this->persistentConnection =
true;
7857 public function getDefaultRpcParams()
7859 return $this->defaultRpcParams;
7873 public function setDefaultRpcParams($rpcParams)
7875 $this->defaultRpcParams = $rpcParams;
7885 public function getProxy()
7888 $evalStr = $this->_getProxyClassCode(
$r);
7891 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7897 eval(
"\$proxy = new nusoap_proxy_$r('');");
7899 $proxy->endpointType =
'wsdl';
7900 $proxy->wsdlFile = $this->wsdlFile;
7901 $proxy->wsdl = $this->wsdl;
7902 $proxy->operations = $this->operations;
7903 $proxy->defaultRpcParams = $this->defaultRpcParams;
7906 $proxy->username = $this->username;
7907 $proxy->password = $this->password;
7908 $proxy->authtype = $this->authtype;
7909 $proxy->certRequest = $this->certRequest;
7910 $proxy->requestHeaders = $this->requestHeaders;
7911 $proxy->endpoint = $this->endpoint;
7912 $proxy->forceEndpoint = $this->forceEndpoint;
7913 $proxy->proxyhost = $this->proxyhost;
7914 $proxy->proxyport = $this->proxyport;
7915 $proxy->proxyusername = $this->proxyusername;
7916 $proxy->proxypassword = $this->proxypassword;
7917 $proxy->http_encoding = $this->http_encoding;
7918 $proxy->timeout = $this->timeout;
7919 $proxy->response_timeout = $this->response_timeout;
7920 $proxy->persistentConnection = &$this->persistentConnection;
7921 $proxy->decode_utf8 = $this->decode_utf8;
7922 $proxy->curl_options = $this->curl_options;
7923 $proxy->bindingType = $this->bindingType;
7924 $proxy->use_curl = $this->use_curl;
7934 public function _getProxyClassCode(
$r)
7936 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7938 if ($this->endpointType !=
'wsdl') {
7939 $evalStr =
'A proxy can only be created for a WSDL client';
7941 $evalStr =
"echo \"$evalStr\";";
7944 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7947 return "echo \"" . $this->
getError() .
"\";";
7951 foreach ($this->operations as $operation => $opData) {
7952 if ($operation !=
'') {
7954 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7956 $paramArrayStr =
'';
7957 $paramCommentStr =
'';
7958 foreach ($opData[
'input'][
'parts'] as $name => $type) {
7959 $paramStr .=
"\$$name, ";
7960 $paramArrayStr .=
"'$name' => \$$name, ";
7961 $paramCommentStr .=
"$type \$$name, ";
7963 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7964 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7965 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7968 $paramArrayStr =
'';
7969 $paramCommentStr =
'void';
7971 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7972 $evalStr .=
"// $paramCommentStr 7973 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7974 \$params = array($paramArrayStr); 7975 return \$this->call('$operation', \$params, '" . $opData[
'namespace'] .
"', '" . (isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'') .
"'); 7979 unset($paramCommentStr);
7982 $evalStr =
'class nusoap_proxy_' .
$r .
' extends nusoap_client { 7994 public function getProxyClassCode()
7997 return $this->_getProxyClassCode(
$r);
8007 public function getHTTPBody($soapmsg)
8020 public function getHTTPContentType()
8034 public function getHTTPContentTypeCharset()
8045 public function decodeUTF8($bool)
8047 $this->decode_utf8 = $bool;
8059 public function setCookie($name, $value)
8061 if (strlen($name) == 0) {
8064 $this->cookies[] = array(
'name' => $name,
'value' => $value);
8074 public function getCookies()
8076 return $this->cookies;
8085 public function checkCookies()
8087 if (
sizeof($this->cookies) == 0) {
8090 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
8091 $curr_cookies = $this->cookies;
8092 $this->cookies = array();
8093 foreach ($curr_cookies as $cookie) {
8094 if (! is_array($cookie)) {
8095 $this->
debug(
'Remove cookie that is not an array');
8098 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
8099 if (strtotime($cookie[
'expires']) > time()) {
8100 $this->cookies[] = $cookie;
8102 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
8105 $this->cookies[] = $cookie;
8108 $this->
debug(
'checkCookie: ' .
sizeof($this->cookies) .
' cookies left in array');
8119 public function UpdateCookies($cookies)
8121 if (
sizeof($this->cookies) == 0) {
8123 if (
sizeof($cookies) > 0) {
8124 $this->
debug(
'Setting new cookie(s)');
8125 $this->cookies = $cookies;
8129 if (
sizeof($cookies) == 0) {
8134 foreach ($cookies as $newCookie) {
8135 if (!is_array($newCookie)) {
8138 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
8141 $newName = $newCookie[
'name'];
8144 for ($i = 0; $i < count($this->cookies); $i++) {
8145 $cookie = $this->cookies[$i];
8146 if (!is_array($cookie)) {
8149 if (!isset($cookie[
'name'])) {
8152 if ($newName != $cookie[
'name']) {
8155 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
8156 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
8157 if ($newDomain != $domain) {
8160 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
8161 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
8162 if ($newPath !=
$path) {
8165 $this->cookies[$i] = $newCookie;
8167 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8171 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8172 $this->cookies[] = $newCookie;
8179 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
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)