For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
985 $stop = gettimeofday();
986 $timePassed = 1000000 * ($stop[
'sec'] -
$start[
'sec'])
987 + $stop[
'usec'] -
$start[
'usec'];
989 while ($timePassed < $usec);
1038 function __construct($faultcode,$faultactor=
'',$faultstring=
'',$faultdetail=
''){
1039 parent::__construct();
1054 foreach($this->namespaces as $k => $v){
1055 $ns_string .=
"\n xmlns:$k=\"$v\"";
1058 '<?xml version="1.0" encoding="'.$this->soap_defencoding.
'"?>'.
1059 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.
">\n".
1066 '</SOAP-ENV:Fault>'.
1068 '</SOAP-ENV:Envelope>';
1098 var $enclosingNamespaces;
1100 var $schemaInfo = array();
1101 var $schemaTargetNamespace =
'';
1104 var $complexTypes = array();
1105 var $complexTypeStack = array();
1106 var $currentComplexType = null;
1107 var $elements = array();
1108 var $elementStack = array();
1109 var $currentElement = null;
1110 var $simpleTypes = array();
1111 var $simpleTypeStack = array();
1112 var $currentSimpleType = null;
1114 var $imports = array();
1119 var $depth_array = array();
1121 var $defaultNamespace = array();
1132 parent::__construct();
1133 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
1135 $this->schema = $schema;
1140 $this->namespaces = array_merge($this->namespaces,
$namespaces);
1144 $this->
debug(
'initial schema file: '.$schema);
1145 $this->parseFile($schema,
'schema');
1150 $this->
debug(
'initial xml file: '.$xml);
1151 $this->parseFile($xml,
'xml');
1164 function parseFile($xml,
$type){
1167 $xmlStr = @join(
"",@file($xml));
1169 $msg =
'Error reading XML from '.$xml;
1174 $this->
debug(
"parsing $xml");
1175 $this->parseString($xmlStr,
$type);
1176 $this->
debug(
"done parsing $xml");
1190 function parseString($xml,
$type){
1195 $this->parser = xml_parser_create();
1197 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1200 xml_set_object($this->parser, $this);
1203 if(
$type ==
"schema"){
1204 xml_set_element_handler($this->parser,
'schemaStartElement',
'schemaEndElement');
1205 xml_set_character_data_handler($this->parser,
'schemaCharacterData');
1206 } elseif(
$type ==
"xml"){
1207 xml_set_element_handler($this->parser,
'xmlStartElement',
'xmlEndElement');
1208 xml_set_character_data_handler($this->parser,
'xmlCharacterData');
1212 if(!xml_parse($this->parser,$xml,
true)){
1214 $errstr = sprintf(
'XML error parsing XML schema on line %d: %s',
1215 xml_get_current_line_number($this->parser),
1216 xml_error_string(xml_get_error_code($this->parser))
1218 $this->
debug($errstr);
1219 $this->
debug(
"XML payload:\n" . $xml);
1223 xml_parser_free($this->parser);
1225 $this->
debug(
'no xml passed to parseString()!!');
1226 $this->
setError(
'no xml passed to parseString()!!');
1237 function CreateTypeName($ename) {
1239 for (
$i = 0;
$i < count($this->complexTypeStack);
$i++) {
1240 $scope .= $this->complexTypeStack[
$i] .
'_';
1242 return $scope . $ename .
'_ContainedType';
1253 function schemaStartElement($parser,
$name, $attrs) {
1256 $pos = $this->position++;
1257 $depth = $this->depth++;
1259 $this->depth_array[$depth] = $pos;
1260 $this->message[$pos] = array(
'cdata' =>
'');
1262 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1264 $this->defaultNamespace[$pos] =
false;
1276 if(count($attrs) > 0){
1277 foreach($attrs as $k => $v){
1279 if(preg_match(
'/^xmlns/',$k)){
1282 if($ns_prefix = substr(strrchr($k,
':'),1)){
1284 $this->namespaces[$ns_prefix] = $v;
1286 $this->defaultNamespace[$pos] = $v;
1288 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $v;
1291 if($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema'){
1292 $this->XMLSchemaVersion = $v;
1293 $this->namespaces[
'xsi'] = $v.
'-instance';
1297 foreach($attrs as $k => $v){
1299 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
1300 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
1314 $this->complexTypes[$this->currentComplexType][
'compositor'] =
$name;
1321 $this->xdebug(
"parsing attribute:");
1323 if (!isset($attrs[
'form'])) {
1324 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
1326 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1327 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1328 if (!strpos($v,
':')) {
1330 if ($this->defaultNamespace[$pos]) {
1332 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1336 if(isset($attrs[
'name'])){
1337 $this->attributes[$attrs[
'name']] = $attrs;
1338 $aname = $attrs[
'name'];
1339 } elseif(isset($attrs[
'ref']) && $attrs[
'ref'] ==
'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1340 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1341 $aname = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1345 } elseif(isset($attrs[
'ref'])){
1346 $aname = $attrs[
'ref'];
1347 $this->attributes[$attrs[
'ref']] = $attrs;
1350 if($this->currentComplexType){
1351 $this->complexTypes[$this->currentComplexType][
'attrs'][$aname] = $attrs;
1354 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType'){
1355 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1357 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1358 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
1362 if(strpos($v,
'[,]')){
1363 $this->complexTypes[$this->currentComplexType][
'multidimensional'] =
true;
1365 $v = substr($v,0,strpos($v,
'['));
1366 if(!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
1367 $v = $this->XMLSchemaVersion.
':'.$v;
1369 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $v;
1372 case 'complexContent':
1375 array_push($this->complexTypeStack, $this->currentComplexType);
1376 if(isset($attrs[
'name'])){
1379 $this->xdebug(
'processing named complexType '.$attrs[
'name']);
1381 $this->currentComplexType = $attrs[
'name'];
1382 $this->complexTypes[$this->currentComplexType] = $attrs;
1383 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1391 if(isset($attrs[
'base']) && preg_match(
'/:Array$/',$attrs[
'base'])){
1392 $this->xdebug(
'complexType is unusual array');
1393 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1395 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1398 $name = $this->CreateTypeName($this->currentElement);
1399 $this->xdebug(
'processing unnamed complexType for element ' . $this->currentElement .
' named ' .
$name);
1400 $this->currentComplexType =
$name;
1402 $this->complexTypes[$this->currentComplexType] = $attrs;
1403 $this->complexTypes[$this->currentComplexType][
'typeClass'] =
'complexType';
1411 if(isset($attrs[
'base']) && preg_match(
'/:Array$/',$attrs[
'base'])){
1412 $this->xdebug(
'complexType is unusual array');
1413 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1415 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'struct';
1420 array_push($this->elementStack, $this->currentElement);
1421 if (!isset($attrs[
'form'])) {
1422 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
1424 if(isset($attrs[
'type'])){
1425 $this->xdebug(
"processing typed element ".$attrs[
'name'].
" of type ".$attrs[
'type']);
1426 if (! $this->
getPrefix($attrs[
'type'])) {
1427 if ($this->defaultNamespace[$pos]) {
1428 $attrs[
'type'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'type'];
1429 $this->xdebug(
'used default namespace to make type ' . $attrs[
'type']);
1439 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
1440 $this->xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
1441 $this->complexTypes[$this->currentComplexType][
'arrayType'] = $attrs[
'type'];
1443 $this->currentElement = $attrs[
'name'];
1444 $ename = $attrs[
'name'];
1445 } elseif(isset($attrs[
'ref'])){
1446 $this->xdebug(
"processing element as ref to ".$attrs[
'ref']);
1447 $this->currentElement =
"ref to ".$attrs[
'ref'];
1450 $type = $this->CreateTypeName($this->currentComplexType .
'_' . $attrs[
'name']);
1451 $this->xdebug(
"processing untyped element " . $attrs[
'name'] .
' type ' .
$type);
1452 $this->currentElement = $attrs[
'name'];
1453 $attrs[
'type'] = $this->schemaTargetNamespace .
':' .
$type;
1454 $ename = $attrs[
'name'];
1456 if (isset($ename) && $this->currentComplexType) {
1457 $this->xdebug(
"add element $ename to complexType $this->currentComplexType");
1458 $this->complexTypes[$this->currentComplexType][
'elements'][$ename] = $attrs;
1459 } elseif (!isset($attrs[
'ref'])) {
1460 $this->xdebug(
"add element $ename to elements array");
1461 $this->elements[ $attrs[
'name'] ] = $attrs;
1462 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
1466 $this->xdebug(
'enumeration ' . $attrs[
'value']);
1467 if ($this->currentSimpleType) {
1468 $this->simpleTypes[$this->currentSimpleType][
'enumeration'][] = $attrs[
'value'];
1469 } elseif ($this->currentComplexType) {
1470 $this->complexTypes[$this->currentComplexType][
'enumeration'][] = $attrs[
'value'];
1474 $this->xdebug(
'extension ' . $attrs[
'base']);
1475 if ($this->currentComplexType) {
1476 $this->complexTypes[$this->currentComplexType][
'extensionBase'] = $attrs[
'base'];
1480 if (isset($attrs[
'schemaLocation'])) {
1482 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
1485 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
1487 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $attrs[
'namespace'];
1494 $this->xdebug(
'restriction ' . $attrs[
'base']);
1495 if($this->currentSimpleType){
1496 $this->simpleTypes[$this->currentSimpleType][
'type'] = $attrs[
'base'];
1497 } elseif($this->currentComplexType){
1498 $this->complexTypes[$this->currentComplexType][
'restrictionBase'] = $attrs[
'base'];
1499 if(strstr($attrs[
'base'],
':') ==
':Array'){
1500 $this->complexTypes[$this->currentComplexType][
'phpType'] =
'array';
1505 $this->schemaInfo = $attrs;
1507 if (isset($attrs[
'targetNamespace'])) {
1508 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
1510 if (!isset($attrs[
'elementFormDefault'])) {
1511 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
1513 if (!isset($attrs[
'attributeFormDefault'])) {
1514 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
1517 case 'simpleContent':
1520 array_push($this->simpleTypeStack, $this->currentSimpleType);
1521 if(isset($attrs[
'name'])){
1522 $this->xdebug(
"processing simpleType for name " . $attrs[
'name']);
1523 $this->currentSimpleType = $attrs[
'name'];
1524 $this->simpleTypes[ $attrs[
'name'] ] = $attrs;
1525 $this->simpleTypes[ $attrs[
'name'] ][
'typeClass'] =
'simpleType';
1526 $this->simpleTypes[ $attrs[
'name'] ][
'phpType'] =
'scalar';
1528 $name = $this->CreateTypeName($this->currentComplexType .
'_' . $this->currentElement);
1529 $this->xdebug(
'processing unnamed simpleType for element ' . $this->currentElement .
' named ' .
$name);
1530 $this->currentSimpleType =
$name;
1532 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1533 $this->simpleTypes[$this->currentSimpleType][
'phpType'] =
'scalar';
1550 function schemaEndElement($parser,
$name) {
1554 if(isset($this->depth_array[$this->depth])){
1555 $pos = $this->depth_array[$this->depth];
1565 if(
$name ==
'complexType'){
1566 $this->xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
1567 $this->currentComplexType = array_pop($this->complexTypeStack);
1570 if(
$name ==
'element'){
1571 $this->xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
1572 $this->currentElement = array_pop($this->elementStack);
1574 if(
$name ==
'simpleType'){
1575 $this->xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
1576 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1587 function schemaCharacterData($parser,
$data){
1588 $pos = $this->depth_array[$this->depth - 1];
1589 $this->message[$pos][
'cdata'] .=
$data;
1597 function serializeSchema(){
1602 if (
sizeof($this->imports) > 0) {
1603 foreach($this->imports as $ns =>
$list) {
1605 if ($ii[
'location'] !=
'') {
1606 $xml .=
" <$schemaPrefix:import location=\"" . $ii[
'location'] .
'" namespace="' . $ns .
"\" />\n";
1608 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
1614 foreach($this->complexTypes as $typeName => $attrs){
1617 if(isset($attrs[
'elements']) && (count($attrs[
'elements']) > 0)){
1618 foreach($attrs[
'elements'] as $element => $eParts){
1619 if(isset($eParts[
'ref'])){
1620 $contentStr .=
" <$schemaPrefix:element ref=\"$element\"/>\n";
1622 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
1623 foreach ($eParts as $aName => $aValue) {
1625 if ($aName !=
'name' && $aName !=
'type') {
1626 $contentStr .=
" $aName=\"$aValue\"";
1629 $contentStr .=
"/>\n";
1633 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
1634 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n".$contentStr.
" </$schemaPrefix:$attrs[compositor]>\n";
1638 if(isset($attrs[
'attrs']) && (count($attrs[
'attrs']) >= 1)){
1639 foreach($attrs[
'attrs'] as $attr => $aParts){
1640 $contentStr .=
" <$schemaPrefix:attribute";
1641 foreach ($aParts as $a => $v) {
1642 if ($a ==
'ref' || $a ==
'type') {
1643 $contentStr .=
" $a=\"".$this->contractQName($v).
'"';
1644 } elseif ($a ==
'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1645 $this->usedNamespaces[
'wsdl'] = $this->namespaces[
'wsdl'];
1646 $contentStr .=
' wsdl:arrayType="'.$this->contractQName($v).
'"';
1648 $contentStr .=
" $a=\"$v\"";
1651 $contentStr .=
"/>\n";
1655 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
''){
1656 $contentStr =
" <$schemaPrefix:restriction base=\"".$this->contractQName($attrs[
'restrictionBase']).
"\">\n".$contentStr.
" </$schemaPrefix:restriction>\n";
1658 if ((isset($attrs[
'elements']) && count($attrs[
'elements']) > 0) || (isset($attrs[
'attrs']) && count($attrs[
'attrs']) > 0)){
1659 $contentStr =
" <$schemaPrefix:complexContent>\n".$contentStr.
" </$schemaPrefix:complexContent>\n";
1663 if($contentStr !=
''){
1664 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr.
" </$schemaPrefix:complexType>\n";
1666 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1668 $xml .= $contentStr;
1671 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
1672 foreach($this->simpleTypes as $typeName => $eParts){
1673 $xml .=
" <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts[
'type']).
"\">\n";
1674 if (isset($eParts[
'enumeration'])) {
1675 foreach ($eParts[
'enumeration'] as $e) {
1676 $xml .=
" <$schemaPrefix:enumeration value=\"$e\"/>\n";
1679 $xml .=
" </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1683 if(isset($this->elements) && count($this->elements) > 0){
1684 foreach($this->elements as $element => $eParts){
1685 $xml .=
" <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts[
'type']).
"\"/>\n";
1689 if(isset($this->attributes) && count($this->attributes) > 0){
1690 foreach($this->attributes as $attr => $aParts){
1691 $xml .=
" <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts[
'type']).
"\"\n/>";
1696 foreach ($this->schemaInfo as $k => $v) {
1697 if ($k ==
'elementFormDefault' || $k ==
'attributeFormDefault') {
1698 $attr .=
" $k=\"$v\"";
1701 $el =
"<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1702 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1703 $el .=
" xmlns:$nsp=\"$ns\"";
1705 $xml = $el .
">\n".$xml.
"</$schemaPrefix:schema>\n";
1715 function xdebug($string){
1716 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> '.$string);
1731 function getPHPType(
$type,$ns){
1732 if(isset($this->typemap[$ns][
$type])){
1734 return $this->typemap[$ns][
$type];
1735 } elseif(isset($this->complexTypes[$type])){
1737 return $this->complexTypes[
$type][
'phpType'];
1764 function getTypeDef($type){
1766 if (substr($type, -1) ==
'^') {
1768 $type = substr($type, 0, -1);
1773 if((! $is_element) && isset($this->complexTypes[$type])){
1774 $this->xdebug(
"in getTypeDef, found complexType $type");
1775 return $this->complexTypes[
$type];
1776 } elseif((! $is_element) && isset($this->simpleTypes[$type])){
1777 $this->xdebug(
"in getTypeDef, found simpleType $type");
1778 if (!isset($this->simpleTypes[$type][
'phpType'])) {
1781 $uqType = substr($this->simpleTypes[$type][
'type'], strrpos($this->simpleTypes[$type][
'type'],
':') + 1);
1782 $ns = substr($this->simpleTypes[$type][
'type'], 0, strrpos($this->simpleTypes[$type][
'type'],
':'));
1783 $etype = $this->getTypeDef($uqType);
1785 $this->xdebug(
"in getTypeDef, found type for simpleType $type:");
1786 $this->xdebug($this->
varDump($etype));
1787 if (isset($etype[
'phpType'])) {
1788 $this->simpleTypes[
$type][
'phpType'] = $etype[
'phpType'];
1790 if (isset($etype[
'elements'])) {
1791 $this->simpleTypes[
$type][
'elements'] = $etype[
'elements'];
1795 return $this->simpleTypes[
$type];
1796 } elseif(isset($this->elements[$type])){
1797 $this->xdebug(
"in getTypeDef, found element $type");
1798 if (!isset($this->elements[$type][
'phpType'])) {
1800 $uqType = substr($this->elements[$type][
'type'], strrpos($this->elements[$type][
'type'],
':') + 1);
1801 $ns = substr($this->elements[$type][
'type'], 0, strrpos($this->elements[$type][
'type'],
':'));
1802 $etype = $this->getTypeDef($uqType);
1804 $this->xdebug(
"in getTypeDef, found type for element $type:");
1805 $this->xdebug($this->
varDump($etype));
1806 if (isset($etype[
'phpType'])) {
1807 $this->elements[
$type][
'phpType'] = $etype[
'phpType'];
1809 if (isset($etype[
'elements'])) {
1810 $this->elements[
$type][
'elements'] = $etype[
'elements'];
1812 } elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
1813 $this->xdebug(
"in getTypeDef, element $type is an XSD type");
1814 $this->elements[
$type][
'phpType'] =
'scalar';
1817 return $this->elements[
$type];
1818 } elseif(isset($this->attributes[$type])){
1819 $this->xdebug(
"in getTypeDef, found attribute $type");
1820 return $this->attributes[
$type];
1821 } elseif (preg_match(
'/_ContainedType$/', $type)) {
1822 $this->xdebug(
"in getTypeDef, have an untyped element $type");
1823 $typeDef[
'typeClass'] =
'simpleType';
1824 $typeDef[
'phpType'] =
'scalar';
1825 $typeDef[
'type'] =
'http://www.w3.org/2001/XMLSchema:string';
1828 $this->xdebug(
"in getTypeDef, did not find $type");
1840 function serializeTypeDef($type){
1842 if($typeDef = $this->getTypeDef($type)){
1844 if(is_array($typeDef[
'attrs'])){
1845 foreach($typeDef[
'attrs'] as $attName =>
$data){
1846 $str .=
" $attName=\"{type = ".$data[
'type'].
"}\"";
1849 $str .=
" xmlns=\"".$this->schema[
'targetNamespace'].
"\"";
1850 if(count($typeDef[
'elements']) > 0){
1852 foreach($typeDef[
'elements'] as $element => $eData){
1853 $str .= $this->serializeTypeDef($element);
1856 } elseif($typeDef[
'typeClass'] ==
'element') {
1857 $str .=
"></$type>";
1876 function typeToForm(
$name,$type){
1878 if($typeDef = $this->getTypeDef($type)){
1880 if($typeDef[
'phpType'] ==
'struct'){
1881 $buffer .=
'<table>';
1882 foreach($typeDef[
'elements'] as $child => $childDef){
1884 <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef[
'type']).
"):</td> 1885 <td><input type='text' name='parameters[".
$name.
"][$childDef[name]]'></td></tr>";
1887 $buffer .=
'</table>';
1889 } elseif($typeDef[
'phpType'] ==
'array'){
1890 $buffer .=
'<table>';
1893 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1894 <td><input type='text' name='parameters[".$name.
"][]'></td></tr>";
1896 $buffer .=
'</table>';
1899 $buffer .=
"<input type='text' name='parameters[$name]'>";
1902 $buffer .=
"<input type='text' name='parameters[$name]'>";
1948 function addComplexType(
$name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',$elements=array(),$attrs=array(),$arrayType=
''){
1949 $this->complexTypes[
$name] = array(
1951 'typeClass' => $typeClass,
1952 'phpType' => $phpType,
1953 'compositor'=> $compositor,
1954 'restrictionBase' => $restrictionBase,
1955 'elements' => $elements,
1957 'arrayType' => $arrayType
1960 $this->xdebug(
"addComplexType $name:");
1976 function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array()) {
1977 $this->simpleTypes[
$name] = array(
1979 'typeClass' => $typeClass,
1980 'phpType' => $phpType,
1981 'type' => $restrictionBase,
1982 'enumeration' => $enumeration
1985 $this->xdebug(
"addSimpleType $name:");
1996 function addElement($attrs) {
1997 if (! $this->
getPrefix($attrs[
'type'])) {
1998 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
2000 $this->elements[ $attrs[
'name'] ] = $attrs;
2001 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
2003 $this->xdebug(
"addElement " . $attrs[
'name']);
2084 function __construct($name=
'soapval',$type=
false,$value=-1,$element_ns=
false,$type_ns=
false,$attributes=
false) {
2085 parent::__construct();
2086 $this->name =
$name;
2087 $this->type =
$type;
2088 $this->value = $value;
2089 $this->element_ns = $element_ns;
2090 $this->type_ns = $type_ns;
2102 return $this->
serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use,
true);
2112 return $this->value;
2135 var $digest_uri =
'';
2140 var $request_method =
'POST';
2141 var $protocol_version =
'1.0';
2143 var $outgoing_headers = array();
2144 var $incoming_headers = array();
2145 var $incoming_cookies = array();
2146 var $outgoing_payload =
'';
2147 var $incoming_payload =
'';
2148 var $response_status_line;
2149 var $useSOAPAction =
true;
2150 var $persistentConnection =
false;
2152 var $ch_options = array();
2153 var $use_curl =
false;
2158 var $digestRequest = array();
2159 var $certRequest = array();
2176 function __construct($url, $curl_options = NULL, $use_curl =
false){
2177 parent::__construct();
2178 $this->
debug(
"ctor url=$url use_curl=$use_curl curl_options:");
2180 $this->setURL($url);
2181 if (is_array($curl_options)) {
2182 $this->ch_options = $curl_options;
2184 $this->use_curl = $use_curl;
2185 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
2186 $this->
setHeader(
'User-Agent', $this->title.
'/'.$this->version.
' ('.$rev[1].
')');
2196 function setCurlOption($option, $value) {
2197 $this->
debug(
"setCurlOption option=$option, value=");
2199 curl_setopt($this->ch, $option, $value);
2210 $this->outgoing_headers[
$name] = $value;
2211 $this->
debug(
"set header $name: $value");
2220 function unsetHeader(
$name) {
2221 if (isset($this->outgoing_headers[
$name])) {
2222 $this->
debug(
"unset header $name");
2223 unset($this->outgoing_headers[$name]);
2233 function setURL($url) {
2236 $u = parse_url($url);
2237 foreach($u as $k => $v){
2238 $this->
debug(
"parsed URL $k = $v");
2243 if(isset($u[
'query']) && $u[
'query'] !=
''){
2244 $this->path .=
'?' . $u[
'query'];
2248 if(!isset($u[
'port'])){
2249 if($u[
'scheme'] ==
'https'){
2257 $this->digest_uri = $this->uri;
2260 if (!isset($u[
'port'])) {
2263 $this->
setHeader(
'Host', $this->host.
':'.$this->port);
2266 if (isset($u[
'user']) && $u[
'user'] !=
'') {
2267 $this->setCredentials(urldecode($u[
'user']), isset($u[
'pass']) ? urldecode($u[
'pass']) :
'');
2277 function io_method() {
2278 if ($this->use_curl || ($this->scheme ==
'https') || ($this->scheme ==
'http' && $this->authtype ==
'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy[
'authtype'] ==
'ntlm'))
2280 if (($this->scheme ==
'http' || $this->scheme ==
'ssl') && $this->authtype !=
'ntlm' && (!is_array($this->proxy) || $this->proxy[
'authtype'] !=
'ntlm'))
2293 function connect($connection_timeout=0,$response_timeout=30){
2306 $this->
debug(
"connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2307 if ($this->io_method() ==
'socket') {
2308 if (!is_array($this->proxy)) {
2309 $host = $this->host;
2310 $port = $this->port;
2312 $host = $this->proxy[
'host'];
2313 $port = $this->proxy[
'port'];
2317 if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
2318 if (!feof($this->fp)) {
2319 $this->
debug(
'Re-use persistent connection');
2323 $this->
debug(
'Closed persistent connection at EOF');
2327 if ($this->scheme ==
'ssl') {
2328 $host =
'ssl://' . $host;
2330 $this->
debug(
'calling fsockopen with host ' . $host .
' connection_timeout ' . $connection_timeout);
2333 if($connection_timeout > 0){
2334 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2336 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
2341 $msg =
'Couldn\'t open socket connection to server ' .
$this->url;
2345 $msg .=
' prior to connect(). This is often a problem looking up the host name.';
2353 $this->
debug(
'set response timeout to ' . $response_timeout);
2354 socket_set_timeout( $this->fp, $response_timeout);
2356 $this->
debug(
'socket connected');
2358 }
else if ($this->io_method() ==
'curl') {
2359 if (!extension_loaded(
'curl')) {
2361 $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.');
2365 if (defined(
'CURLOPT_CONNECTIONTIMEOUT'))
2366 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2368 $CURLOPT_CONNECTIONTIMEOUT = 78;
2369 if (defined(
'CURLOPT_HTTPAUTH'))
2370 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2372 $CURLOPT_HTTPAUTH = 107;
2373 if (defined(
'CURLOPT_PROXYAUTH'))
2374 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2376 $CURLOPT_PROXYAUTH = 111;
2377 if (defined(
'CURLAUTH_BASIC'))
2378 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2380 $CURLAUTH_BASIC = 1;
2381 if (defined(
'CURLAUTH_DIGEST'))
2382 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2384 $CURLAUTH_DIGEST = 2;
2385 if (defined(
'CURLAUTH_NTLM'))
2386 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2390 $this->
debug(
'connect using cURL');
2392 $this->ch = curl_init();
2394 $hostURL = ($this->port !=
'') ?
"$this->scheme://$this->host:$this->port" :
"$this->scheme://$this->host";
2397 $this->setCurlOption(CURLOPT_URL, $hostURL);
2399 if (ini_get(
'safe_mode') || ini_get(
'open_basedir')) {
2400 $this->
debug(
'safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2401 $this->
debug(
'safe_mode = ');
2403 $this->
debug(
'open_basedir = ');
2406 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2409 $this->setCurlOption(CURLOPT_HEADER, 1);
2411 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2418 if ($this->persistentConnection) {
2424 $this->persistentConnection =
false;
2425 $this->
setHeader(
'Connection',
'close');
2428 if ($connection_timeout != 0) {
2429 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2431 if ($response_timeout != 0) {
2432 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2435 if ($this->scheme ==
'https') {
2436 $this->
debug(
'set cURL SSL verify options');
2441 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2442 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2445 if ($this->authtype ==
'certificate') {
2446 $this->
debug(
'set cURL certificate options');
2447 if (isset($this->certRequest[
'cainfofile'])) {
2448 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest[
'cainfofile']);
2450 if (isset($this->certRequest[
'verifypeer'])) {
2451 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest[
'verifypeer']);
2453 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2455 if (isset($this->certRequest[
'verifyhost'])) {
2456 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest[
'verifyhost']);
2458 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2460 if (isset($this->certRequest[
'sslcertfile'])) {
2461 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest[
'sslcertfile']);
2463 if (isset($this->certRequest[
'sslkeyfile'])) {
2464 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest[
'sslkeyfile']);
2466 if (isset($this->certRequest[
'passphrase'])) {
2467 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest[
'passphrase']);
2469 if (isset($this->certRequest[
'certpassword'])) {
2470 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest[
'certpassword']);
2474 if ($this->authtype && ($this->authtype !=
'certificate')) {
2475 if ($this->username) {
2476 $this->
debug(
'set cURL username/password');
2477 $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
2479 if ($this->authtype ==
'basic') {
2480 $this->
debug(
'set cURL for Basic authentication');
2481 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2483 if ($this->authtype ==
'digest') {
2484 $this->
debug(
'set cURL for digest authentication');
2485 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2487 if ($this->authtype ==
'ntlm') {
2488 $this->
debug(
'set cURL for NTLM authentication');
2489 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2492 if (is_array($this->proxy)) {
2493 $this->
debug(
'set cURL proxy options');
2494 if ($this->proxy[
'port'] !=
'') {
2495 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host'].
':'.$this->proxy[
'port']);
2497 $this->setCurlOption(CURLOPT_PROXY, $this->proxy[
'host']);
2499 if ($this->proxy[
'username'] || $this->proxy[
'password']) {
2500 $this->
debug(
'set cURL proxy authentication options');
2501 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy[
'username'].
':'.$this->proxy[
'password']);
2502 if ($this->proxy[
'authtype'] ==
'basic') {
2503 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2505 if ($this->proxy[
'authtype'] ==
'ntlm') {
2506 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2510 $this->
debug(
'cURL connection set up');
2513 $this->
setError(
'Unknown scheme ' . $this->scheme);
2514 $this->
debug(
'Unknown scheme ' . $this->scheme);
2529 function send(
$data, $timeout=0, $response_timeout=30, $cookies=NULL) {
2531 $this->
debug(
'entered send() with data of length: '.strlen(
$data));
2533 $this->tryagain =
true;
2535 while ($this->tryagain) {
2536 $this->tryagain =
false;
2539 if (!$this->connect($timeout, $response_timeout)){
2544 if (!$this->sendRequest(
$data, $cookies)){
2549 $respdata = $this->getResponse();
2551 $this->
setError(
"Too many tries to get an OK response ($this->response_status_line)");
2554 $this->
debug(
'end of send()');
2570 function sendHTTPS(
$data, $timeout=0, $response_timeout=30, $cookies) {
2571 return $this->send(
$data, $timeout, $response_timeout, $cookies);
2584 function setCredentials($username, $password, $authtype =
'basic', $digestRequest = array(), $certRequest = array()) {
2585 $this->
debug(
"setCredentials username=$username authtype=$authtype digestRequest=");
2587 $this->
debug(
"certRequest=");
2590 if ($authtype ==
'basic') {
2591 $this->
setHeader(
'Authorization',
'Basic '.base64_encode(str_replace(
':',
'',$username).
':'.$password));
2592 } elseif ($authtype ==
'digest') {
2593 if (isset($digestRequest[
'nonce'])) {
2594 $digestRequest[
'nc'] = isset($digestRequest[
'nc']) ? $digestRequest[
'nc']++ : 1;
2599 $A1 = $username.
':' . (isset($digestRequest[
'realm']) ? $digestRequest[
'realm'] :
'') .
':' . $password;
2605 $A2 = $this->request_method .
':' . $this->digest_uri;
2621 $unhashedDigest =
'';
2622 $nonce = isset($digestRequest[
'nonce']) ? $digestRequest[
'nonce'] :
'';
2624 if ($digestRequest[
'qop'] !=
'') {
2625 $unhashedDigest = $HA1 .
':' . $nonce .
':' . sprintf(
"%08d", $digestRequest[
'nc']) .
':' . $cnonce .
':' . $digestRequest[
'qop'] .
':' . $HA2;
2627 $unhashedDigest = $HA1 .
':' . $nonce .
':' . $HA2;
2630 $hashedDigest = md5($unhashedDigest);
2633 if (isset($digestRequest[
'opaque'])) {
2634 $opaque =
', opaque="' . $digestRequest[
'opaque'] .
'"';
2637 $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 .
'"');
2639 } elseif ($authtype ==
'certificate') {
2640 $this->certRequest = $certRequest;
2641 $this->
debug(
'Authorization header not set for certificate');
2642 } elseif ($authtype ==
'ntlm') {
2644 $this->
debug(
'Authorization header not set for ntlm');
2646 $this->username = $username;
2648 $this->authtype = $authtype;
2649 $this->digestRequest = $digestRequest;
2658 function setSOAPAction($soapaction) {
2659 $this->
setHeader(
'SOAPAction',
'"' . $soapaction .
'"');
2668 function setEncoding($enc=
'gzip, deflate') {
2669 if (function_exists(
'gzdeflate')) {
2670 $this->protocol_version =
'1.1';
2671 $this->
setHeader(
'Accept-Encoding', $enc);
2672 if (!isset($this->outgoing_headers[
'Connection'])) {
2673 $this->
setHeader(
'Connection',
'close');
2674 $this->persistentConnection =
false;
2676 #set_magic_quotes_runtime(0); 2678 $this->encoding = $enc;
2692 function setProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'', $proxyauthtype =
'basic') {
2694 $this->proxy = array(
2695 'host' => $proxyhost,
2696 'port' => $proxyport,
2697 'username' => $proxyusername,
2698 'password' => $proxypassword,
2699 'authtype' => $proxyauthtype
2701 if ($proxyusername !=
'' && $proxypassword !=
'' && $proxyauthtype =
'basic') {
2702 $this->
setHeader(
'Proxy-Authorization',
' Basic '.base64_encode($proxyusername.
':'.$proxypassword));
2705 $this->
debug(
'remove proxy');
2707 unsetHeader(
'Proxy-Authorization');
2720 function isSkippableCurlHeader(&
$data) {
2721 $skipHeaders = array(
'HTTP/1.1 100',
2728 'HTTP/1.0 200 Connection established');
2729 foreach ($skipHeaders as $hd) {
2730 $prefix = substr(
$data, 0, strlen($hd));
2731 if ($prefix == $hd)
return true;
2747 function decodeChunked($buffer, $lb){
2754 $chunkend = strpos($buffer, $lb);
2755 if ($chunkend == FALSE) {
2756 $this->
debug(
'no linebreak found in decodeChunked');
2759 $temp = substr($buffer,0,$chunkend);
2760 $chunk_size = hexdec( trim($temp) );
2761 $chunkstart = $chunkend + strlen($lb);
2763 while ($chunk_size > 0) {
2764 $this->
debug(
"chunkstart: $chunkstart chunk_size: $chunk_size");
2765 $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
2768 if ($chunkend == FALSE) {
2769 $chunk = substr($buffer,$chunkstart);
2772 $length += strlen($chunk);
2777 $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2781 $length += strlen($chunk);
2783 $chunkstart = $chunkend + strlen($lb);
2785 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2786 if ($chunkend == FALSE) {
2789 $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2790 $chunk_size = hexdec( trim($temp) );
2791 $chunkstart = $chunkend;
2804 function buildPayload(
$data, $cookie_str =
'') {
2818 $req =
"$this->request_method $uri HTTP/$this->protocol_version";
2819 $this->
debug(
"HTTP request: $req");
2820 $this->outgoing_payload =
"$req\r\n";
2823 foreach($this->outgoing_headers as $k => $v){
2825 $this->
debug(
"HTTP header: $hdr");
2826 $this->outgoing_payload .=
"$hdr\r\n";
2830 if ($cookie_str !=
'') {
2831 $hdr =
'Cookie: '.$cookie_str;
2832 $this->
debug(
"HTTP header: $hdr");
2833 $this->outgoing_payload .=
"$hdr\r\n";
2837 $this->outgoing_payload .=
"\r\n";
2840 $this->outgoing_payload .=
$data;
2851 function sendRequest(
$data, $cookies = NULL) {
2853 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme ==
'ssl') || ($this->scheme ==
'https')));
2856 $this->buildPayload(
$data, $cookie_str);
2858 if ($this->io_method() ==
'socket') {
2860 if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2861 $this->
setError(
'couldn\'t write message data to socket');
2862 $this->
debug(
'couldn\'t write message data to socket');
2865 $this->
debug(
'wrote data to socket, length = ' . strlen($this->outgoing_payload));
2867 }
else if ($this->io_method() ==
'curl') {
2873 $curl_headers = array();
2874 foreach($this->outgoing_headers as $k => $v){
2875 if ($k ==
'Connection' || $k ==
'Content-Length' || $k ==
'Host' || $k ==
'Authorization' || $k ==
'Proxy-Authorization') {
2876 $this->
debug(
"Skip cURL header $k: $v");
2878 $curl_headers[] =
"$k: $v";
2881 if ($cookie_str !=
'') {
2882 $curl_headers[] =
'Cookie: ' . $cookie_str;
2884 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2885 $this->
debug(
'set cURL HTTP headers');
2886 if ($this->request_method ==
"POST") {
2887 $this->setCurlOption(CURLOPT_POST, 1);
2888 $this->setCurlOption(CURLOPT_POSTFIELDS,
$data);
2889 $this->
debug(
'set cURL POST data');
2893 foreach ($this->ch_options as
$key => $val) {
2894 $this->setCurlOption(
$key, $val);
2897 $this->
debug(
'set cURL payload');
2908 function getResponse(){
2909 $this->incoming_payload =
'';
2911 if ($this->io_method() ==
'socket') {
2914 while (!isset($lb)){
2917 if(feof($this->fp)) {
2918 $this->incoming_payload =
$data;
2919 $this->
debug(
'found no headers before EOF after length ' . strlen(
$data));
2920 $this->
debug(
"received before EOF:\n" .
$data);
2921 $this->
setError(
'server failed to send headers');
2925 $tmp = fgets($this->fp, 256);
2926 $tmplen = strlen($tmp);
2927 $this->
debug(
"read line of $tmplen bytes: " . trim($tmp));
2930 $this->incoming_payload =
$data;
2931 $this->
debug(
'socket read of headers timed out after length ' . strlen(
$data));
2932 $this->
debug(
"read before timeout: " .
$data);
2933 $this->
setError(
'socket read of headers timed out');
2938 $pos = strpos(
$data,
"\r\n\r\n");
2942 $pos = strpos(
$data,
"\n\n");
2948 if (isset($lb) && preg_match(
'/^HTTP\/1.1 100/',
$data)) {
2954 $this->incoming_payload .=
$data;
2955 $this->
debug(
'found end of headers after length ' . strlen(
$data));
2957 $header_data = trim(substr(
$data,0,$pos));
2958 $header_array = explode($lb,$header_data);
2959 $this->incoming_headers = array();
2960 $this->incoming_cookies = array();
2961 foreach($header_array as $header_line){
2962 $arr = explode(
':',$header_line, 2);
2963 if(count($arr) > 1){
2964 $header_name = strtolower(trim($arr[0]));
2965 $this->incoming_headers[$header_name] = trim($arr[1]);
2966 if ($header_name ==
'set-cookie') {
2968 $cookie = $this->parseCookie(trim($arr[1]));
2970 $this->incoming_cookies[] = $cookie;
2971 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
2973 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
2976 }
else if (isset($header_name)) {
2978 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
2983 if (isset($this->incoming_headers[
'transfer-encoding']) && strtolower($this->incoming_headers[
'transfer-encoding']) ==
'chunked') {
2984 $content_length = 2147483647;
2986 $this->
debug(
"want to read chunked content");
2987 } elseif (isset($this->incoming_headers[
'content-length'])) {
2988 $content_length = $this->incoming_headers[
'content-length'];
2990 $this->
debug(
"want to read content of length $content_length");
2992 $content_length = 2147483647;
2994 $this->
debug(
"want to read content to EOF");
2999 $tmp = fgets($this->fp, 256);
3000 $tmplen = strlen($tmp);
3001 $this->
debug(
"read chunk line of $tmplen bytes");
3003 $this->incoming_payload =
$data;
3004 $this->
debug(
'socket read of chunk length timed out after length ' . strlen(
$data));
3005 $this->
debug(
"read before timeout:\n" .
$data);
3006 $this->
setError(
'socket read of chunk length timed out');
3009 $content_length = hexdec(trim($tmp));
3010 $this->
debug(
"chunk length $content_length");
3013 while (($strlen < $content_length) && (!feof($this->fp))) {
3014 $readlen = min(8192, $content_length - $strlen);
3015 $tmp = fread($this->fp, $readlen);
3016 $tmplen = strlen($tmp);
3017 $this->
debug(
"read buffer of $tmplen bytes");
3018 if (($tmplen == 0) && (!feof($this->fp))) {
3019 $this->incoming_payload =
$data;
3020 $this->
debug(
'socket read of body timed out after length ' . strlen(
$data));
3021 $this->
debug(
"read before timeout:\n" .
$data);
3022 $this->
setError(
'socket read of body timed out');
3028 if ($chunked && ($content_length > 0)) {
3029 $tmp = fgets($this->fp, 256);
3030 $tmplen = strlen($tmp);
3031 $this->
debug(
"read chunk terminator of $tmplen bytes");
3033 $this->incoming_payload =
$data;
3034 $this->
debug(
'socket read of chunk terminator timed out after length ' . strlen(
$data));
3035 $this->
debug(
"read before timeout:\n" .
$data);
3036 $this->
setError(
'socket read of chunk terminator timed out');
3040 }
while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3041 if (feof($this->fp)) {
3042 $this->
debug(
'read to EOF');
3044 $this->
debug(
'read body of length ' . strlen(
$data));
3045 $this->incoming_payload .=
$data;
3046 $this->
debug(
'received a total of '.strlen($this->incoming_payload).
' bytes of data from server');
3050 (isset($this->incoming_headers[
'connection']) && strtolower($this->incoming_headers[
'connection']) ==
'close') ||
3051 (! $this->persistentConnection) || feof($this->fp)){
3054 $this->
debug(
'closed socket');
3058 if($this->incoming_payload ==
''){
3059 $this->
setError(
'no response from server');
3074 }
else if ($this->io_method() ==
'curl') {
3076 $this->
debug(
'send and receive with cURL');
3077 $this->incoming_payload = curl_exec($this->ch);
3078 $data = $this->incoming_payload;
3080 $cErr = curl_error($this->ch);
3082 $err =
'cURL ERROR: '.curl_errno($this->ch).
': '.$cErr.
'<br>';
3084 foreach(curl_getinfo($this->ch) as $k => $v){
3085 $err .=
"$k: $v<br>";
3089 curl_close($this->ch);
3097 $this->
debug(
'No cURL error, closing cURL');
3098 curl_close($this->ch);
3102 while ($this->isSkippableCurlHeader(
$data)) {
3103 $this->
debug(
"Found HTTP header to skip");
3104 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3106 } elseif($pos = strpos(
$data,
"\n\n") ) {
3114 while (preg_match(
'/^HTTP\/1.1 100/',
$data)) {
3115 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3117 } elseif($pos = strpos(
$data,
"\n\n") ) {
3124 if ($pos = strpos(
$data,
"\r\n\r\n")) {
3126 } elseif( $pos = strpos(
$data,
"\n\n")) {
3129 $this->
debug(
'no proper separation of headers and document');
3130 $this->
setError(
'no proper separation of headers and document');
3133 $header_data = trim(substr(
$data,0,$pos));
3134 $header_array = explode($lb,$header_data);
3136 $this->
debug(
'found proper separation of headers and document');
3137 $this->
debug(
'cleaned data, stringlen: '.strlen(
$data));
3139 foreach ($header_array as $header_line) {
3140 $arr = explode(
':',$header_line,2);
3141 if(count($arr) > 1){
3142 $header_name = strtolower(trim($arr[0]));
3143 $this->incoming_headers[$header_name] = trim($arr[1]);
3144 if ($header_name ==
'set-cookie') {
3146 $cookie = $this->parseCookie(trim($arr[1]));
3148 $this->incoming_cookies[] = $cookie;
3149 $this->
debug(
'found cookie: ' . $cookie[
'name'] .
' = ' . $cookie[
'value']);
3151 $this->
debug(
'did not find cookie in ' . trim($arr[1]));
3154 }
else if (isset($header_name)) {
3156 $this->incoming_headers[$header_name] .= $lb .
' ' . $header_line;
3161 $this->response_status_line = $header_array[0];
3162 $arr = explode(
' ', $this->response_status_line, 3);
3163 $http_version = $arr[0];
3164 $http_status = intval($arr[1]);
3165 $http_reason = count($arr) > 2 ? $arr[2] :
'';
3168 if (isset($this->incoming_headers[
'location']) && ($http_status == 301 || $http_status == 302)) {
3169 $this->
debug(
"Got $http_status $http_reason with Location: " . $this->incoming_headers[
'location']);
3170 $this->setURL($this->incoming_headers[
'location']);
3171 $this->tryagain =
true;
3176 if (isset($this->incoming_headers[
'www-authenticate']) && $http_status == 401) {
3177 $this->
debug(
"Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers[
'www-authenticate']);
3178 if (strstr($this->incoming_headers[
'www-authenticate'],
"Digest ")) {
3179 $this->
debug(
'Server wants digest authentication');
3181 $digestString = str_replace(
'Digest ',
'', $this->incoming_headers[
'www-authenticate']);
3184 $digestElements = explode(
',', $digestString);
3185 foreach ($digestElements as $val) {
3186 $tempElement = explode(
'=', trim($val), 2);
3187 $digestRequest[$tempElement[0]] = str_replace(
"\"",
'', $tempElement[1]);
3191 if (isset($digestRequest[
'nonce'])) {
3192 $this->setCredentials($this->username, $this->password,
'digest', $digestRequest);
3193 $this->tryagain =
true;
3197 $this->
debug(
'HTTP authentication failed');
3198 $this->
setError(
'HTTP authentication failed');
3203 ($http_status >= 300 && $http_status <= 307) ||
3204 ($http_status >= 400 && $http_status <= 417) ||
3205 ($http_status >= 501 && $http_status <= 505)
3207 $this->
setError(
"Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3212 if(isset($this->incoming_headers[
'content-encoding']) && $this->incoming_headers[
'content-encoding'] !=
''){
3213 if(strtolower($this->incoming_headers[
'content-encoding']) ==
'deflate' || strtolower($this->incoming_headers[
'content-encoding']) ==
'gzip'){
3215 if(function_exists(
'gzinflate')){
3219 $this->
debug(
'The gzinflate function exists');
3220 $datalen = strlen(
$data);
3221 if ($this->incoming_headers[
'content-encoding'] ==
'deflate') {
3222 if ($degzdata = @gzinflate(
$data)) {
3224 $this->
debug(
'The payload has been inflated to ' . strlen(
$data) .
' bytes');
3225 if (strlen(
$data) < $datalen) {
3227 $this->
debug(
'The inflated payload is smaller than the gzipped one; try again');
3228 if ($degzdata = @gzinflate(
$data)) {
3230 $this->
debug(
'The payload has been inflated again to ' . strlen(
$data) .
' bytes');
3234 $this->
debug(
'Error using gzinflate to inflate the payload');
3235 $this->
setError(
'Error using gzinflate to inflate the payload');
3237 } elseif ($this->incoming_headers[
'content-encoding'] ==
'gzip') {
3238 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3240 $this->
debug(
'The payload has been un-gzipped to ' . strlen(
$data) .
' bytes');
3241 if (strlen(
$data) < $datalen) {
3243 $this->
debug(
'The un-gzipped payload is smaller than the gzipped one; try again');
3244 if ($degzdata = @gzinflate(substr(
$data, 10))) {
3246 $this->
debug(
'The payload has been un-gzipped again to ' . strlen(
$data) .
' bytes');
3250 $this->
debug(
'Error using gzinflate to un-gzip the payload');
3251 $this->
setError(
'Error using gzinflate to un-gzip the payload');
3257 $this->incoming_payload = $header_data.$lb.$lb.$data;
3259 $this->
debug(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3260 $this->
setError(
'The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3263 $this->
debug(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3264 $this->
setError(
'Unsupported Content-Encoding ' . $this->incoming_headers[
'content-encoding']);
3267 $this->
debug(
'No Content-Encoding header');
3270 if(strlen(
$data) == 0){
3271 $this->
debug(
'no data after headers!');
3272 $this->
setError(
'no data present after HTTP headers');
3286 function setContentType($type, $charset =
false) {
3287 $this->
setHeader(
'Content-Type', $type . ($charset ?
'; charset=' . $charset :
''));
3296 function usePersistentConnection(){
3297 if (isset($this->outgoing_headers[
'Accept-Encoding'])) {
3300 $this->protocol_version =
'1.1';
3301 $this->persistentConnection =
true;
3302 $this->
setHeader(
'Connection',
'Keep-Alive');
3316 function parseCookie($cookie_str) {
3317 $cookie_str = str_replace(
'; ',
';', $cookie_str) .
';';
3319 $value_str =
$data[0];
3321 $cookie_param =
'domain=';
3322 $start = strpos($cookie_str, $cookie_param);
3324 $domain = substr($cookie_str,
$start + strlen($cookie_param));
3330 $cookie_param =
'expires=';
3331 $start = strpos($cookie_str, $cookie_param);
3333 $expires = substr($cookie_str,
$start + strlen($cookie_param));
3334 $expires = substr($expires, 0, strpos($expires,
';'));
3339 $cookie_param =
'path=';
3340 $start = strpos($cookie_str, $cookie_param);
3342 $path = substr($cookie_str,
$start + strlen($cookie_param));
3343 $path = substr($path, 0, strpos($path,
';'));
3348 $cookie_param =
';secure;';
3349 if (strpos($cookie_str, $cookie_param) !== FALSE) {
3355 $sep_pos = strpos($value_str,
'=');
3358 $name = substr($value_str, 0, $sep_pos);
3359 $value = substr($value_str, $sep_pos + 1);
3360 $cookie= array(
'name' =>
$name,
3364 'expires' => $expires,
3380 function getCookiesForRequest($cookies, $secure=
false) {
3382 if ((! is_null($cookies)) && (is_array($cookies))) {
3383 foreach ($cookies as $cookie) {
3384 if (! is_array($cookie)) {
3387 $this->
debug(
"check cookie for validity: ".$cookie[
'name'].
'='.$cookie[
'value']);
3388 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
3389 if (strtotime($cookie[
'expires']) <= time()) {
3390 $this->
debug(
'cookie has expired');
3394 if ((isset($cookie[
'domain'])) && (! empty($cookie[
'domain']))) {
3395 $domain = preg_quote($cookie[
'domain']);
3396 if (! preg_match(
"'.*$domain$'i", $this->host)) {
3397 $this->
debug(
'cookie has different domain');
3401 if ((isset($cookie[
'path'])) && (! empty($cookie[
'path']))) {
3402 $path = preg_quote($cookie[
'path']);
3403 if (! preg_match(
"'^$path.*'i", $this->path)) {
3404 $this->
debug(
'cookie is for a different path');
3408 if ((! $secure) && (isset($cookie[
'secure'])) && ($cookie[
'secure'])) {
3409 $this->
debug(
'cookie is secure, transport is not');
3412 $cookie_str .= $cookie[
'name'] .
'=' . $cookie[
'value'] .
'; ';
3413 $this->
debug(
'add cookie to Cookie-String: ' . $cookie[
'name'] .
'=' . $cookie[
'value']);
3440 var $headers = array();
3452 var $requestHeaders =
'';
3458 var $requestHeader = NULL;
3470 var $requestSOAP =
'';
3476 var $methodURI =
'';
3482 var $methodname =
'';
3488 var $methodparams = array();
3494 var $SOAPAction =
'';
3500 var $xml_encoding =
'';
3506 var $decode_utf8 =
true;
3513 var $outgoing_headers = array();
3525 var $responseHeaders =
'';
3531 var $responseSOAP =
'';
3537 var $methodreturn =
false;
3543 var $methodreturnisliteralxml =
false;
3563 var $operations = array();
3575 var $externalWSDLURL =
false;
3581 var $debug_flag =
false;
3592 parent::__construct();
3595 global $HTTP_SERVER_VARS;
3598 $this->
debug(
"_SERVER is defined:");
3600 } elseif (isset($HTTP_SERVER_VARS)) {
3601 $this->
debug(
"HTTP_SERVER_VARS is defined:");
3604 $this->
debug(
"Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3607 if (isset($debug)) {
3608 $this->
debug(
"In nusoap_server, set debug_flag=$debug based on global flag");
3609 $this->debug_flag =
$debug;
3610 } elseif (isset(
$_SERVER[
'QUERY_STRING'])) {
3611 $qs = explode(
'&',
$_SERVER[
'QUERY_STRING']);
3612 foreach ($qs as $v) {
3613 if (substr($v, 0, 6) ==
'debug=') {
3614 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #1");
3615 $this->debug_flag = substr($v, 6);
3618 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3619 $qs = explode(
'&', $HTTP_SERVER_VARS[
'QUERY_STRING']);
3620 foreach ($qs as $v) {
3621 if (substr($v, 0, 6) ==
'debug=') {
3622 $this->
debug(
"In nusoap_server, set debug_flag=" . substr($v, 6) .
" based on query string #2");
3623 $this->debug_flag = substr($v, 6);
3630 $this->
debug(
"In nusoap_server, WSDL is specified");
3631 if (is_object($wsdl) && (get_class($wsdl) ==
'wsdl')) {
3632 $this->
wsdl = $wsdl;
3633 $this->externalWSDLURL = $this->
wsdl->
wsdl;
3634 $this->
debug(
'Use existing wsdl instance from ' . $this->externalWSDLURL);
3636 $this->
debug(
'Create wsdl from ' . $wsdl);
3638 $this->externalWSDLURL = $wsdl;
3643 die(
'WSDL ERROR: '.$err);
3654 function service(
$data){
3655 global $HTTP_SERVER_VARS;
3657 if (isset(
$_SERVER[
'QUERY_STRING'])) {
3659 } elseif (isset($HTTP_SERVER_VARS[
'QUERY_STRING'])) {
3660 $qs = $HTTP_SERVER_VARS[
'QUERY_STRING'];
3664 $this->
debug(
"In service, query string=$qs");
3666 if (preg_match(
'/wsdl/', $qs) ){
3667 $this->
debug(
"In service, this is a request for WSDL");
3668 if($this->externalWSDLURL){
3669 if (strpos($this->externalWSDLURL,
"://")!==
false) {
3670 header(
'Location: '.$this->externalWSDLURL);
3672 header(
"Content-Type: text/xml\r\n");
3673 $fp =
fopen($this->externalWSDLURL,
'r');
3676 } elseif ($this->
wsdl) {
3677 header(
"Content-Type: text/xml; charset=ISO-8859-1\r\n");
3679 if ($this->debug_flag) {
3680 $this->
debug(
'wsdl:');
3685 header(
"Content-Type: text/html; charset=ISO-8859-1\r\n");
3686 print
"This service does not provide WSDL";
3689 $this->
debug(
"In service, there is no data, so return Web description");
3692 $this->
debug(
"In service, invoke the request");
3694 if (! $this->fault) {
3695 $this->invoke_method();
3697 if (! $this->fault) {
3698 $this->serialize_return();
3700 $this->send_response();
3716 function parse_http_headers() {
3717 global $HTTP_SERVER_VARS;
3719 $this->request =
'';
3720 $this->SOAPAction =
'';
3721 if(function_exists(
'getallheaders')){
3722 $this->
debug(
"In parse_http_headers, use getallheaders");
3723 $headers = getallheaders();
3724 foreach($headers as $k=>$v){
3725 $k = strtolower($k);
3726 $this->headers[$k] = $v;
3727 $this->request .=
"$k: $v\r\n";
3728 $this->
debug(
"$k: $v");
3731 if(isset($this->headers[
'soapaction'])){
3732 $this->SOAPAction = str_replace(
'"',
'',$this->headers[
'soapaction']);
3735 if(isset($this->headers[
'content-type']) && strpos($this->headers[
'content-type'],
'=')){
3736 $enc = str_replace(
'"',
'',substr(strstr($this->headers[
"content-type"],
'='),1));
3737 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
3738 $this->xml_encoding = strtoupper($enc);
3740 $this->xml_encoding =
'US-ASCII';
3744 $this->xml_encoding =
'ISO-8859-1';
3747 $this->
debug(
"In parse_http_headers, use _SERVER");
3749 if (substr($k, 0, 5) ==
'HTTP_') {
3750 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5))));
3752 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k)));
3754 if ($k ==
'soapaction') {
3757 $v = str_replace(
'"',
'', $v);
3758 $v = str_replace(
'\\',
'', $v);
3759 $this->SOAPAction = $v;
3760 }
else if ($k ==
'content-type') {
3762 if (strpos($v,
'=')) {
3763 $enc = substr(strstr($v,
'='), 1);
3764 $enc = str_replace(
'"',
'', $enc);
3765 $enc = str_replace(
'\\',
'', $enc);
3766 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3767 $this->xml_encoding = strtoupper($enc);
3769 $this->xml_encoding =
'US-ASCII';
3773 $this->xml_encoding =
'ISO-8859-1';
3776 $this->headers[$k] = $v;
3777 $this->request .=
"$k: $v\r\n";
3778 $this->
debug(
"$k: $v");
3780 } elseif (is_array($HTTP_SERVER_VARS)) {
3781 $this->
debug(
"In parse_http_headers, use HTTP_SERVER_VARS");
3782 foreach ($HTTP_SERVER_VARS as $k => $v) {
3783 if (substr($k, 0, 5) ==
'HTTP_') {
3784 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
3786 $k = str_replace(
' ',
'-', strtolower(str_replace(
'_',
' ', $k))); $k = strtolower($k);
3788 if ($k ==
'soapaction') {
3791 $v = str_replace(
'"',
'', $v);
3792 $v = str_replace(
'\\',
'', $v);
3793 $this->SOAPAction = $v;
3794 }
else if ($k ==
'content-type') {
3796 if (strpos($v,
'=')) {
3797 $enc = substr(strstr($v,
'='), 1);
3798 $enc = str_replace(
'"',
'', $enc);
3799 $enc = str_replace(
'\\',
'', $enc);
3800 if (preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3801 $this->xml_encoding = strtoupper($enc);
3803 $this->xml_encoding =
'US-ASCII';
3807 $this->xml_encoding =
'ISO-8859-1';
3810 $this->headers[$k] = $v;
3811 $this->request .=
"$k: $v\r\n";
3812 $this->
debug(
"$k: $v");
3815 $this->
debug(
"In parse_http_headers, HTTP headers not accessible");
3816 $this->
setError(
"HTTP headers not accessible");
3843 $this->
debug(
'entering parse_request()');
3844 $this->parse_http_headers();
3845 $this->
debug(
'got character encoding: '.$this->xml_encoding);
3847 if (isset($this->headers[
'content-encoding']) && $this->headers[
'content-encoding'] !=
'') {
3848 $this->
debug(
'got content encoding: ' . $this->headers[
'content-encoding']);
3849 if ($this->headers[
'content-encoding'] ==
'deflate' || $this->headers[
'content-encoding'] ==
'gzip') {
3851 if (function_exists(
'gzuncompress')) {
3852 if ($this->headers[
'content-encoding'] ==
'deflate' && $degzdata = @gzuncompress(
$data)) {
3854 } elseif ($this->headers[
'content-encoding'] ==
'gzip' && $degzdata = gzinflate(substr(
$data, 10))) {
3857 $this->fault(
'SOAP-ENV:Client',
'Errors occurred when trying to decode the data');
3861 $this->fault(
'SOAP-ENV:Client',
'This Server does not support compressed data');
3866 $this->request .=
"\r\n".$data;
3867 $data = $this->parseRequest($this->headers,
$data);
3868 $this->requestSOAP =
$data;
3869 $this->
debug(
'leaving parse_request');
3889 function invoke_method() {
3890 $this->
debug(
'in invoke_method, methodname=' . $this->methodname .
' methodURI=' . $this->methodURI .
' SOAPAction=' . $this->SOAPAction);
3894 $this->
debug(
'in invoke_method, found WSDL operation=' . $this->methodname);
3898 $this->
debug(
'in invoke_method, found WSDL soapAction=' . $this->SOAPAction .
' for operation=' . $this->opData[
'name']);
3900 $this->methodname = $this->opData[
'name'];
3902 $this->
debug(
'in invoke_method, no WSDL for operation=' . $this->methodname);
3903 $this->fault(
'SOAP-ENV:Client',
"Operation '" . $this->methodname .
"' is not defined in the WSDL for this service");
3907 $this->
debug(
'in invoke_method, no WSDL to validate method');
3915 if (strpos($this->methodname,
'..') > 0) {
3917 }
else if (strpos($this->methodname,
'.') > 0) {
3923 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3924 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3926 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3927 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3928 $this->
debug(
"in invoke_method, class=$class method=$method delim=$delim");
3932 if ($class ==
'' && $this->
class !=
'')
3934 $class = $this->class;
3936 $method = $this->methodname;
3941 if (!function_exists($this->methodname)) {
3942 $this->
debug(
"in invoke_method, function '$this->methodname' not found!");
3943 $this->result =
'fault: method not found';
3944 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
3948 $method_to_compare = (substr(phpversion(), 0, 2) ==
'4.') ? strtolower($method) : $method;
3949 if (!in_array($method_to_compare, get_class_methods($class))) {
3950 $this->
debug(
"in invoke_method, method '$this->methodname' not found in class '$class'!");
3951 $this->result =
'fault: method not found';
3952 $this->fault(
'SOAP-ENV:Client',
"method '$this->methodname' not defined in service");
3959 if(! $this->verify_method($this->methodname,$this->methodparams)){
3961 $this->
debug(
'ERROR: request not verified against method signature');
3962 $this->result =
'fault: request failed validation against method signature';
3964 $this->fault(
'SOAP-ENV:Client',
"Operation '$this->methodname' not defined in service.");
3969 $this->
debug(
'in invoke_method, params:');
3971 $this->
debug(
"in invoke_method, calling '$this->methodname'");
3972 if (!function_exists(
'call_user_func_array')) {
3974 $this->
debug(
'in invoke_method, calling function using eval()');
3975 $funcCall =
"\$this->methodreturn = $this->methodname(";
3977 if ($delim ==
'..') {
3978 $this->
debug(
'in invoke_method, calling class method using eval()');
3979 $funcCall =
"\$this->methodreturn = ".$class.
"::".$method.
"(";
3981 $this->
debug(
'in invoke_method, calling instance method using eval()');
3983 $instname =
"\$inst_".time();
3984 $funcCall = $instname.
" = new ".$class.
"(); ";
3985 $funcCall .=
"\$this->methodreturn = ".$instname.
"->".$method.
"(";
3988 if ($this->methodparams) {
3989 foreach ($this->methodparams as $param) {
3990 if (is_array($param) || is_object($param)) {
3991 $this->fault(
'SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
3994 $funcCall .=
"\"$param\",";
3996 $funcCall = substr($funcCall, 0, -1);
3999 $this->
debug(
'in invoke_method, function call: '.$funcCall);
4003 $this->
debug(
'in invoke_method, calling function using call_user_func_array()');
4004 $call_arg =
"$this->methodname";
4005 } elseif ($delim ==
'..') {
4006 $this->
debug(
'in invoke_method, calling class method using call_user_func_array()');
4007 $call_arg = array ($class, $method);
4009 $this->
debug(
'in invoke_method, calling instance method using call_user_func_array()');
4010 $instance =
new $class ();
4011 $call_arg = array(&$instance, $method);
4013 if (is_array($this->methodparams)) {
4014 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4016 $this->methodreturn = call_user_func_array($call_arg, array());
4019 $this->
debug(
'in invoke_method, methodreturn:');
4021 $this->
debug(
"in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
4035 function serialize_return() {
4036 $this->
debug(
'Entering serialize_return methodname: ' . $this->methodname .
' methodURI: ' . $this->methodURI);
4038 if (isset($this->methodreturn) && ((get_class((
object)$this->methodreturn) ==
'soap_fault') || (get_class((
object)$this->methodreturn) ==
'nusoap_fault'))) {
4039 $this->
debug(
'got a fault object from method');
4040 $this->fault = $this->methodreturn;
4042 } elseif ($this->methodreturnisliteralxml) {
4043 $return_val = $this->methodreturn;
4046 $this->
debug(
'got a(n) '.gettype($this->methodreturn).
' from method');
4047 $this->
debug(
'serializing return value');
4049 if (
sizeof($this->opData[
'output'][
'parts']) > 1) {
4050 $this->
debug(
'more than one output part, so use the method return unchanged');
4051 $opParams = $this->methodreturn;
4052 } elseif (
sizeof($this->opData[
'output'][
'parts']) == 1) {
4053 $this->
debug(
'exactly one output part, so wrap the method return in a simple array');
4058 $opParams = array($this->methodreturn);
4064 $this->
debug(
'got wsdl error: '.$errstr);
4065 $this->fault(
'SOAP-ENV:Server',
'unable to serialize result');
4069 if (isset($this->methodreturn)) {
4070 $return_val = $this->
serialize_val($this->methodreturn,
'return');
4073 $this->
debug(
'in absence of WSDL, assume void return for backward compatibility');
4077 $this->
debug(
'return value:');
4080 $this->
debug(
'serializing response');
4082 $this->
debug(
'have WSDL for serialization: style is ' . $this->opData[
'style']);
4083 if ($this->opData[
'style'] ==
'rpc') {
4084 $this->
debug(
'style is rpc for serialization: use is ' . $this->opData[
'output'][
'use']);
4085 if ($this->opData[
'output'][
'use'] ==
'literal') {
4087 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4089 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4092 $this->
debug(
'style is not rpc for serialization: assume document');
4093 $payload = $return_val;
4096 $this->
debug(
'do not have WSDL for serialization: assume rpc/encoded');
4097 $payload =
'<ns1:'.$this->methodname.
'Response xmlns:ns1="'.$this->methodURI.
'">'.$return_val.
'</ns1:'.$this->methodname.
"Response>";
4099 $this->result =
'successful';
4104 if (isset($opData[
'output'][
'encodingStyle'])) {
4105 $encodingStyle = $opData[
'output'][
'encodingStyle'];
4107 $encodingStyle =
'';
4110 $this->responseSOAP = $this->
serializeEnvelope($payload,$this->responseHeaders,$this->
wsdl->usedNamespaces,$this->opData[
'style'],$this->opData[
'output'][
'use'],$encodingStyle);
4112 $this->responseSOAP = $this->
serializeEnvelope($payload,$this->responseHeaders);
4114 $this->
debug(
"Leaving serialize_return");
4127 function send_response() {
4128 $this->
debug(
'Enter send_response');
4130 $payload = $this->fault->serialize();
4131 $this->outgoing_headers[] =
"HTTP/1.0 500 Internal Server Error";
4132 $this->outgoing_headers[] =
"Status: 500 Internal Server Error";
4134 $payload = $this->responseSOAP;
4142 if(isset($this->debug_flag) && $this->debug_flag){
4145 $this->outgoing_headers[] =
"Server: $this->title Server v$this->version";
4146 preg_match(
'/\$Revisio' .
'n: ([^ ]+)/', $this->revision, $rev);
4147 $this->outgoing_headers[] =
"X-SOAP-Server: $this->title/$this->version (".$rev[1].
")";
4150 $payload = $this->getHTTPBody($payload);
4151 $type = $this->getHTTPContentType();
4152 $charset = $this->getHTTPContentTypeCharset();
4153 $this->outgoing_headers[] =
"Content-Type: $type" . ($charset ?
'; charset=' . $charset :
'');
4157 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers[
'accept-encoding'])) {
4158 if (strstr($this->headers[
'accept-encoding'],
'gzip')) {
4159 if (function_exists(
'gzencode')) {
4160 if (isset($this->debug_flag) && $this->debug_flag) {
4161 $payload .=
"<!-- Content being gzipped -->";
4163 $this->outgoing_headers[] =
"Content-Encoding: gzip";
4164 $payload = gzencode($payload);
4166 if (isset($this->debug_flag) && $this->debug_flag) {
4167 $payload .=
"<!-- Content will not be gzipped: no gzencode -->";
4170 } elseif (strstr($this->headers[
'accept-encoding'],
'deflate')) {
4174 if (function_exists(
'gzdeflate')) {
4175 if (isset($this->debug_flag) && $this->debug_flag) {
4176 $payload .=
"<!-- Content being deflated -->";
4178 $this->outgoing_headers[] =
"Content-Encoding: deflate";
4179 $payload = gzdeflate($payload);
4181 if (isset($this->debug_flag) && $this->debug_flag) {
4182 $payload .=
"<!-- Content will not be deflated: no gzcompress -->";
4188 $this->outgoing_headers[] =
"Content-Length: ".strlen($payload);
4189 reset($this->outgoing_headers);
4190 foreach($this->outgoing_headers as $hdr){
4191 header($hdr,
false);
4194 $this->response = join(
"\r\n",$this->outgoing_headers).
"\r\n\r\n".$payload;
4206 function verify_method($operation,$request){
4207 if(isset($this->
wsdl) && is_object($this->
wsdl)){
4211 } elseif(isset($this->operations[$operation])){
4225 function parseRequest($headers,
$data) {
4226 $this->
debug(
'Entering parseRequest() for data of length ' . strlen(
$data) .
' and type ' . $headers[
'content-type']);
4227 if (!strstr($headers[
'content-type'],
'text/xml')) {
4228 $this->
setError(
'Request not of type text/xml');
4231 if (strpos($headers[
'content-type'],
'=')) {
4232 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
4233 $this->
debug(
'Got response encoding: ' . $enc);
4234 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
4235 $this->xml_encoding = strtoupper($enc);
4237 $this->xml_encoding =
'US-ASCII';
4241 $this->xml_encoding =
'ISO-8859-1';
4243 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
4247 $this->
debug(
"parser debug: \n".$parser->getDebug());
4249 if($err = $parser->getError()){
4250 $this->result =
'fault: error in msg parsing: '.$err;
4251 $this->fault(
'SOAP-ENV:Client',
"error in msg parsing:\n".$err);
4255 $this->methodURI = $parser->root_struct_namespace;
4256 $this->methodname = $parser->root_struct_name;
4257 $this->
debug(
'methodname: '.$this->methodname.
' methodURI: '.$this->methodURI);
4258 $this->
debug(
'calling parser->get_soapbody()');
4259 $this->methodparams = $parser->get_soapbody();
4261 $this->requestHeaders = $parser->getHeaders();
4263 $this->requestHeader = $parser->get_soapheader();
4265 $this->document = $parser->document;
4276 function getHTTPBody($soapmsg) {
4288 function getHTTPContentType() {
4301 function getHTTPContentTypeCharset() {
4314 function add_to_map($methodname,
$in,
$out){
4315 $this->operations[$methodname] = array(
'name' => $methodname,
'in' =>
$in,
'out' =>
$out);
4332 function register(
$name,
$in=array(),
$out=array(),
$namespace=
false,$soapaction=
false,
$style=
false,$use=
false,$documentation=
'',$encodingStyle=
''){
4333 global $HTTP_SERVER_VARS;
4335 if($this->externalWSDLURL){
4336 die(
'You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4339 die(
'You must specify a name when you register an operation');
4341 if (!is_array($in)) {
4342 die(
'You must provide an array for operation inputs');
4344 if (!is_array(
$out)) {
4345 die(
'You must provide an array for operation outputs');
4349 if(
false == $soapaction) {
4351 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4353 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4354 } elseif (isset($HTTP_SERVER_VARS)) {
4355 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4356 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4357 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4359 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4361 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4366 $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4374 if ($use ==
'encoded' && $encodingStyle =
'') {
4375 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
4378 $this->operations[
$name] = array(
4383 'soapaction' => $soapaction,
4401 function fault($faultcode,$faultstring,$faultactor=
'',$faultdetail=
''){
4402 if ($faultdetail ==
'' && $this->debug_flag) {
4405 $this->fault =
new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
4420 function configureWSDL($serviceName,
$namespace =
false,
$endpoint =
false,
$style=
'rpc', $transport =
'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace =
false)
4422 global $HTTP_SERVER_VARS;
4425 $SERVER_NAME =
$_SERVER[
'SERVER_NAME'];
4426 $SERVER_PORT =
$_SERVER[
'SERVER_PORT'];
4428 $HTTPS = isset(
$_SERVER[
'HTTPS']) ?
$_SERVER[
'HTTPS'] : (isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off');
4429 } elseif (isset($HTTP_SERVER_VARS)) {
4430 $SERVER_NAME = $HTTP_SERVER_VARS[
'SERVER_NAME'];
4431 $SERVER_PORT = $HTTP_SERVER_VARS[
'SERVER_PORT'];
4432 $SCRIPT_NAME = isset($HTTP_SERVER_VARS[
'PHP_SELF']) ? $HTTP_SERVER_VARS[
'PHP_SELF'] : $HTTP_SERVER_VARS[
'SCRIPT_NAME'];
4433 $HTTPS = isset($HTTP_SERVER_VARS[
'HTTPS']) ? $HTTP_SERVER_VARS[
'HTTPS'] :
'off';
4435 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
4438 $colon = strpos($SERVER_NAME,
":");
4440 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4442 if ($SERVER_PORT == 80) {
4445 $SERVER_PORT =
':' . $SERVER_PORT;
4448 $namespace =
"http://$SERVER_NAME/soap/$serviceName";
4452 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4457 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4460 if(
false == $schemaTargetNamespace) {
4465 $this->
wsdl->serviceName = $serviceName;
4468 $this->
wsdl->namespaces[
'soap'] =
'http://schemas.xmlsoap.org/wsdl/soap/';
4469 $this->
wsdl->namespaces[
'wsdl'] =
'http://schemas.xmlsoap.org/wsdl/';
4471 $this->
wsdl->namespaces[
'types'] = $schemaTargetNamespace;
4474 if (
$style ==
'document') {
4475 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo[
'elementFormDefault'] =
'qualified';
4477 $this->
wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4478 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/soap/encoding/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4479 $this->
wsdl->schemas[$schemaTargetNamespace][0]->imports[
'http://schemas.xmlsoap.org/wsdl/'][0] = array(
'location' =>
'',
'loaded' =>
true);
4480 $this->
wsdl->bindings[$serviceName.
'Binding'] = array(
4481 'name'=>$serviceName.
'Binding',
4483 'transport'=>$transport,
4484 'portType'=>$serviceName.
'PortType');
4485 $this->
wsdl->ports[$serviceName.
'Port'] = array(
4486 'binding'=>$serviceName.
'Binding',
4488 'bindingType'=>
'http://schemas.xmlsoap.org/wsdl/soap/');
4515 var $schemas = array();
4517 var $message = array();
4518 var $complexTypes = array();
4520 var $currentMessage;
4521 var $currentOperation;
4522 var $portTypes = array();
4523 var $currentPortType;
4525 var $currentBinding;
4526 var $ports = array();
4528 var $opData = array();
4530 var $documentation =
false;
4533 var $import = array();
4538 var $depth_array = array();
4540 var $proxyhost =
'';
4541 var $proxyport =
'';
4542 var $proxyusername =
'';
4543 var $proxypassword =
'';
4545 var $response_timeout = 30;
4546 var $curl_options = array();
4547 var $use_curl =
false;
4552 var $certRequest = array();
4568 function __construct($wsdl =
'',$proxyhost=
false,$proxyport=
false,$proxyusername=
false,$proxypassword=
false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=
false){
4569 parent::__construct();
4570 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4571 $this->proxyhost = $proxyhost;
4572 $this->proxyport = $proxyport;
4573 $this->proxyusername = $proxyusername;
4574 $this->proxypassword = $proxypassword;
4575 $this->timeout = $timeout;
4576 $this->response_timeout = $response_timeout;
4577 if (is_array($curl_options))
4578 $this->curl_options = $curl_options;
4579 $this->use_curl = $use_curl;
4580 $this->fetchWSDL($wsdl);
4588 function fetchWSDL($wsdl) {
4589 $this->
debug(
"parse and process WSDL path=$wsdl");
4590 $this->
wsdl = $wsdl;
4592 if ($this->
wsdl !=
"") {
4593 $this->parseWSDL($this->
wsdl);
4597 $imported_urls = array();
4599 while ($imported > 0) {
4602 foreach ($this->schemas as $ns =>
$list) {
4603 foreach (
$list as $xs) {
4604 $wsdlparts = parse_url($this->
wsdl);
4605 foreach ($xs->imports as $ns2 => $list2) {
4606 for (
$ii = 0;
$ii < count($list2);
$ii++) {
4607 if (! $list2[
$ii][
'loaded']) {
4608 $this->schemas[$ns]->imports[$ns2][
$ii][
'loaded'] =
true;
4609 $url = $list2[
$ii][
'location'];
4611 $urlparts = parse_url($url);
4612 if (!isset($urlparts[
'host'])) {
4613 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' .$wsdlparts[
'port'] :
'') .
4614 substr($wsdlparts[
'path'],0,strrpos($wsdlparts[
'path'],
'/') + 1) .$urlparts[
'path'];
4616 if (! in_array($url, $imported_urls)) {
4617 $this->parseWSDL($url);
4619 $imported_urls[] =
$url;
4622 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4630 $wsdlparts = parse_url($this->
wsdl);
4631 foreach ($this->
import as $ns =>
$list) {
4632 for ($ii = 0; $ii < count(
$list); $ii++) {
4633 if (!
$list[$ii][
'loaded']) {
4634 $this->
import[$ns][
$ii][
'loaded'] =
true;
4637 $urlparts = parse_url($url);
4638 if (!isset($urlparts[
'host'])) {
4639 $url = $wsdlparts[
'scheme'] .
'://' . $wsdlparts[
'host'] . (isset($wsdlparts[
'port']) ?
':' . $wsdlparts[
'port'] :
'') .
4640 substr($wsdlparts[
'path'],0,strrpos($wsdlparts[
'path'],
'/') + 1) .$urlparts[
'path'];
4642 if (! in_array($url, $imported_urls)) {
4643 $this->parseWSDL($url);
4645 $imported_urls[] =
$url;
4648 $this->
debug(
"Unexpected scenario: empty URL for unloaded import");
4655 foreach($this->bindings as
$binding => $bindingData) {
4656 if (isset($bindingData[
'operations']) && is_array($bindingData[
'operations'])) {
4657 foreach($bindingData[
'operations'] as $operation =>
$data) {
4658 $this->
debug(
'post-parse data gathering for ' . $operation);
4659 $this->bindings[
$binding][
'operations'][$operation][
'input'] =
4660 isset($this->bindings[
$binding][
'operations'][$operation][
'input']) ?
4661 array_merge($this->bindings[
$binding][
'operations'][$operation][
'input'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input']) :
4662 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'input'];
4663 $this->bindings[
$binding][
'operations'][$operation][
'output'] =
4664 isset($this->bindings[
$binding][
'operations'][$operation][
'output']) ?
4665 array_merge($this->bindings[
$binding][
'operations'][$operation][
'output'], $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output']) :
4666 $this->portTypes[ $bindingData[
'portType'] ][$operation][
'output'];
4667 if(isset($this->messages[ $this->bindings[
$binding][
'operations'][$operation][
'input'][
'message'] ])){
4668 $this->bindings[
$binding][
'operations'][$operation][
'input'][
'parts'] = $this->messages[ $this->bindings[
$binding][
'operations'][$operation][
'input'][
'message'] ];
4670 if(isset($this->messages[ $this->bindings[
$binding][
'operations'][$operation][
'output'][
'message'] ])){
4671 $this->bindings[
$binding][
'operations'][$operation][
'output'][
'parts'] = $this->messages[ $this->bindings[
$binding][
'operations'][$operation][
'output'][
'message'] ];
4674 if (isset($bindingData[
'style']) && !isset($this->bindings[
$binding][
'operations'][$operation][
'style'])) {
4675 $this->bindings[
$binding][
'operations'][$operation][
'style'] = $bindingData[
'style'];
4677 $this->bindings[
$binding][
'operations'][$operation][
'transport'] = isset($bindingData[
'transport']) ? $bindingData[
'transport'] :
'';
4678 $this->bindings[
$binding][
'operations'][$operation][
'documentation'] = isset($this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation']) ? $this->portTypes[ $bindingData[
'portType'] ][$operation][
'documentation'] :
'';
4679 $this->bindings[
$binding][
'operations'][$operation][
'endpoint'] = isset($bindingData[
'endpoint']) ? $bindingData[
'endpoint'] :
'';
4691 function parseWSDL($wsdl =
'') {
4692 $this->
debug(
"parse WSDL at path=$wsdl");
4695 $this->
debug(
'no wsdl passed to parseWSDL()!!');
4696 $this->
setError(
'no wsdl passed to parseWSDL()!!');
4701 $wsdl_props = parse_url($wsdl);
4703 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'http' || $wsdl_props[
'scheme'] ==
'https')) {
4704 $this->
debug(
'getting WSDL http(s) URL ' . $wsdl);
4707 $tr->request_method =
'GET';
4708 $tr->useSOAPAction =
false;
4709 if($this->proxyhost && $this->proxyport){
4710 $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
4712 if ($this->authtype !=
'') {
4713 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4715 $tr->setEncoding(
'gzip, deflate');
4716 $wsdl_string = $tr->send(
'', $this->timeout, $this->response_timeout);
4721 if($err = $tr->getError() ){
4722 $errstr =
'HTTP ERROR: '.$err;
4723 $this->
debug($errstr);
4729 $this->
debug(
"got WSDL URL");
4732 if (isset($wsdl_props[
'scheme']) && ($wsdl_props[
'scheme'] ==
'file') && isset($wsdl_props[
'path'])) {
4733 $path = isset($wsdl_props[
'host']) ? ($wsdl_props[
'host'] .
':' . $wsdl_props[
'path']) : $wsdl_props[
'path'];
4737 $this->
debug(
'getting WSDL file ' . $path);
4738 if ($fp = @
fopen($path,
'r')) {
4740 while (
$data = fread($fp, 32768)) {
4741 $wsdl_string .=
$data;
4745 $errstr =
"Bad path to WSDL file $path";
4746 $this->
debug($errstr);
4751 $this->
debug(
'Parse WSDL');
4754 $this->parser = xml_parser_create();
4757 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4759 xml_set_object($this->parser, $this);
4761 xml_set_element_handler($this->parser,
'start_element',
'end_element');
4762 xml_set_character_data_handler($this->parser,
'character_data');
4764 if (!xml_parse($this->parser, $wsdl_string,
true)) {
4767 'XML error parsing WSDL from %s on line %d: %s',
4769 xml_get_current_line_number($this->parser),
4770 xml_error_string(xml_get_error_code($this->parser))
4772 $this->
debug($errstr);
4773 $this->
debug(
"XML payload:\n" . $wsdl_string);
4778 xml_parser_free($this->parser);
4779 $this->
debug(
'Parsing WSDL done');
4795 function start_element($parser,
$name, $attrs)
4797 if ($this->status ==
'schema') {
4798 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4799 $this->
appendDebug($this->currentSchema->getDebug());
4800 $this->currentSchema->clearDebug();
4801 } elseif (preg_match(
'/schema$/',
$name)) {
4802 $this->
debug(
'Parsing WSDL schema');
4804 $this->status =
'schema';
4806 $this->currentSchema->schemaStartElement($parser,
$name, $attrs);
4807 $this->
appendDebug($this->currentSchema->getDebug());
4808 $this->currentSchema->clearDebug();
4811 $pos = $this->position++;
4812 $depth = $this->depth++;
4814 $this->depth_array[$depth] = $pos;
4815 $this->message[$pos] = array(
'cdata' =>
'');
4817 if (count($attrs) > 0) {
4819 foreach($attrs as $k => $v) {
4820 if (preg_match(
'/^xmlns/',$k)) {
4821 if ($ns_prefix = substr(strrchr($k,
':'), 1)) {
4822 $this->namespaces[$ns_prefix] = $v;
4824 $this->namespaces[
'ns' . (count($this->namespaces) + 1)] = $v;
4826 if ($v ==
'http://www.w3.org/2001/XMLSchema' || $v ==
'http://www.w3.org/1999/XMLSchema' || $v ==
'http://www.w3.org/2000/10/XMLSchema') {
4827 $this->XMLSchemaVersion = $v;
4828 $this->namespaces[
'xsi'] = $v .
'-instance';
4833 foreach($attrs as $k => $v) {
4834 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
4835 if ($k !=
'location' && $k !=
'soapAction' && $k !=
'namespace') {
4836 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
4845 if (preg_match(
'/:/',
$name)) {
4847 $prefix = substr(
$name, 0, strpos(
$name,
':'));
4849 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] :
'';
4855 switch ($this->status) {
4857 if (
$name ==
'part') {
4858 if (isset($attrs[
'type'])) {
4859 $this->
debug(
"msg " . $this->currentMessage .
": found part (with type) $attrs[name]: " . implode(
',', $attrs));
4860 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'type'];
4862 if (isset($attrs[
'element'])) {
4863 $this->
debug(
"msg " . $this->currentMessage .
": found part (with element) $attrs[name]: " . implode(
',', $attrs));
4864 $this->messages[$this->currentMessage][$attrs[
'name']] = $attrs[
'element'] .
'^';
4871 $this->currentPortOperation = $attrs[
'name'];
4872 $this->
debug(
"portType $this->currentPortType operation: $this->currentPortOperation");
4873 if (isset($attrs[
'parameterOrder'])) {
4874 $this->portTypes[$this->currentPortType][$attrs[
'name']][
'parameterOrder'] = $attrs[
'parameterOrder'];
4877 case 'documentation':
4878 $this->documentation =
true;
4882 $m = isset($attrs[
'message']) ? $this->
getLocalPart($attrs[
'message']) :
'';
4883 $this->portTypes[$this->currentPortType][$this->currentPortOperation][
$name][
'message'] =
$m;
4891 if (isset($attrs[
'style'])) {
4892 $this->bindings[$this->currentBinding][
'prefix'] = $prefix;
4894 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4897 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus][
'headers'][] = $attrs;
4900 if (isset($attrs[
'soapAction'])) {
4901 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'soapAction'] = $attrs[
'soapAction'];
4903 if (isset($attrs[
'style'])) {
4904 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'style'] = $attrs[
'style'];
4906 if (isset($attrs[
'name'])) {
4907 $this->currentOperation = $attrs[
'name'];
4908 $this->
debug(
"current binding operation: $this->currentOperation");
4909 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'name'] = $attrs[
'name'];
4910 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'binding'] = $this->currentBinding;
4911 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][
'endpoint'] = isset($this->bindings[$this->currentBinding][
'endpoint']) ? $this->bindings[$this->currentBinding][
'endpoint'] :
'';
4915 $this->opStatus =
'input';
4918 $this->opStatus =
'output';
4921 if (isset($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus])) {
4922 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus], $attrs);
4924 $this->bindings[$this->currentBinding][
'operations'][$this->currentOperation][$this->opStatus] = $attrs;
4932 $this->currentPort = $attrs[
'name'];
4933 $this->
debug(
'current port: ' . $this->currentPort);
4934 $this->ports[$this->currentPort][
'binding'] = $this->
getLocalPart($attrs[
'binding']);
4938 $this->ports[$this->currentPort][
'location'] = $attrs[
'location'];
4939 $this->ports[$this->currentPort][
'bindingType'] =
$namespace;
4940 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'bindingType'] =
$namespace;
4941 $this->bindings[ $this->ports[$this->currentPort][
'binding'] ][
'endpoint'] = $attrs[
'location'];
4949 if (isset($attrs[
'location'])) {
4950 $this->
import[$attrs[
'namespace']][] = array(
'location' => $attrs[
'location'],
'loaded' =>
false);
4951 $this->
debug(
'parsing import ' . $attrs[
'namespace'].
' - ' . $attrs[
'location'] .
' (' . count($this->
import[$attrs[
'namespace']]).
')');
4953 $this->
import[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
4955 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $attrs[
'namespace'];
4957 $this->
debug(
'parsing import ' . $attrs[
'namespace'].
' - [no location] (' . count($this->
import[$attrs[
'namespace']]).
')');
4965 $this->status =
'message';
4966 $this->messages[$attrs[
'name']] = array();
4967 $this->currentMessage = $attrs[
'name'];
4970 $this->status =
'portType';
4971 $this->portTypes[$attrs[
'name']] = array();
4972 $this->currentPortType = $attrs[
'name'];
4975 if (isset($attrs[
'name'])) {
4977 if (strpos($attrs[
'name'],
':')) {
4978 $this->currentBinding = $this->
getLocalPart($attrs[
'name']);
4980 $this->currentBinding = $attrs[
'name'];
4982 $this->status =
'binding';
4983 $this->bindings[$this->currentBinding][
'portType'] = $this->
getLocalPart($attrs[
'type']);
4984 $this->
debug(
"current binding: $this->currentBinding of portType: " . $attrs[
'type']);
4988 $this->serviceName = $attrs[
'name'];
4989 $this->status =
'service';
4990 $this->
debug(
'current service: ' . $this->serviceName);
4993 foreach ($attrs as
$name => $value) {
4994 $this->wsdl_info[
$name] = $value;
5008 function end_element($parser,
$name){
5010 if ( preg_match(
'/schema$/',
$name)) {
5012 $this->
appendDebug($this->currentSchema->getDebug());
5013 $this->currentSchema->clearDebug();
5014 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5015 $this->
debug(
'Parsing WSDL schema done');
5017 if ($this->status ==
'schema') {
5018 $this->currentSchema->schemaEndElement($parser,
$name);
5024 if ($this->documentation) {
5027 $this->documentation =
false;
5038 function character_data($parser,
$data)
5040 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5041 if (isset($this->message[$pos][
'cdata'])) {
5042 $this->message[$pos][
'cdata'] .=
$data;
5044 if ($this->documentation) {
5045 $this->documentation .=
$data;
5058 function setCredentials($username, $password, $authtype =
'basic', $certRequest = array()) {
5059 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
5061 $this->username = $username;
5063 $this->authtype = $authtype;
5064 $this->certRequest = $certRequest;
5069 if (is_array($this->bindings[
$binding])) {
5081 function getOperations($bindingType =
'soap') {
5083 if ($bindingType ==
'soap') {
5084 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5085 } elseif ($bindingType ==
'soap12') {
5086 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5089 foreach($this->ports as $port => $portData) {
5091 if ($portData[
'bindingType'] == $bindingType) {
5096 if (isset($this->bindings[ $portData[
'binding'] ][
'operations'])) {
5097 $ops = array_merge ($ops, $this->bindings[ $portData[
'binding'] ][
'operations']);
5112 function getOperationData($operation, $bindingType =
'soap')
5114 if ($bindingType ==
'soap') {
5115 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5116 } elseif ($bindingType ==
'soap12') {
5117 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5120 foreach($this->ports as $port => $portData) {
5122 if ($portData[
'bindingType'] == $bindingType) {
5125 foreach(array_keys($this->bindings[ $portData[
'binding'] ][
'operations']) as $bOperation) {
5127 if ($operation == $bOperation) {
5128 $opData = $this->bindings[ $portData[
'binding'] ][
'operations'][$operation];
5144 function getOperationDataForSoapAction($soapAction, $bindingType =
'soap') {
5145 if ($bindingType ==
'soap') {
5146 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap/';
5147 } elseif ($bindingType ==
'soap12') {
5148 $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
5151 foreach($this->ports as $port => $portData) {
5153 if ($portData[
'bindingType'] == $bindingType) {
5155 foreach ($this->bindings[ $portData[
'binding'] ][
'operations'] as $bOperation => $opData) {
5156 if ($opData[
'soapAction'] == $soapAction) {
5182 function getTypeDef($type, $ns) {
5183 $this->
debug(
"in getTypeDef: type=$type, ns=$ns");
5184 if ((! $ns) && isset($this->namespaces[
'tns'])) {
5185 $ns = $this->namespaces[
'tns'];
5186 $this->
debug(
"in getTypeDef: type namespace forced to $ns");
5188 if (!isset($this->schemas[$ns])) {
5189 foreach ($this->schemas as $ns0 => $schema0) {
5190 if (strcasecmp($ns, $ns0) == 0) {
5191 $this->
debug(
"in getTypeDef: replacing schema namespace $ns with $ns0");
5197 if (isset($this->schemas[$ns])) {
5198 $this->
debug(
"in getTypeDef: have schema for namespace $ns");
5199 for (
$i = 0;
$i < count($this->schemas[$ns]);
$i++) {
5200 $xs = &$this->schemas[$ns][
$i];
5201 $t = $xs->getTypeDef($type);
5205 if (!isset(
$t[
'phpType'])) {
5207 $uqType = substr(
$t[
'type'], strrpos(
$t[
'type'],
':') + 1);
5208 $ns = substr(
$t[
'type'], 0, strrpos(
$t[
'type'],
':'));
5209 $etype = $this->getTypeDef($uqType, $ns);
5211 $this->
debug(
"found type for [element] $type:");
5213 if (isset($etype[
'phpType'])) {
5214 $t[
'phpType'] = $etype[
'phpType'];
5216 if (isset($etype[
'elements'])) {
5217 $t[
'elements'] = $etype[
'elements'];
5219 if (isset($etype[
'attrs'])) {
5220 $t[
'attrs'] = $etype[
'attrs'];
5228 $this->
debug(
"in getTypeDef: do not have schema for namespace $ns");
5238 function webDescription(){
5239 global $HTTP_SERVER_VARS;
5243 } elseif (isset($HTTP_SERVER_VARS)) {
5244 $PHP_SELF = $HTTP_SERVER_VARS[
'PHP_SELF'];
5246 $this->
setError(
"Neither _SERVER nor HTTP_SERVER_VARS is available");
5249 $PHP_SELF = filter_var($PHP_SELF, FILTER_SANITIZE_STRING);
5253 <html><head><title>NuSOAP: '.$this->serviceName.
'</title> 5254 <style type="text/css"> 5255 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5256 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5257 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5258 ul { margin-top: 10px; margin-left: 20px; } 5259 li { list-style-type: none; margin-top: 10px; color: #000000; } 5261 margin-left: 0px; padding-bottom: 2em; } 5263 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5264 margin-top: 10px; margin-left: 0px; color: #000000; 5265 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5267 font-family: arial; font-size: 26px; color: #ffffff; 5268 background-color: #999999; width: 105%; margin-left: 0px; 5269 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5271 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5272 font-family: arial; overflow: hidden; width: 600; 5273 padding: 20px; font-size: 10px; background-color: #999999; 5274 layer-background-color:#FFFFFF; } 5275 a,a:active { color: charcoal; font-weight: bold; } 5276 a:visited { color: #666666; font-weight: bold; } 5277 a:hover { color: cc3300; font-weight: bold; } 5279 <script language="JavaScript" type="text/javascript"> 5281 // POP-UP CAPTIONS... 5282 function lib_bwcheck(){ //Browsercheck (needed) 5283 this.ver=navigator.appVersion 5284 this.agent=navigator.userAgent 5285 this.dom=document.getElementById?1:0 5286 this.opera5=this.agent.indexOf("Opera 5")>-1 5287 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5288 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5289 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5290 this.ie=this.ie4||this.ie5||this.ie6 5291 this.mac=this.agent.indexOf("Mac")>-1 5292 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5293 this.ns4=(document.layers && !this.dom)?1:0; 5294 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5297 var bw = new lib_bwcheck() 5298 //Makes crossbrowser object. 5299 function makeObj(obj){ 5300 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5301 if(!this.evnt) return false 5302 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5303 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5304 this.writeIt=b_writeIt; 5307 // A unit of measure that will be added when setting the position of a layer. 5308 //var px = bw.ns4||window.opera?"":"px"; 5309 function b_writeIt(text){ 5310 if (bw.ns4){this.wref.write(text);this.wref.close()} 5311 else this.wref.innerHTML = text 5313 //Shows the messages 5315 function popup(divid){ 5316 if(oDesc = new makeObj(divid)){ 5317 oDesc.css.visibility = "visible" 5320 function popout(){ // Hides message 5321 if(oDesc) oDesc.css.visibility = "hidden" 5329 <div class=title>'.$this->serviceName.
'</div> 5331 <p>View the <a href="'.$PHP_SELF.
'?wsdl">WSDL</a> for the service. 5332 Click on an operation name to view it's details.</p> 5334 foreach($this->getOperations() as $op =>
$data){
5336 if (isset(
$data[
'endpoint'])) {
5337 $data[
'endpoint'] = filter_var(
$data[
'endpoint'], FILTER_SANITIZE_STRING);
5340 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5342 $b .=
"<div id='$op' class='hidden'> 5343 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5344 foreach(
$data as $donnie => $marie){
5345 if($donnie ==
'input' || $donnie ==
'output'){
5346 $b .=
"<font color='white'>".ucfirst($donnie).
':</font><br>';
5347 foreach($marie as $captain => $tenille){
5348 if($captain ==
'parts'){
5349 $b .=
" $captain:<br>";
5351 foreach($tenille as $joanie => $chachi){
5352 $b .=
" $joanie: $chachi<br>";
5356 $b .=
" $captain: $tenille<br>";
5360 $b .=
"<font color='white'>".ucfirst($donnie).
":</font> $marie<br>";
5368 </div></body></html>';
5381 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5382 $xml .=
"\n<definitions";
5383 foreach($this->namespaces as $k => $v) {
5384 $xml .=
" xmlns:$k=\"$v\"";
5387 if (isset($this->namespaces[
'wsdl'])) {
5388 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5390 if (isset($this->namespaces[
'tns'])) {
5391 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5395 if (
sizeof($this->
import) > 0) {
5396 foreach($this->
import as $ns =>
$list) {
5397 foreach (
$list as $ii) {
5398 if ($ii[
'location'] !=
'') {
5399 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5401 $xml .=
'<import namespace="' . $ns .
'" />';
5407 if (count($this->schemas)>=1) {
5408 $xml .=
"\n<types>\n";
5409 foreach ($this->schemas as $ns =>
$list) {
5410 foreach (
$list as $xs) {
5411 $xml .= $xs->serializeSchema();
5417 if (count($this->messages) >= 1) {
5418 foreach($this->messages as $msgName => $msgParts) {
5419 $xml .=
"\n<message name=\"" . $msgName .
'">';
5420 if(is_array($msgParts)){
5421 foreach($msgParts as $partName => $partType) {
5423 if (strpos($partType,
':')) {
5425 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5427 $typePrefix =
'xsd';
5429 foreach($this->typemap as $ns => $types) {
5430 if (isset($types[$partType])) {
5434 if (!isset($typePrefix)) {
5435 die(
"$partType has no namespace!");
5440 $typeDef = $this->getTypeDef($localPart, $ns);
5441 if ($typeDef[
'typeClass'] ==
'element') {
5442 $elementortype =
'element';
5443 if (substr($localPart, -1) ==
'^') {
5444 $localPart = substr($localPart, 0, -1);
5447 $elementortype =
'type';
5449 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5452 $xml .=
'</message>';
5456 if (count($this->bindings) >= 1) {
5459 foreach($this->bindings as $bindingName => $attrs) {
5460 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5461 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5462 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5463 foreach($attrs[
'operations'] as $opName => $opParts) {
5464 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5465 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="'. $opParts[
'style'] .
'"/>';
5466 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5467 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5471 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5472 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5473 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5477 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5478 $binding_xml .=
"\n" .
' </operation>';
5479 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5480 if (isset($opParts[
'parameterOrder'])) {
5481 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5483 $portType_xml .=
'>';
5484 if(isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5485 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5487 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5488 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5489 $portType_xml .=
"\n" .
' </operation>';
5491 $portType_xml .=
"\n" .
'</portType>';
5492 $binding_xml .=
"\n" .
'</binding>';
5494 $xml .= $portType_xml . $binding_xml;
5497 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5498 $has_client = isset(
$_GET[
'client_id']);
5499 if (count($this->ports) >= 1) {
5500 foreach($this->ports as $pName => $attrs) {
5501 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5502 $address = $attrs[
'location'] . ($debug || $has_client ?
"?" :
"")
5503 . ($debug ?
'debug=1' :
'') . ($debug && $has_client ?
"&" :
"")
5504 . ($has_client ?
'client_id=' .
$_GET[
'client_id'] :
'');
5505 $xml .=
"\n" .
' <soap:address location="' . $address.
'"/>';
5506 $xml .=
"\n" .
' </port>';
5510 $xml .=
"\n" .
'</service>';
5511 return $xml .
"\n</definitions>";
5523 function parametersMatchWrapped($type, &$parameters) {
5524 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5528 if (strpos($type,
':')) {
5529 $uqType = substr($type, strrpos($type,
':') + 1);
5530 $ns = substr($type, 0, strrpos($type,
':'));
5531 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5534 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5539 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5545 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5546 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5549 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5551 if (substr($uqType, -1) ==
'^') {
5552 $uqType = substr($uqType, 0, -1);
5554 $phpType = $typeDef[
'phpType'];
5555 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5556 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5559 if ($phpType !=
'struct') {
5560 $this->
debug(
"in parametersMatchWrapped: not a struct");
5565 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5569 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5570 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5573 foreach ($typeDef[
'elements'] as
$name => $attrs) {
5575 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5576 $parameters[
$name] = $parameters[$elements];
5577 unset($parameters[$elements]);
5579 } elseif (isset($parameters[
$name])) {
5580 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5583 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5588 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5589 if ($matches == 0) {
5597 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5598 return count($parameters) == 0;
5616 function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap') {
5617 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5620 if ($direction !=
'input' && $direction !=
'output') {
5621 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5622 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5625 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5626 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5627 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5630 $this->
debug(
'in serializeRPCParameters: opData:');
5634 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5635 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5636 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5637 $enc_style = $encodingStyle;
5642 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5643 $parts = &$opData[$direction][
'parts'];
5644 $part_count =
sizeof($parts);
5645 $style = $opData[
'style'];
5646 $use = $opData[$direction][
'use'];
5647 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5648 if (is_array($parameters)) {
5650 $parameter_count = count($parameters);
5651 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5653 if (
$style ==
'document' && $use ==
'literal' && $part_count == 1 && isset($parts[
'parameters'])) {
5654 $this->
debug(
'check whether the caller has wrapped the parameters');
5655 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5656 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5657 if ($this->parametersMatchWrapped($parts[
'parameters'], $parameters)) {
5658 $this->
debug(
'wrap the parameters for the caller');
5659 $parameters = array(
'parameters' => $parameters);
5660 $parameter_count = 1;
5664 foreach ($parts as
$name => $type) {
5665 $this->
debug(
"serializing part $name of type $type");
5667 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5668 $encodingStyle = $opData[$direction][
'encodingStyle'];
5669 $enc_style = $encodingStyle;
5675 if ($parametersArrayType ==
'arraySimple') {
5676 $p = array_shift($parameters);
5677 $this->
debug(
'calling serializeType w/indexed param');
5678 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5679 } elseif (isset($parameters[
$name])) {
5680 $this->
debug(
'calling serializeType w/named param');
5681 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5684 $this->
debug(
'calling serializeType w/null param');
5685 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5689 $this->
debug(
'no parameters passed.');
5692 $this->
debug(
"serializeRPCParameters returning: $xml");
5710 function serializeParameters($operation, $direction, $parameters)
5712 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5715 if ($direction !=
'input' && $direction !=
'output') {
5716 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5717 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5720 if (!$opData = $this->getOperationData($operation)) {
5721 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5722 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5725 $this->
debug(
'opData:');
5729 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5730 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5731 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5732 $enc_style = $encodingStyle;
5737 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5739 $use = $opData[$direction][
'use'];
5740 $this->
debug(
"use=$use");
5741 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5742 if (is_array($parameters)) {
5744 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5745 foreach($opData[$direction][
'parts'] as
$name => $type) {
5746 $this->
debug(
'serializing part "'.
$name.
'" of type "'.$type.
'"');
5748 if(isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5749 $encodingStyle = $opData[$direction][
'encodingStyle'];
5750 $enc_style = $encodingStyle;
5756 if ($parametersArrayType ==
'arraySimple') {
5757 $p = array_shift($parameters);
5758 $this->
debug(
'calling serializeType w/indexed param');
5759 $xml .= $this->serializeType(
$name, $type, $p, $use, $enc_style);
5760 } elseif (isset($parameters[
$name])) {
5761 $this->
debug(
'calling serializeType w/named param');
5762 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5765 $this->
debug(
'calling serializeType w/null param');
5766 $xml .= $this->serializeType(
$name, $type, null, $use, $enc_style);
5770 $this->
debug(
'no parameters passed.');
5773 $this->
debug(
"serializeParameters returning: $xml");
5789 function serializeType(
$name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5791 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5793 if($use ==
'encoded' && $encodingStyle) {
5794 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5798 if (is_object($value) && get_class($value) ==
'soapval') {
5799 if ($value->type_ns) {
5800 $type = $value->type_ns .
':' . $value->type;
5802 $this->
debug(
"in serializeType: soapval overrides type to $type");
5803 } elseif ($value->type) {
5804 $type = $value->type;
5806 $this->
debug(
"in serializeType: soapval overrides type to $type");
5809 $this->
debug(
"in serializeType: soapval does not override type");
5811 $attrs = $value->attributes;
5812 $value = $value->value;
5813 $this->
debug(
"in serializeType: soapval overrides value to $value");
5815 if (!is_array($value)) {
5816 $value[
'!'] = $value;
5818 foreach ($attrs as
$n => $v) {
5819 $value[
'!' .
$n] = $v;
5821 $this->
debug(
"in serializeType: soapval provides attributes");
5828 if (strpos($type,
':')) {
5829 $uqType = substr($type, strrpos($type,
':') + 1);
5830 $ns = substr($type, 0, strrpos($type,
':'));
5831 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5834 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5837 if($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/'){
5838 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5839 if ($unqualified && $use ==
'literal') {
5840 $elementNS =
" xmlns=\"\"";
5844 if (is_null($value)) {
5845 if ($use ==
'literal') {
5847 $xml =
"<$name$elementNS/>";
5850 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5852 $this->
debug(
"in serializeType: returning: $xml");
5855 if ($uqType ==
'Array') {
5859 if ($uqType ==
'boolean') {
5860 if ((is_string($value) && $value ==
'false') || (! $value)) {
5866 if ($uqType ==
'string' && gettype($value) ==
'string') {
5869 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5870 $value = sprintf(
"%.0lf", $value);
5875 if (!$this->getTypeDef($uqType, $ns)) {
5876 if ($use ==
'literal') {
5878 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
5880 $xml =
"<$name$elementNS>$value</$name>";
5883 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
5885 $this->
debug(
"in serializeType: returning: $xml");
5888 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5889 }
else if ($ns ==
'http://xml.apache.org/xml-soap') {
5890 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
5891 if ($uqType ==
'Map') {
5894 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
5895 $tt_prefix =
'ns' . rand(1000, 9999);
5896 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
5901 foreach($value as $k => $v) {
5902 $this->
debug(
"serializing map element: key $k, value $v");
5903 $contents .=
'<item>';
5904 $contents .= $this->
serialize_val($k,
'key',
false,
false,
false,
false,$use);
5905 $contents .= $this->
serialize_val($v,
'value',
false,
false,
false,
false,$use);
5906 $contents .=
'</item>';
5908 if ($use ==
'literal') {
5910 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
5912 $xml =
"<$name>$contents</$name>";
5915 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
5917 $this->
debug(
"in serializeType: returning: $xml");
5920 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
5925 $this->
debug(
"in serializeType: No namespace for type $type");
5929 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5930 $this->
setError(
"$type ($uqType) is not a supported type.");
5931 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
5934 $this->
debug(
"in serializeType: found typeDef");
5936 if (substr($uqType, -1) ==
'^') {
5937 $uqType = substr($uqType, 0, -1);
5940 $phpType = $typeDef[
'phpType'];
5941 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'') );
5943 if ($phpType ==
'struct') {
5944 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
5945 $elementName = $uqType;
5946 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5947 $elementNS =
" xmlns=\"$ns\"";
5949 $elementNS =
" xmlns=\"\"";
5952 $elementName =
$name;
5954 $elementNS =
" xmlns=\"\"";
5959 if (is_null($value)) {
5960 if ($use ==
'literal') {
5962 $xml =
"<$elementName$elementNS/>";
5964 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5966 $this->
debug(
"in serializeType: returning: $xml");
5969 if (is_object($value)) {
5970 $value = get_object_vars($value);
5972 if (is_array($value)) {
5973 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5974 if ($use ==
'literal') {
5976 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
5978 $xml =
"<$elementName$elementNS$elementAttrs>";
5981 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
5984 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5985 $xml .=
"</$elementName>";
5987 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
5988 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
5991 } elseif ($phpType ==
'array') {
5992 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5993 $elementNS =
" xmlns=\"$ns\"";
5996 $elementNS =
" xmlns=\"\"";
6001 if (is_null($value)) {
6002 if ($use ==
'literal') {
6004 $xml =
"<$name$elementNS/>";
6006 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6015 $this->
debug(
"in serializeType: returning: $xml");
6018 if (isset($typeDef[
'multidimensional'])) {
6020 foreach($value as $v) {
6021 $cols =
',' .
sizeof($v);
6022 $nv = array_merge($nv, $v);
6028 if (is_array($value) &&
sizeof($value) >= 1) {
6029 $rows =
sizeof($value);
6031 foreach($value as $k => $v) {
6032 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6034 if (!in_array($typeDef[
'arrayType'],$this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6035 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6037 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6046 if ($use ==
'literal') {
6047 $xml =
"<$name$elementNS>" 6051 $xml =
"<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/').
':Array" '.
6054 .$this->getPrefixFromNamespace($this->
getPrefix($typeDef[
'arrayType']))
6055 .
":".$this->
getLocalPart($typeDef[
'arrayType']).
"[$rows$cols]\">" 6059 } elseif ($phpType ==
'scalar') {
6060 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6061 $elementNS =
" xmlns=\"$ns\"";
6064 $elementNS =
" xmlns=\"\"";
6069 if ($use ==
'literal') {
6071 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6073 $xml =
"<$name$elementNS>$value</$name>";
6076 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6079 $this->
debug(
"in serializeType: returning: $xml");
6093 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6095 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6096 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6097 if (is_array($value)) {
6099 } elseif (is_object($value)) {
6100 $xvalue = get_object_vars($value);
6102 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6105 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6106 if (isset($xvalue[
'!' . $aName])) {
6107 $xname =
'!' . $aName;
6108 $this->
debug(
"value provided for attribute $aName with key $xname");
6109 } elseif (isset($xvalue[$aName])) {
6111 $this->
debug(
"value provided for attribute $aName with key $xname");
6112 } elseif (isset($attrs[
'default'])) {
6113 $xname =
'!' . $aName;
6114 $xvalue[$xname] = $attrs[
'default'];
6115 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6118 $this->
debug(
"no value provided for attribute $aName");
6121 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6125 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6127 if (isset($typeDef[
'extensionBase'])) {
6128 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6129 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6133 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6134 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6135 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6137 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6155 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false) {
6157 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6158 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6159 if (is_array($value)) {
6161 } elseif (is_object($value)) {
6162 $xvalue = get_object_vars($value);
6164 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6168 if (count($typeDef[
'elements']) != count($xvalue)){
6171 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6172 if (!isset($xvalue[$eName])) {
6173 if (isset($attrs[
'default'])) {
6174 $xvalue[$eName] = $attrs[
'default'];
6175 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6179 if (isset($optionals)
6180 && (!isset($xvalue[$eName]))
6181 && ( (!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6183 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6184 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6187 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6190 if (isset($xvalue[$eName])) {
6191 $v = $xvalue[$eName];
6195 if (isset($attrs[
'form'])) {
6196 $unqualified = ($attrs[
'form'] ==
'unqualified');
6198 $unqualified =
false;
6200 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6202 foreach ($vv as $k => $v) {
6203 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6205 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6208 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6209 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6213 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6215 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6218 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6219 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6225 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6227 if (isset($typeDef[
'extensionBase'])) {
6228 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6229 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6233 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6234 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6235 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6237 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6257 function addComplexType(
$name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',$elements=array(),$attrs=array(),$arrayType=
'') {
6258 if (count($elements) > 0) {
6259 $eElements = array();
6260 foreach($elements as
$n => $e){
6263 foreach ($e as $k => $v) {
6264 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6265 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6268 $eElements[
$n] = $ee;
6270 $elements = $eElements;
6273 if (count($attrs) > 0) {
6274 foreach($attrs as
$n => $a){
6276 foreach ($a as $k => $v) {
6277 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6278 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6286 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6287 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6289 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6290 $this->schemas[$typens][0]->addComplexType(
$name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6304 function addSimpleType(
$name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array()) {
6305 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6307 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6308 $this->schemas[$typens][0]->addSimpleType(
$name, $restrictionBase, $typeClass, $phpType, $enumeration);
6318 function addElement($attrs) {
6319 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6320 $this->schemas[$typens][0]->addElement($attrs);
6337 function addOperation(
$name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false,
$style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
''){
6338 if ($use ==
'encoded' && $encodingStyle ==
'') {
6339 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6342 if (
$style ==
'document') {
6343 $elements = array();
6344 foreach ($in as
$n =>
$t) {
6345 $elements[
$n] = array(
'name' =>
$n,
'type' =>
$t);
6347 $this->addComplexType(
$name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6348 $this->addElement(array(
'name' =>
$name,
'type' =>
$name .
'RequestType'));
6349 $in = array(
'parameters' =>
'tns:' .
$name .
'^');
6351 $elements = array();
6353 $elements[
$n] = array(
'name' =>
$n,
'type' =>
$t);
6355 $this->addComplexType(
$name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6356 $this->addElement(array(
'name' =>
$name .
'Response',
'type' =>
$name .
'ResponseType',
'form' =>
'qualified'));
6357 $out = array(
'parameters' =>
'tns:' .
$name .
'Response' .
'^');
6361 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][
$name] =
6364 'binding' => $this->serviceName .
'Binding',
6365 'endpoint' => $this->endpoint,
6366 'soapAction' => $soapaction,
6371 'encodingStyle' => $encodingStyle,
6372 'message' =>
$name .
'Request',
6377 'encodingStyle' => $encodingStyle,
6378 'message' =>
$name .
'Response',
6381 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6382 'documentation' => $documentation);
6387 foreach($in as $pName => $pType)
6389 if(strpos($pType,
':')) {
6392 $this->messages[
$name.
'Request'][$pName] = $pType;
6395 $this->messages[
$name.
'Request']=
'0';
6399 foreach(
$out as $pName => $pType)
6401 if(strpos($pType,
':')) {
6404 $this->messages[
$name.
'Response'][$pName] = $pType;
6407 $this->messages[
$name.
'Response']=
'0';
6428 var $xml_encoding =
'';
6430 var $root_struct =
'';
6431 var $root_struct_name =
'';
6432 var $root_struct_namespace =
'';
6433 var $root_header =
'';
6439 var $default_namespace =
'';
6441 var $message = array();
6444 var $fault_code =
'';
6445 var $fault_str =
'';
6446 var $fault_detail =
'';
6447 var $depth_array = array();
6448 var $debug_flag =
true;
6449 var $soapresponse = NULL;
6450 var $soapheader = NULL;
6451 var $responseHeaders =
'';
6452 var $body_position = 0;
6457 var $multirefs = array();
6459 var $decode_utf8 =
true;
6470 function __construct($xml,$encoding=
'UTF-8',$method=
'',$decode_utf8=
true){
6471 parent::__construct();
6473 $this->xml_encoding = $encoding;
6474 $this->method = $method;
6475 $this->decode_utf8 = $decode_utf8;
6480 $pos_xml = strpos($xml,
'<?xml');
6481 if ($pos_xml !== FALSE) {
6482 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6483 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6484 $xml_encoding =
$res[1];
6485 if (strtoupper($xml_encoding) != $encoding) {
6486 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6488 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6494 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6497 $this->
debug(
'No encoding specified in XML declaration');
6500 $this->
debug(
'No XML declaration');
6502 $this->
debug(
'Entering nusoap_parser(), length='.strlen($xml).
', encoding='.$encoding);
6504 $this->parser = xml_parser_create($this->xml_encoding);
6507 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6508 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6510 xml_set_object($this->parser, $this);
6512 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6513 xml_set_character_data_handler($this->parser,
'character_data');
6516 if(!xml_parse($this->parser,$xml,
true)){
6518 $err = sprintf(
'XML error parsing SOAP payload on line %d: %s',
6519 xml_get_current_line_number($this->parser),
6520 xml_error_string(xml_get_error_code($this->parser)));
6522 $this->
debug(
"XML payload:\n" . $xml);
6525 $this->
debug(
'parsed successfully, found root struct: '.$this->root_struct.
' of name '.$this->root_struct_name);
6527 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6529 if($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])){
6530 $this->soapheader = $this->message[$this->root_header][
'result'];
6533 if(
sizeof($this->multirefs) > 0){
6534 foreach($this->multirefs as
$id => $hrefs){
6535 $this->
debug(
'resolving multirefs for id: '.
$id);
6536 $idVal = $this->buildVal($this->ids[
$id]);
6537 if (is_array($idVal) && isset($idVal[
'!id'])) {
6538 unset($idVal[
'!id']);
6540 foreach($hrefs as $refPos => $ref){
6541 $this->
debug(
'resolving href at pos '.$refPos);
6542 $this->multirefs[
$id][$refPos] = $idVal;
6547 xml_parser_free($this->parser);
6549 $this->
debug(
'xml was empty, didn\'t parse!');
6550 $this->
setError(
'xml was empty, didn\'t parse!');
6562 function start_element($parser,
$name, $attrs) {
6565 $pos = $this->position++;
6567 $this->message[$pos] = array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6570 $this->message[$pos][
'depth'] = $this->depth++;
6574 $this->message[$this->parent][
'children'] .=
'|'.$pos;
6577 $this->message[$pos][
'parent'] = $this->parent;
6581 $this->depth_array[$this->depth] = $pos;
6583 if(strpos(
$name,
':')){
6590 if(
$name ==
'Envelope'){
6591 $this->status =
'envelope';
6592 } elseif(
$name ==
'Header' && $this->status =
'envelope'){
6593 $this->root_header = $pos;
6594 $this->status =
'header';
6595 } elseif(
$name ==
'Body' && $this->status =
'envelope'){
6596 $this->status =
'body';
6597 $this->body_position = $pos;
6599 } elseif($this->status ==
'body' && $pos == ($this->body_position+1)){
6600 $this->status =
'method';
6601 $this->root_struct_name =
$name;
6602 $this->root_struct = $pos;
6603 $this->message[$pos][
'type'] =
'struct';
6604 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6607 $this->message[$pos][
'status'] = $this->status;
6609 $this->message[$pos][
'name'] = htmlspecialchars(
$name);
6611 $this->message[$pos][
'attrs'] = $attrs;
6615 foreach($attrs as
$key => $value){
6619 if($key_prefix ==
'xmlns'){
6620 if(preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6621 $this->XMLSchemaVersion = $value;
6623 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion.
'-instance';
6625 $this->namespaces[$key_localpart] = $value;
6627 if(
$name == $this->root_struct_name){
6628 $this->methodNamespace = $value;
6631 } elseif($key_localpart ==
'type'){
6632 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6635 $value_prefix = $this->
getPrefix($value);
6637 $this->message[$pos][
'type'] = $value_localpart;
6638 $this->message[$pos][
'typePrefix'] = $value_prefix;
6639 if(isset($this->namespaces[$value_prefix])){
6640 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6641 }
else if(isset($attrs[
'xmlns:'.$value_prefix])) {
6642 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:'.$value_prefix];
6646 } elseif($key_localpart ==
'arrayType'){
6647 $this->message[$pos][
'type'] =
'array';
6656 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6657 if(preg_match($expr,$value,$regs)){
6658 $this->message[$pos][
'typePrefix'] = $regs[1];
6659 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6660 if (isset($this->namespaces[$regs[1]])) {
6661 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6662 }
else if (isset($attrs[
'xmlns:'.$regs[1]])) {
6663 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:'.$regs[1]];
6665 $this->message[$pos][
'arrayType'] = $regs[2];
6666 $this->message[$pos][
'arraySize'] = $regs[3];
6667 $this->message[$pos][
'arrayCols'] = $regs[4];
6670 } elseif ($key_localpart ==
'nil'){
6671 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6673 } elseif (
$key !=
'href' &&
$key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6674 $this->message[$pos][
'xattrs'][
'!' .
$key] = $value;
6677 if (
$key ==
'xmlns') {
6678 $this->default_namespace = $value;
6682 $this->ids[$value] = $pos;
6685 if($key_localpart ==
'root' && $value == 1){
6686 $this->status =
'method';
6687 $this->root_struct_name =
$name;
6688 $this->root_struct = $pos;
6689 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6692 $attstr .=
" $key=\"$value\"";
6696 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6697 $this->default_namespace = $this->namespaces[$prefix];
6699 $this->message[$pos][
'namespace'] = $this->default_namespace;
6701 if($this->status ==
'header'){
6702 if ($this->root_header != $pos) {
6703 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6705 } elseif($this->root_struct_name !=
''){
6706 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6717 function end_element($parser,
$name) {
6719 $pos = $this->depth_array[$this->depth--];
6722 if(strpos(
$name,
':')){
6730 if(isset($this->body_position) && $pos > $this->body_position){
6732 if(isset($this->message[$pos][
'attrs'][
'href'])){
6734 $id = substr($this->message[$pos][
'attrs'][
'href'],1);
6736 $this->multirefs[
$id][$pos] =
'placeholder';
6738 $this->message[$pos][
'result'] =& $this->multirefs[
$id][$pos];
6740 } elseif($this->message[$pos][
'children'] !=
''){
6742 if(!isset($this->message[$pos][
'result'])){
6743 $this->message[$pos][
'result'] = $this->buildVal($pos);
6746 } elseif (isset($this->message[$pos][
'xattrs'])) {
6747 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6748 $this->message[$pos][
'xattrs'][
'!'] = null;
6749 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6750 if (isset($this->message[$pos][
'type'])) {
6751 $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'] :
'');
6753 $parent = $this->message[$pos][
'parent'];
6754 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6755 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6757 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6761 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6765 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6766 $this->message[$pos][
'xattrs'][
'!'] = null;
6767 } elseif (isset($this->message[$pos][
'type'])) {
6768 $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'] :
'');
6770 $parent = $this->message[$pos][
'parent'];
6771 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6772 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6774 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6792 if($this->status ==
'header'){
6793 if ($this->root_header != $pos) {
6794 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6796 } elseif($pos >= $this->root_struct){
6797 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6800 if($pos == $this->root_struct){
6801 $this->status =
'body';
6802 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6803 } elseif(
$name ==
'Body'){
6804 $this->status =
'envelope';
6805 } elseif(
$name ==
'Header'){
6806 $this->status =
'envelope';
6807 } elseif(
$name ==
'Envelope'){
6811 $this->
parent = $this->message[$pos][
'parent'];
6821 function character_data($parser,
$data){
6822 $pos = $this->depth_array[$this->depth];
6823 if ($this->xml_encoding==
'UTF-8'){
6827 if($this->decode_utf8){
6831 $this->message[$pos][
'cdata'] .=
$data;
6833 if($this->status ==
'header'){
6834 $this->responseHeaders .=
$data;
6836 $this->document .=
$data;
6847 function get_response(){
6848 return $this->soapresponse;
6857 function get_soapbody(){
6858 return $this->soapresponse;
6867 function get_soapheader(){
6868 return $this->soapheader;
6878 return $this->responseHeaders;
6890 function decodeSimple($value, $type, $typens) {
6892 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
6893 return (
string) $value;
6895 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
6896 return (
int) $value;
6898 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
6899 return (
double) $value;
6901 if ($type ==
'boolean') {
6902 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
6905 return (
boolean) $value;
6907 if ($type ==
'base64' || $type ==
'base64Binary') {
6908 $this->
debug(
'Decode base64 value');
6909 return base64_decode($value);
6912 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 6913 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 6914 || $type ==
'unsignedInt' 6915 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
6916 return (
int) $value;
6919 if ($type ==
'array') {
6923 return (
string) $value;
6934 function buildVal($pos){
6935 if(!isset($this->message[$pos][
'type'])){
6936 $this->message[$pos][
'type'] =
'';
6938 $this->
debug(
'in buildVal() for '.$this->message[$pos][
'name'].
"(pos $pos) of type ".$this->message[$pos][
'type']);
6940 if($this->message[$pos][
'children'] !=
''){
6941 $this->
debug(
'in buildVal, there are children');
6942 $children = explode(
'|',$this->message[$pos][
'children']);
6943 array_shift($children);
6945 if(isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
''){
6948 foreach($children as $child_pos){
6949 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
6950 $params[
$r][] = $this->message[$child_pos][
'result'];
6952 if(
$c == $this->message[$pos][
'arrayCols']){
6958 } elseif($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array'){
6959 $this->
debug(
'in buildVal, adding array '.$this->message[$pos][
'name']);
6960 foreach($children as $child_pos){
6961 $params[] = &$this->message[$child_pos][
'result'];
6964 } elseif($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap'){
6965 $this->
debug(
'in buildVal, Java Map '.$this->message[$pos][
'name']);
6966 foreach($children as $child_pos){
6967 $kv = explode(
"|",$this->message[$child_pos][
'children']);
6968 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
6974 $this->
debug(
'in buildVal, adding Java Vector or generic compound type '.$this->message[$pos][
'name']);
6975 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
6981 foreach($children as $child_pos){
6983 $params[] = &$this->message[$child_pos][
'result'];
6985 if (isset(
$params[$this->message[$child_pos][
'name']])) {
6987 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
6988 $params[$this->message[$child_pos][
'name']] = array(
$params[$this->message[$child_pos][
'name']]);
6990 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
6992 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
6997 if (isset($this->message[$pos][
'xattrs'])) {
6998 $this->
debug(
'in buildVal, handling attributes');
6999 foreach ($this->message[$pos][
'xattrs'] as
$n => $v) {
7004 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
7005 $this->
debug(
'in buildVal, handling simpleContent');
7006 if (isset($this->message[$pos][
'type'])) {
7007 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7009 $parent = $this->message[$pos][
'parent'];
7010 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7011 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7013 $params[
'!'] = $this->message[$pos][
'cdata'];
7018 $this->
debug(
'in buildVal, return:');
7022 $this->
debug(
'in buildVal, no children, building scalar');
7023 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7024 if (isset($this->message[$pos][
'type'])) {
7025 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7026 $this->
debug(
"in buildVal, return: $ret");
7029 $parent = $this->message[$pos][
'parent'];
7030 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7031 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7032 $this->
debug(
"in buildVal, return: $ret");
7035 $ret = $this->message[$pos][
'cdata'];
7036 $this->
debug(
"in buildVal, return: $ret");
7077 var $certRequest = array();
7078 var $requestHeaders =
false;
7079 var $responseHeaders =
'';
7080 var $responseHeader = NULL;
7083 var $forceEndpoint =
'';
7084 var $proxyhost =
'';
7085 var $proxyport =
'';
7086 var $proxyusername =
'';
7087 var $proxypassword =
'';
7088 var $xml_encoding =
'';
7089 var $http_encoding =
false;
7091 var $response_timeout = 30;
7092 var $endpointType =
'';
7093 var $persistentConnection =
false;
7094 var $defaultRpcParams =
false;
7098 var $cookies = array();
7099 var $decode_utf8 =
true;
7100 var $operations = array();
7101 var $curl_options = array();
7102 var $bindingType =
'';
7103 var $use_curl =
false;
7143 function __construct($endpoint,$wsdl =
false,$proxyhost =
false,$proxyport =
false,$proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30){
7144 parent::__construct();
7146 $this->proxyhost = $proxyhost;
7147 $this->proxyport = $proxyport;
7148 $this->proxyusername = $proxyusername;
7149 $this->proxypassword = $proxypassword;
7150 $this->timeout = $timeout;
7151 $this->response_timeout = $response_timeout;
7153 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7158 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7160 $this->endpoint = $this->
wsdl->
wsdl;
7162 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7167 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7169 $this->endpointType =
'wsdl';
7171 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7172 $this->endpointType =
'soap';
7201 function call($operation,
$params=array(),
$namespace=
'http://tempuri.org',$soapAction=
'',$headers=
false,$rpcParams=null,
$style=
'rpc',$use=
'encoded'){
7202 $this->operation = $operation;
7203 $this->fault =
false;
7205 $this->request =
'';
7206 $this->response =
'';
7207 $this->responseData =
'';
7208 $this->faultstring =
'';
7209 $this->faultcode =
'';
7210 $this->opData = array();
7212 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7216 $this->requestHeaders = $headers;
7218 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7224 if($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)){
7226 $this->opData = $opData;
7227 $this->
debug(
"found operation");
7229 if (isset($opData[
'soapAction'])) {
7230 $soapAction = $opData[
'soapAction'];
7232 if (! $this->forceEndpoint) {
7233 $this->endpoint = $opData[
'endpoint'];
7235 $this->endpoint = $this->forceEndpoint;
7237 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7238 $style = $opData[
'style'];
7239 $use = $opData[
'input'][
'use'];
7242 $nsPrefix =
'ns' . rand(1000, 9999);
7248 $this->
debug(
"serializing param string for WSDL operation $operation");
7250 } elseif (is_array(
$params)) {
7251 $this->
debug(
"serializing param array for WSDL operation $operation");
7254 $this->
debug(
'params must be array or string');
7255 $this->
setError(
'params must be array or string');
7259 if (isset($opData[
'input'][
'encodingStyle'])) {
7260 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7262 $encodingStyle =
'';
7267 $this->
debug(
'got wsdl error: '.$errstr);
7268 $this->
setError(
'wsdl error: '.$errstr);
7271 } elseif($this->endpointType ==
'wsdl') {
7275 $this->
setError(
'operation '.$operation.
' not present.');
7276 $this->
debug(
"operation '$operation' not present.");
7281 $nsPrefix =
'ns' . rand(1000, 9999);
7285 $this->
debug(
"serializing param string for operation $operation");
7287 } elseif (is_array(
$params)) {
7288 $this->
debug(
"serializing param array for operation $operation");
7290 $payload .= $this->
serialize_val($v,$k,
false,
false,
false,
false,$use);
7293 $this->
debug(
'params must be array or string');
7294 $this->
setError(
'params must be array or string');
7298 if ($use ==
'encoded') {
7299 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7301 $encodingStyle =
'';
7306 if ($use ==
'literal') {
7307 $this->
debug(
"wrapping RPC request with literal method element");
7310 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7312 "</$nsPrefix:$operation>";
7314 $payload =
"<$operation>" . $payload .
"</$operation>";
7317 $this->
debug(
"wrapping RPC request with encoded method element");
7319 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7321 "</$nsPrefix:$operation>";
7323 $payload =
"<$operation>" .
7331 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7332 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7334 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7336 $this->
debug(
'Error: '.$errstr);
7339 $this->
return = $return;
7340 $this->
debug(
'sent message successfully and got a(n) '.gettype($return));
7344 if(is_array($return) && isset($return[
'faultcode'])){
7345 $this->
debug(
'got fault');
7346 $this->
setError($return[
'faultcode'].
': '.$return[
'faultstring']);
7347 $this->fault =
true;
7348 foreach($return as $k => $v){
7350 $this->
debug(
"$k = $v<br>");
7353 } elseif (
$style ==
'document') {
7359 if(is_array($return)){
7362 if(
sizeof($return) > 1){
7366 $return = array_shift($return);
7367 $this->
debug(
'return shifted value: ');
7383 function checkWSDL() {
7386 $this->
debug(
'checkWSDL');
7389 $this->
debug(
'got wsdl error: '.$errstr);
7390 $this->
setError(
'wsdl error: '.$errstr);
7392 $this->bindingType =
'soap';
7393 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7395 $this->bindingType =
'soap12';
7396 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7397 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7399 $this->
debug(
'getOperations returned false');
7400 $this->
setError(
'no operations defined in the WSDL document!');
7409 function loadWSDL() {
7410 $this->
debug(
'instantiating wsdl class with doc: '.$this->wsdlFile);
7411 $this->
wsdl =
new wsdl(
'',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7412 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7424 function getOperationData($operation){
7425 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7430 if(isset($this->operations[$operation])){
7431 return $this->operations[$operation];
7433 $this->
debug(
"No data for operation: $operation");
7450 function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30) {
7451 $this->checkCookies();
7455 case preg_match(
'/^http/',$this->endpoint):
7456 $this->
debug(
'transporting via HTTP');
7457 if($this->persistentConnection ==
true && is_object($this->persistentConnection)){
7458 $http =& $this->persistentConnection;
7461 if ($this->persistentConnection) {
7462 $http->usePersistentConnection();
7465 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7466 $http->setSOAPAction($soapaction);
7467 if($this->proxyhost && $this->proxyport){
7468 $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7470 if($this->authtype !=
'') {
7471 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7473 if($this->http_encoding !=
''){
7474 $http->setEncoding($this->http_encoding);
7476 $this->
debug(
'sending message, length='.strlen($msg));
7477 if(preg_match(
'/^http:/',$this->endpoint)){
7479 $this->responseData =
$http->send($msg,$timeout,$response_timeout,$this->cookies);
7480 } elseif(preg_match(
'/^https/',$this->endpoint)){
7487 $this->responseData =
$http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7489 $this->
setError(
'no http/s in endpoint url');
7491 $this->request =
$http->outgoing_payload;
7492 $this->response =
$http->incoming_payload;
7494 $this->UpdateCookies(
$http->incoming_cookies);
7497 if ($this->persistentConnection) {
7498 $http->clearDebug();
7499 if (!is_object($this->persistentConnection)) {
7500 $this->persistentConnection =
$http;
7504 if($err =
$http->getError()){
7505 $this->
setError(
'HTTP Error: '.$err);
7510 $this->
debug(
'got response, length='. strlen($this->responseData).
' type='.
$http->incoming_headers[
'content-type']);
7511 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7515 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7529 function parseResponse($headers,
$data) {
7530 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7532 if (!strstr($headers[
'content-type'],
'text/xml')) {
7533 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7536 if (strpos($headers[
'content-type'],
'=')) {
7537 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7538 $this->
debug(
'Got response encoding: ' . $enc);
7539 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7540 $this->xml_encoding = strtoupper($enc);
7542 $this->xml_encoding =
'US-ASCII';
7546 $this->xml_encoding =
'ISO-8859-1';
7548 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7549 $parser =
new nusoap_parser(
$data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7553 if($errstr = $parser->getError()){
7560 $this->responseHeaders = $parser->getHeaders();
7562 $this->responseHeader = $parser->get_soapheader();
7564 $return = $parser->get_soapbody();
7566 $this->document = $parser->document;
7581 function setCurlOption($option, $value) {
7582 $this->
debug(
"setCurlOption option=$option, value=");
7584 $this->curl_options[$option] = $value;
7593 function setEndpoint($endpoint) {
7594 $this->
debug(
"setEndpoint(\"$endpoint\")");
7605 $this->
debug(
"setHeaders headers=");
7607 $this->requestHeaders = $headers;
7617 return $this->responseHeaders;
7627 return $this->responseHeader;
7639 function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'') {
7640 $this->proxyhost = $proxyhost;
7641 $this->proxyport = $proxyport;
7642 $this->proxyusername = $proxyusername;
7643 $this->proxypassword = $proxypassword;
7655 function setCredentials($username, $password, $authtype =
'basic', $certRequest = array()) {
7656 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7658 $this->username = $username;
7660 $this->authtype = $authtype;
7661 $this->certRequest = $certRequest;
7670 function setHTTPEncoding($enc=
'gzip, deflate'){
7671 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7672 $this->http_encoding = $enc;
7681 function setUseCURL($use) {
7682 $this->
debug(
"setUseCURL($use)");
7683 $this->use_curl = $use;
7691 function useHTTPPersistentConnection(){
7692 $this->
debug(
"useHTTPPersistentConnection");
7693 $this->persistentConnection =
true;
7707 function getDefaultRpcParams() {
7708 return $this->defaultRpcParams;
7722 function setDefaultRpcParams($rpcParams) {
7723 $this->defaultRpcParams = $rpcParams;
7733 function getProxy() {
7735 $evalStr = $this->_getProxyClassCode(
$r);
7738 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7744 eval(
"\$proxy = new nusoap_proxy_$r('');");
7746 $proxy->endpointType =
'wsdl';
7747 $proxy->wsdlFile = $this->wsdlFile;
7748 $proxy->wsdl = $this->wsdl;
7749 $proxy->operations = $this->operations;
7750 $proxy->defaultRpcParams = $this->defaultRpcParams;
7753 $proxy->username = $this->username;
7755 $proxy->authtype = $this->authtype;
7756 $proxy->certRequest = $this->certRequest;
7757 $proxy->requestHeaders = $this->requestHeaders;
7759 $proxy->forceEndpoint = $this->forceEndpoint;
7760 $proxy->proxyhost = $this->proxyhost;
7761 $proxy->proxyport = $this->proxyport;
7762 $proxy->proxyusername = $this->proxyusername;
7763 $proxy->proxypassword = $this->proxypassword;
7764 $proxy->http_encoding = $this->http_encoding;
7765 $proxy->timeout = $this->timeout;
7766 $proxy->response_timeout = $this->response_timeout;
7767 $proxy->persistentConnection = &$this->persistentConnection;
7768 $proxy->decode_utf8 = $this->decode_utf8;
7769 $proxy->curl_options = $this->curl_options;
7770 $proxy->bindingType = $this->bindingType;
7771 $proxy->use_curl = $this->use_curl;
7781 function _getProxyClassCode(
$r) {
7782 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7784 if ($this->endpointType !=
'wsdl') {
7785 $evalStr =
'A proxy can only be created for a WSDL client';
7787 $evalStr =
"echo \"$evalStr\";";
7790 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7793 return "echo \"" . $this->
getError() .
"\";";
7797 foreach ($this->operations as $operation => $opData) {
7798 if ($operation !=
'') {
7800 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7802 $paramArrayStr =
'';
7803 $paramCommentStr =
'';
7804 foreach ($opData[
'input'][
'parts'] as
$name => $type) {
7805 $paramStr .=
"\$$name, ";
7806 $paramArrayStr .=
"'$name' => \$$name, ";
7807 $paramCommentStr .=
"$type \$$name, ";
7809 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7810 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7811 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7814 $paramArrayStr =
'';
7815 $paramCommentStr =
'void';
7817 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7818 $evalStr .=
"// $paramCommentStr 7819 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7820 \$params = array($paramArrayStr); 7821 return \$this->call('$operation', \$params, '".$opData[
'namespace'].
"', '".(isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'').
"'); 7825 unset($paramCommentStr);
7828 $evalStr =
'class nusoap_proxy_'.$r.
' extends nusoap_client { 7840 function getProxyClassCode() {
7842 return $this->_getProxyClassCode(
$r);
7852 function getHTTPBody($soapmsg) {
7864 function getHTTPContentType() {
7877 function getHTTPContentTypeCharset() {
7887 function decodeUTF8($bool){
7888 $this->decode_utf8 = $bool;
7900 function setCookie(
$name, $value) {
7901 if (strlen(
$name) == 0) {
7904 $this->cookies[] = array(
'name' =>
$name,
'value' => $value);
7914 function getCookies() {
7915 return $this->cookies;
7924 function checkCookies() {
7925 if (
sizeof($this->cookies) == 0) {
7928 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
7929 $curr_cookies = $this->cookies;
7930 $this->cookies = array();
7931 foreach ($curr_cookies as $cookie) {
7932 if (! is_array($cookie)) {
7933 $this->
debug(
'Remove cookie that is not an array');
7936 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
7937 if (strtotime($cookie[
'expires']) > time()) {
7938 $this->cookies[] = $cookie;
7940 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
7943 $this->cookies[] = $cookie;
7946 $this->
debug(
'checkCookie: '.
sizeof($this->cookies).
' cookies left in array');
7957 function UpdateCookies($cookies) {
7958 if (
sizeof($this->cookies) == 0) {
7960 if (
sizeof($cookies) > 0) {
7961 $this->
debug(
'Setting new cookie(s)');
7962 $this->cookies = $cookies;
7966 if (
sizeof($cookies) == 0) {
7971 foreach ($cookies as $newCookie) {
7972 if (!is_array($newCookie)) {
7975 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
7978 $newName = $newCookie[
'name'];
7981 for (
$i = 0;
$i < count($this->cookies);
$i++) {
7982 $cookie = $this->cookies[
$i];
7983 if (!is_array($cookie)) {
7986 if (!isset($cookie[
'name'])) {
7989 if ($newName != $cookie[
'name']) {
7992 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
7993 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
7997 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
7998 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
7999 if ($newPath != $path) {
8002 $this->cookies[
$i] = $newCookie;
8004 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
8008 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
8009 $this->cookies[] = $newCookie;
8016 if (!extension_loaded(
'soap')) {
if($err=$client->getError()) $namespace
appendDebug($string)
adds debug data to the instance debug string without formatting
soap_server allows the user to create a SOAP server that is capable of receiving messages and returni...
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded')
serialize message
setError($str)
sets error string
if(isset($_REQUEST['delete'])) $list
Contains information for a SOAP fault.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
& getDebug()
gets the current debug data for this instance
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
parses a WSDL file, allows access to it's data, other utility methods
foreach($paths as $path) $request
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
split($path)
Returns the 'dirname' and 'basename' for a path.
soap_fault class, allows for creation of faults mainly used for returning faults from deployed functi...
if(!array_key_exists('StateId', $_REQUEST)) $id
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
serialize()
serialize the parsed wsdl
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='')
register a service with the server
setHeaders(array $headers)
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed ...
parses an XML Schema, allows access to it's data, other utility methods no validation...
for creating serializable abstractions of native PHP types NOTE: this is only really used when WSDL i...
getError()
returns error string if present
debug($string)
adds debug data to the class level debug string
setHeader($name, $value)
Updates a HTTP header.
soap_parser class parses SOAP XML messages into native PHP values
catch(Exception $e) $message
foreach($_POST as $key=> $value) $res
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
expandQname($qname)
expands a qualified name
parses an XML Schema, allows access to it's data, other utility methods.
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
webDescription()
prints html description of services
[nu]soapclient higher level class for easy usage.
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded')
serializes PHP values in accordance w/ section 5.
wsdl($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
if(array_key_exists('yes', $_REQUEST)) $attributes
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
getOperations($bindingType='soap')
returns an assoc array of operation names => operation data
if(php_sapi_name() !='cli') $in
serialize()
serialize a fault
expandEntities($val)
expands entities, e.g.
serializeRPCParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
parse_request($message)
Parses a request message string into a request object.
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace returns false if no namespace registered with the given pref...
nusoap_parser class parses SOAP XML messages into native PHP values
getOperationData($operation, $bindingType='soap')
returns an associative array of data necessary for calling an operation
if(!array_key_exists('domain', $_REQUEST)) $domain
clearDebug()
clears the current debug data for this instance
fetchWSDL($wsdl)
fetches the WSDL document and parses it