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 =
'';
1103 var $attributes =
array();
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();
1120 var $message =
array();
1121 var $defaultNamespace =
array();
1132 parent::__construct();
1133 $this->
debug(
'nusoap_xmlschema class instantiated, inside constructor');
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) {
1604 foreach ($list as $ii) {
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>';
1891 for($i=0;$i < 3; $i++){
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;
2091 $this->attributes = $attributes;
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);
2209 function setHeader($name, $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'])) {
2261 $this->setHeader(
'Host', $this->host);
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;
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;
2647 $this->password = $password;
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 =
'') {
2810 $this->setHeader(
'Content-Length', strlen(
$data));
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) .
';';
3318 $data = split(
';', $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));
3325 $domain = substr($domain, 0, strpos($domain,
';'));
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,
3362 'domain' => $domain,
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");
3693 $this->parse_request(
$data);
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");
3842 function parse_request(
$data=
'') {
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){
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);
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";
4451 if(
false == $endpoint) {
4452 if ($HTTPS ==
'1' || $HTTPS ==
'on') {
4457 $endpoint =
"$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4460 if(
false == $schemaTargetNamespace) {
4465 $this->
wsdl->serviceName = $serviceName;
4466 $this->
wsdl->endpoint = $endpoint;
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',
4487 'location'=>$endpoint,
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;
4524 var $bindings =
array();
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;
4635 $url = $list[$ii][
'location'];
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] :
'';
4851 $name = substr(strstr($name,
':'), 1);
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;
5062 $this->password = $password;
5063 $this->authtype = $authtype;
5064 $this->certRequest = $certRequest;
5067 function getBindingData($binding)
5069 if (is_array($this->bindings[$binding])) {
5070 return $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");
5250 <html><head><title>NuSOAP: '.$this->serviceName.
'</title> 5251 <style type="text/css"> 5252 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } 5253 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } 5254 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} 5255 ul { margin-top: 10px; margin-left: 20px; } 5256 li { list-style-type: none; margin-top: 10px; color: #000000; } 5258 margin-left: 0px; padding-bottom: 2em; } 5260 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; 5261 margin-top: 10px; margin-left: 0px; color: #000000; 5262 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } 5264 font-family: arial; font-size: 26px; color: #ffffff; 5265 background-color: #999999; width: 105%; margin-left: 0px; 5266 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;} 5268 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; 5269 font-family: arial; overflow: hidden; width: 600; 5270 padding: 20px; font-size: 10px; background-color: #999999; 5271 layer-background-color:#FFFFFF; } 5272 a,a:active { color: charcoal; font-weight: bold; } 5273 a:visited { color: #666666; font-weight: bold; } 5274 a:hover { color: cc3300; font-weight: bold; } 5276 <script language="JavaScript" type="text/javascript"> 5278 // POP-UP CAPTIONS... 5279 function lib_bwcheck(){ //Browsercheck (needed) 5280 this.ver=navigator.appVersion 5281 this.agent=navigator.userAgent 5282 this.dom=document.getElementById?1:0 5283 this.opera5=this.agent.indexOf("Opera 5")>-1 5284 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; 5285 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; 5286 this.ie4=(document.all && !this.dom && !this.opera5)?1:0; 5287 this.ie=this.ie4||this.ie5||this.ie6 5288 this.mac=this.agent.indexOf("Mac")>-1 5289 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; 5290 this.ns4=(document.layers && !this.dom)?1:0; 5291 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) 5294 var bw = new lib_bwcheck() 5295 //Makes crossbrowser object. 5296 function makeObj(obj){ 5297 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; 5298 if(!this.evnt) return false 5299 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; 5300 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; 5301 this.writeIt=b_writeIt; 5304 // A unit of measure that will be added when setting the position of a layer. 5305 //var px = bw.ns4||window.opera?"":"px"; 5306 function b_writeIt(text){ 5307 if (bw.ns4){this.wref.write(text);this.wref.close()} 5308 else this.wref.innerHTML = text 5310 //Shows the messages 5312 function popup(divid){ 5313 if(oDesc = new makeObj(divid)){ 5314 oDesc.css.visibility = "visible" 5317 function popout(){ // Hides message 5318 if(oDesc) oDesc.css.visibility = "hidden" 5326 <div class=title>'.$this->serviceName.
'</div> 5328 <p>View the <a href="'.$PHP_SELF.
'?wsdl">WSDL</a> for the service. 5329 Click on an operation name to view it's details.</p> 5331 foreach($this->getOperations() as $op =>
$data){
5332 $b .=
"<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5334 $b .=
"<div id='$op' class='hidden'> 5335 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5336 foreach(
$data as $donnie => $marie){
5337 if($donnie ==
'input' || $donnie ==
'output'){
5338 $b .=
"<font color='white'>".ucfirst($donnie).
':</font><br>';
5339 foreach($marie as $captain => $tenille){
5340 if($captain ==
'parts'){
5341 $b .=
" $captain:<br>";
5343 foreach($tenille as $joanie => $chachi){
5344 $b .=
" $joanie: $chachi<br>";
5348 $b .=
" $captain: $tenille<br>";
5352 $b .=
"<font color='white'>".ucfirst($donnie).
":</font> $marie<br>";
5360 </div></body></html>';
5373 $xml =
'<?xml version="1.0" encoding="ISO-8859-1"?>';
5374 $xml .=
"\n<definitions";
5375 foreach($this->namespaces as $k => $v) {
5376 $xml .=
" xmlns:$k=\"$v\"";
5379 if (isset($this->namespaces[
'wsdl'])) {
5380 $xml .=
" xmlns=\"" . $this->namespaces[
'wsdl'] .
"\"";
5382 if (isset($this->namespaces[
'tns'])) {
5383 $xml .=
" targetNamespace=\"" . $this->namespaces[
'tns'] .
"\"";
5387 if (
sizeof($this->
import) > 0) {
5388 foreach($this->
import as $ns => $list) {
5389 foreach ($list as $ii) {
5390 if ($ii[
'location'] !=
'') {
5391 $xml .=
'<import location="' . $ii[
'location'] .
'" namespace="' . $ns .
'" />';
5393 $xml .=
'<import namespace="' . $ns .
'" />';
5399 if (count($this->schemas)>=1) {
5400 $xml .=
"\n<types>\n";
5401 foreach ($this->schemas as $ns => $list) {
5402 foreach ($list as $xs) {
5403 $xml .= $xs->serializeSchema();
5409 if (count($this->messages) >= 1) {
5410 foreach($this->messages as $msgName => $msgParts) {
5411 $xml .=
"\n<message name=\"" . $msgName .
'">';
5412 if(is_array($msgParts)){
5413 foreach($msgParts as $partName => $partType) {
5415 if (strpos($partType,
':')) {
5417 } elseif (isset($this->typemap[$this->namespaces[
'xsd']][$partType])) {
5419 $typePrefix =
'xsd';
5421 foreach($this->typemap as $ns => $types) {
5422 if (isset($types[$partType])) {
5426 if (!isset($typePrefix)) {
5427 die(
"$partType has no namespace!");
5432 $typeDef = $this->getTypeDef($localPart, $ns);
5433 if ($typeDef[
'typeClass'] ==
'element') {
5434 $elementortype =
'element';
5435 if (substr($localPart, -1) ==
'^') {
5436 $localPart = substr($localPart, 0, -1);
5439 $elementortype =
'type';
5441 $xml .=
"\n" .
' <part name="' . $partName .
'" ' . $elementortype .
'="' . $typePrefix .
':' . $localPart .
'" />';
5444 $xml .=
'</message>';
5448 if (count($this->bindings) >= 1) {
5451 foreach($this->bindings as $bindingName => $attrs) {
5452 $binding_xml .=
"\n<binding name=\"" . $bindingName .
'" type="tns:' . $attrs[
'portType'] .
'">';
5453 $binding_xml .=
"\n" .
' <soap:binding style="' . $attrs[
'style'] .
'" transport="' . $attrs[
'transport'] .
'"/>';
5454 $portType_xml .=
"\n<portType name=\"" . $attrs[
'portType'] .
'">';
5455 foreach($attrs[
'operations'] as $opName => $opParts) {
5456 $binding_xml .=
"\n" .
' <operation name="' . $opName .
'">';
5457 $binding_xml .=
"\n" .
' <soap:operation soapAction="' . $opParts[
'soapAction'] .
'" style="'. $opParts[
'style'] .
'"/>';
5458 if (isset($opParts[
'input'][
'encodingStyle']) && $opParts[
'input'][
'encodingStyle'] !=
'') {
5459 $enc_style =
' encodingStyle="' . $opParts[
'input'][
'encodingStyle'] .
'"';
5463 $binding_xml .=
"\n" .
' <input><soap:body use="' . $opParts[
'input'][
'use'] .
'" namespace="' . $opParts[
'input'][
'namespace'] .
'"' . $enc_style .
'/></input>';
5464 if (isset($opParts[
'output'][
'encodingStyle']) && $opParts[
'output'][
'encodingStyle'] !=
'') {
5465 $enc_style =
' encodingStyle="' . $opParts[
'output'][
'encodingStyle'] .
'"';
5469 $binding_xml .=
"\n" .
' <output><soap:body use="' . $opParts[
'output'][
'use'] .
'" namespace="' . $opParts[
'output'][
'namespace'] .
'"' . $enc_style .
'/></output>';
5470 $binding_xml .=
"\n" .
' </operation>';
5471 $portType_xml .=
"\n" .
' <operation name="' . $opParts[
'name'] .
'"';
5472 if (isset($opParts[
'parameterOrder'])) {
5473 $portType_xml .=
' parameterOrder="' . $opParts[
'parameterOrder'] .
'"';
5475 $portType_xml .=
'>';
5476 if(isset($opParts[
'documentation']) && $opParts[
'documentation'] !=
'') {
5477 $portType_xml .=
"\n" .
' <documentation>' . htmlspecialchars($opParts[
'documentation']) .
'</documentation>';
5479 $portType_xml .=
"\n" .
' <input message="tns:' . $opParts[
'input'][
'message'] .
'"/>';
5480 $portType_xml .=
"\n" .
' <output message="tns:' . $opParts[
'output'][
'message'] .
'"/>';
5481 $portType_xml .=
"\n" .
' </operation>';
5483 $portType_xml .=
"\n" .
'</portType>';
5484 $binding_xml .=
"\n" .
'</binding>';
5486 $xml .= $portType_xml . $binding_xml;
5489 $xml .=
"\n<service name=\"" . $this->serviceName .
'">';
5490 if (count($this->ports) >= 1) {
5491 foreach($this->ports as $pName => $attrs) {
5492 $xml .=
"\n" .
' <port name="' . $pName .
'" binding="tns:' . $attrs[
'binding'] .
'">';
5493 $xml .=
"\n" .
' <soap:address location="' . $attrs[
'location'] . ($debug ?
'?debug=1' :
'') .
'"/>';
5494 $xml .=
"\n" .
' </port>';
5497 $xml .=
"\n" .
'</service>';
5498 return $xml .
"\n</definitions>";
5510 function parametersMatchWrapped($type, &$parameters) {
5511 $this->
debug(
"in parametersMatchWrapped type=$type, parameters=");
5515 if (strpos($type,
':')) {
5516 $uqType = substr($type, strrpos($type,
':') + 1);
5517 $ns = substr($type, 0, strrpos($type,
':'));
5518 $this->
debug(
"in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5521 $this->
debug(
"in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5526 $this->
debug(
"in parametersMatchWrapped: No namespace for type $type");
5532 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5533 $this->
debug(
"in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5536 $this->
debug(
"in parametersMatchWrapped: found typeDef=");
5538 if (substr($uqType, -1) ==
'^') {
5539 $uqType = substr($uqType, 0, -1);
5541 $phpType = $typeDef[
'phpType'];
5542 $arrayType = (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'');
5543 $this->
debug(
"in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5546 if ($phpType !=
'struct') {
5547 $this->
debug(
"in parametersMatchWrapped: not a struct");
5552 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
5556 if ($this->
isArraySimpleOrStruct($parameters) ==
'arraySimple' && count($parameters) == count($typeDef[
'elements'])) {
5557 $this->
debug(
"in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5560 foreach ($typeDef[
'elements'] as $name => $attrs) {
5562 $this->
debug(
"in parametersMatchWrapped: change parameter $element to name $name");
5563 $parameters[$name] = $parameters[$elements];
5564 unset($parameters[$elements]);
5566 } elseif (isset($parameters[$name])) {
5567 $this->
debug(
"in parametersMatchWrapped: have parameter named $name");
5570 $this->
debug(
"in parametersMatchWrapped: do not have parameter named $name");
5575 $this->
debug(
"in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5576 if ($matches == 0) {
5584 $this->
debug(
"in parametersMatchWrapped: no elements type $ns:$uqType");
5585 return count($parameters) == 0;
5603 function serializeRPCParameters($operation, $direction, $parameters, $bindingType =
'soap') {
5604 $this->
debug(
"in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5607 if ($direction !=
'input' && $direction !=
'output') {
5608 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5609 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5612 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5613 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5614 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation .
' bindingType: ' . $bindingType);
5617 $this->
debug(
'in serializeRPCParameters: opData:');
5621 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5622 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5623 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5624 $enc_style = $encodingStyle;
5629 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5630 $parts = &$opData[$direction][
'parts'];
5631 $part_count =
sizeof($parts);
5632 $style = $opData[
'style'];
5633 $use = $opData[$direction][
'use'];
5634 $this->
debug(
"have $part_count part(s) to serialize using $style/$use");
5635 if (is_array($parameters)) {
5637 $parameter_count = count($parameters);
5638 $this->
debug(
"have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5640 if (
$style ==
'document' && $use ==
'literal' && $part_count == 1 && isset($parts[
'parameters'])) {
5641 $this->
debug(
'check whether the caller has wrapped the parameters');
5642 if ((($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters[
'parameters'])) || ($direction ==
'output' && $parametersArrayType ==
'arraySimple' && $parameter_count == 1)) {
5643 $this->
debug(
'check whether caller\'s parameters match the wrapped ones');
5644 if ($this->parametersMatchWrapped($parts[
'parameters'], $parameters)) {
5645 $this->
debug(
'wrap the parameters for the caller');
5646 $parameters =
array(
'parameters' => $parameters);
5647 $parameter_count = 1;
5651 foreach ($parts as $name => $type) {
5652 $this->
debug(
"serializing part $name of type $type");
5654 if (isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5655 $encodingStyle = $opData[$direction][
'encodingStyle'];
5656 $enc_style = $encodingStyle;
5662 if ($parametersArrayType ==
'arraySimple') {
5663 $p = array_shift($parameters);
5664 $this->
debug(
'calling serializeType w/indexed param');
5665 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5666 } elseif (isset($parameters[$name])) {
5667 $this->
debug(
'calling serializeType w/named param');
5668 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5671 $this->
debug(
'calling serializeType w/null param');
5672 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5676 $this->
debug(
'no parameters passed.');
5679 $this->
debug(
"serializeRPCParameters returning: $xml");
5697 function serializeParameters($operation, $direction, $parameters)
5699 $this->
debug(
"in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5702 if ($direction !=
'input' && $direction !=
'output') {
5703 $this->
debug(
'The value of the \$direction argument needs to be either "input" or "output"');
5704 $this->
setError(
'The value of the \$direction argument needs to be either "input" or "output"');
5707 if (!$opData = $this->getOperationData($operation)) {
5708 $this->
debug(
'Unable to retrieve WSDL data for operation: ' . $operation);
5709 $this->
setError(
'Unable to retrieve WSDL data for operation: ' . $operation);
5712 $this->
debug(
'opData:');
5716 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
5717 if(($direction ==
'input') && isset($opData[
'output'][
'encodingStyle']) && ($opData[
'output'][
'encodingStyle'] != $encodingStyle)) {
5718 $encodingStyle = $opData[
'output'][
'encodingStyle'];
5719 $enc_style = $encodingStyle;
5724 if (isset($opData[$direction][
'parts']) &&
sizeof($opData[$direction][
'parts']) > 0) {
5726 $use = $opData[$direction][
'use'];
5727 $this->
debug(
"use=$use");
5728 $this->
debug(
'got ' . count($opData[$direction][
'parts']) .
' part(s)');
5729 if (is_array($parameters)) {
5731 $this->
debug(
'have ' . $parametersArrayType .
' parameters');
5732 foreach($opData[$direction][
'parts'] as $name => $type) {
5733 $this->
debug(
'serializing part "'.$name.
'" of type "'.$type.
'"');
5735 if(isset($opData[$direction][
'encodingStyle']) && $encodingStyle != $opData[$direction][
'encodingStyle']) {
5736 $encodingStyle = $opData[$direction][
'encodingStyle'];
5737 $enc_style = $encodingStyle;
5743 if ($parametersArrayType ==
'arraySimple') {
5744 $p = array_shift($parameters);
5745 $this->
debug(
'calling serializeType w/indexed param');
5746 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5747 } elseif (isset($parameters[$name])) {
5748 $this->
debug(
'calling serializeType w/named param');
5749 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5752 $this->
debug(
'calling serializeType w/null param');
5753 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5757 $this->
debug(
'no parameters passed.');
5760 $this->
debug(
"serializeParameters returning: $xml");
5776 function serializeType($name, $type, $value, $use=
'encoded', $encodingStyle=
false, $unqualified=
false)
5778 $this->
debug(
"in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ?
"unqualified" :
"qualified"));
5780 if($use ==
'encoded' && $encodingStyle) {
5781 $encodingStyle =
' SOAP-ENV:encodingStyle="' . $encodingStyle .
'"';
5785 if (is_object($value) && get_class($value) ==
'soapval') {
5786 if ($value->type_ns) {
5787 $type = $value->type_ns .
':' . $value->type;
5789 $this->
debug(
"in serializeType: soapval overrides type to $type");
5790 } elseif ($value->type) {
5791 $type = $value->type;
5793 $this->
debug(
"in serializeType: soapval overrides type to $type");
5796 $this->
debug(
"in serializeType: soapval does not override type");
5798 $attrs = $value->attributes;
5799 $value = $value->value;
5800 $this->
debug(
"in serializeType: soapval overrides value to $value");
5802 if (!is_array($value)) {
5803 $value[
'!'] = $value;
5805 foreach ($attrs as
$n => $v) {
5806 $value[
'!' .
$n] = $v;
5808 $this->
debug(
"in serializeType: soapval provides attributes");
5815 if (strpos($type,
':')) {
5816 $uqType = substr($type, strrpos($type,
':') + 1);
5817 $ns = substr($type, 0, strrpos($type,
':'));
5818 $this->
debug(
"in serializeType: got a prefixed type: $uqType, $ns");
5821 $this->
debug(
"in serializeType: expanded prefixed type: $uqType, $ns");
5824 if($ns == $this->XMLSchemaVersion || $ns ==
'http://schemas.xmlsoap.org/soap/encoding/'){
5825 $this->
debug(
'in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5826 if ($unqualified && $use ==
'literal') {
5827 $elementNS =
" xmlns=\"\"";
5831 if (is_null($value)) {
5832 if ($use ==
'literal') {
5834 $xml =
"<$name$elementNS/>";
5837 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5839 $this->
debug(
"in serializeType: returning: $xml");
5842 if ($uqType ==
'Array') {
5844 return $this->
serialize_val($value, $name,
false,
false,
false,
false, $use);
5846 if ($uqType ==
'boolean') {
5847 if ((is_string($value) && $value ==
'false') || (! $value)) {
5853 if ($uqType ==
'string' && gettype($value) ==
'string') {
5856 if (($uqType ==
'long' || $uqType ==
'unsignedLong') && gettype($value) ==
'double') {
5857 $value = sprintf(
"%.0lf", $value);
5862 if (!$this->getTypeDef($uqType, $ns)) {
5863 if ($use ==
'literal') {
5865 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
5867 $xml =
"<$name$elementNS>$value</$name>";
5870 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
5872 $this->
debug(
"in serializeType: returning: $xml");
5875 $this->
debug(
'custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5876 }
else if ($ns ==
'http://xml.apache.org/xml-soap') {
5877 $this->
debug(
'in serializeType: appears to be Apache SOAP type');
5878 if ($uqType ==
'Map') {
5881 $this->
debug(
'in serializeType: Add namespace for Apache SOAP type');
5882 $tt_prefix =
'ns' . rand(1000, 9999);
5883 $this->namespaces[$tt_prefix] =
'http://xml.apache.org/xml-soap';
5888 foreach($value as $k => $v) {
5889 $this->
debug(
"serializing map element: key $k, value $v");
5895 if ($use ==
'literal') {
5897 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\">$contents</$name>";
5899 $xml =
"<$name>$contents</$name>";
5902 $xml =
"<$name xsi:type=\"" . $tt_prefix .
":$uqType\"$encodingStyle>$contents</$name>";
5904 $this->
debug(
"in serializeType: returning: $xml");
5907 $this->
debug(
'in serializeType: Apache SOAP type, but only support Map');
5912 $this->
debug(
"in serializeType: No namespace for type $type");
5916 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5917 $this->
setError(
"$type ($uqType) is not a supported type.");
5918 $this->
debug(
"in serializeType: $type ($uqType) is not a supported type.");
5921 $this->
debug(
"in serializeType: found typeDef");
5923 if (substr($uqType, -1) ==
'^') {
5924 $uqType = substr($uqType, 0, -1);
5927 $phpType = $typeDef[
'phpType'];
5928 $this->
debug(
"in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef[
'arrayType']) ? $typeDef[
'arrayType'] :
'') );
5930 if ($phpType ==
'struct') {
5931 if (isset($typeDef[
'typeClass']) && $typeDef[
'typeClass'] ==
'element') {
5932 $elementName = $uqType;
5933 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5934 $elementNS =
" xmlns=\"$ns\"";
5936 $elementNS =
" xmlns=\"\"";
5939 $elementName = $name;
5941 $elementNS =
" xmlns=\"\"";
5946 if (is_null($value)) {
5947 if ($use ==
'literal') {
5949 $xml =
"<$elementName$elementNS/>";
5951 $xml =
"<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"/>";
5953 $this->
debug(
"in serializeType: returning: $xml");
5956 if (is_object($value)) {
5957 $value = get_object_vars($value);
5959 if (is_array($value)) {
5960 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5961 if ($use ==
'literal') {
5963 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">";
5965 $xml =
"<$elementName$elementNS$elementAttrs>";
5968 $xml =
"<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>";
5971 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5972 $xml .=
"</$elementName>";
5974 $this->
debug(
"in serializeType: phpType is struct, but value is not an array");
5975 $this->
setError(
"phpType is struct, but value is not an array: see debug output for details");
5978 } elseif ($phpType ==
'array') {
5979 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
5980 $elementNS =
" xmlns=\"$ns\"";
5983 $elementNS =
" xmlns=\"\"";
5988 if (is_null($value)) {
5989 if ($use ==
'literal') {
5991 $xml =
"<$name$elementNS/>";
5993 $xml =
"<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6002 $this->
debug(
"in serializeType: returning: $xml");
6005 if (isset($typeDef[
'multidimensional'])) {
6007 foreach($value as $v) {
6008 $cols =
',' .
sizeof($v);
6009 $nv = array_merge($nv, $v);
6015 if (is_array($value) &&
sizeof($value) >= 1) {
6016 $rows =
sizeof($value);
6018 foreach($value as $k => $v) {
6019 $this->
debug(
"serializing array element: $k, $v of type: $typeDef[arrayType]");
6021 if (!in_array($typeDef[
'arrayType'],$this->typemap[
'http://www.w3.org/2001/XMLSchema'])) {
6022 $contents .= $this->serializeType(
'item', $typeDef[
'arrayType'], $v, $use);
6024 $contents .= $this->
serialize_val($v,
'item', $typeDef[
'arrayType'], null, $this->XMLSchemaVersion,
false, $use);
6033 if ($use ==
'literal') {
6034 $xml =
"<$name$elementNS>" 6038 $xml =
"<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace(
'http://schemas.xmlsoap.org/soap/encoding/').
':Array" '.
6041 .$this->getPrefixFromNamespace($this->
getPrefix($typeDef[
'arrayType']))
6042 .
":".$this->
getLocalPart($typeDef[
'arrayType']).
"[$rows$cols]\">" 6046 } elseif ($phpType ==
'scalar') {
6047 if (isset($typeDef[
'form']) && ($typeDef[
'form'] ==
'qualified')) {
6048 $elementNS =
" xmlns=\"$ns\"";
6051 $elementNS =
" xmlns=\"\"";
6056 if ($use ==
'literal') {
6058 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\">$value</$name>";
6060 $xml =
"<$name$elementNS>$value</$name>";
6063 $xml =
"<$name$elementNS xsi:type=\"" . $this->
getPrefixFromNamespace($ns) .
":$uqType\"$encodingStyle>$value</$name>";
6066 $this->
debug(
"in serializeType: returning: $xml");
6080 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6082 if (isset($typeDef[
'attrs']) && is_array($typeDef[
'attrs'])) {
6083 $this->
debug(
"serialize attributes for XML Schema type $ns:$uqType");
6084 if (is_array($value)) {
6086 } elseif (is_object($value)) {
6087 $xvalue = get_object_vars($value);
6089 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6092 foreach ($typeDef[
'attrs'] as $aName => $attrs) {
6093 if (isset($xvalue[
'!' . $aName])) {
6094 $xname =
'!' . $aName;
6095 $this->
debug(
"value provided for attribute $aName with key $xname");
6096 } elseif (isset($xvalue[$aName])) {
6098 $this->
debug(
"value provided for attribute $aName with key $xname");
6099 } elseif (isset($attrs[
'default'])) {
6100 $xname =
'!' . $aName;
6101 $xvalue[$xname] = $attrs[
'default'];
6102 $this->
debug(
'use default value of ' . $xvalue[$aName] .
' for attribute ' . $aName);
6105 $this->
debug(
"no value provided for attribute $aName");
6108 $xml .=
" $aName=\"" . $this->
expandEntities($xvalue[$xname]) .
"\"";
6112 $this->
debug(
"no attributes to serialize for XML Schema type $ns:$uqType");
6114 if (isset($typeDef[
'extensionBase'])) {
6115 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6116 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6120 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6121 $this->
debug(
"serialize attributes for extension base $ns:$uqType");
6122 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6124 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6142 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use=
'encoded', $encodingStyle=
false) {
6144 if (isset($typeDef[
'elements']) && is_array($typeDef[
'elements'])) {
6145 $this->
debug(
"in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6146 if (is_array($value)) {
6148 } elseif (is_object($value)) {
6149 $xvalue = get_object_vars($value);
6151 $this->
debug(
"value is neither an array nor an object for XML Schema type $ns:$uqType");
6155 if (count($typeDef[
'elements']) != count($xvalue)){
6158 foreach ($typeDef[
'elements'] as $eName => $attrs) {
6159 if (!isset($xvalue[$eName])) {
6160 if (isset($attrs[
'default'])) {
6161 $xvalue[$eName] = $attrs[
'default'];
6162 $this->
debug(
'use default value of ' . $xvalue[$eName] .
' for element ' . $eName);
6166 if (isset($optionals)
6167 && (!isset($xvalue[$eName]))
6168 && ( (!isset($attrs[
'nillable'])) || $attrs[
'nillable'] !=
'true')
6170 if (isset($attrs[
'minOccurs']) && $attrs[
'minOccurs'] <>
'0') {
6171 $this->
debug(
"apparent error: no value provided for element $eName with minOccurs=" . $attrs[
'minOccurs']);
6174 $this->
debug(
"no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6177 if (isset($xvalue[$eName])) {
6178 $v = $xvalue[$eName];
6182 if (isset($attrs[
'form'])) {
6183 $unqualified = ($attrs[
'form'] ==
'unqualified');
6185 $unqualified =
false;
6187 if (isset($attrs[
'maxOccurs']) && ($attrs[
'maxOccurs'] ==
'unbounded' || $attrs[
'maxOccurs'] > 1) && isset($v) && is_array($v) && $this->
isArraySimpleOrStruct($v) ==
'arraySimple') {
6189 foreach ($vv as $k => $v) {
6190 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6192 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6195 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6196 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6200 if (isset($attrs[
'type']) || isset($attrs[
'ref'])) {
6202 $xml .= $this->serializeType($eName, isset($attrs[
'type']) ? $attrs[
'type'] : $attrs[
'ref'], $v, $use, $encodingStyle, $unqualified);
6205 $this->
debug(
"calling serialize_val() for $v, $eName, false, false, false, false, $use");
6206 $xml .= $this->
serialize_val($v, $eName,
false,
false,
false,
false, $use);
6212 $this->
debug(
"no elements to serialize for XML Schema type $ns:$uqType");
6214 if (isset($typeDef[
'extensionBase'])) {
6215 $ns = $this->
getPrefix($typeDef[
'extensionBase']);
6216 $uqType = $this->
getLocalPart($typeDef[
'extensionBase']);
6220 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6221 $this->
debug(
"serialize elements for extension base $ns:$uqType");
6222 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6224 $this->
debug(
"extension base $ns:$uqType is not a supported type");
6244 function addComplexType($name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',$elements=
array(),$attrs=
array(),$arrayType=
'') {
6245 if (count($elements) > 0) {
6246 $eElements =
array();
6247 foreach($elements as
$n => $e){
6250 foreach ($e as $k => $v) {
6251 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6252 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6255 $eElements[
$n] = $ee;
6257 $elements = $eElements;
6260 if (count($attrs) > 0) {
6261 foreach($attrs as
$n => $a){
6263 foreach ($a as $k => $v) {
6264 $k = strpos($k,
':') ? $this->
expandQname($k) : $k;
6265 $v = strpos($v,
':') ? $this->
expandQname($v) : $v;
6273 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6274 $arrayType = strpos($arrayType,
':') ? $this->
expandQname($arrayType) : $arrayType;
6276 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6277 $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6291 function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=
array()) {
6292 $restrictionBase = strpos($restrictionBase,
':') ? $this->
expandQname($restrictionBase) : $restrictionBase;
6294 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6295 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6305 function addElement($attrs) {
6306 $typens = isset($this->namespaces[
'types']) ? $this->namespaces[
'types'] : $this->namespaces[
'tns'];
6307 $this->schemas[$typens][0]->addElement($attrs);
6324 function addOperation($name, $in =
false,
$out =
false,
$namespace =
false, $soapaction =
false,
$style =
'rpc', $use =
'encoded', $documentation =
'', $encodingStyle =
''){
6325 if ($use ==
'encoded' && $encodingStyle ==
'') {
6326 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
6329 if (
$style ==
'document') {
6330 $elements =
array();
6331 foreach ($in as
$n =>
$t) {
6332 $elements[
$n] =
array(
'name' =>
$n,
'type' =>
$t);
6334 $this->addComplexType($name .
'RequestType',
'complexType',
'struct',
'all',
'', $elements);
6335 $this->addElement(
array(
'name' => $name,
'type' => $name .
'RequestType'));
6336 $in =
array(
'parameters' =>
'tns:' . $name .
'^');
6338 $elements =
array();
6340 $elements[
$n] =
array(
'name' =>
$n,
'type' =>
$t);
6342 $this->addComplexType($name .
'ResponseType',
'complexType',
'struct',
'all',
'', $elements);
6343 $this->addElement(
array(
'name' => $name .
'Response',
'type' => $name .
'ResponseType',
'form' =>
'qualified'));
6344 $out =
array(
'parameters' =>
'tns:' . $name .
'Response' .
'^');
6348 $this->bindings[ $this->serviceName .
'Binding' ][
'operations'][$name] =
6351 'binding' => $this->serviceName .
'Binding',
6352 'endpoint' => $this->endpoint,
6353 'soapAction' => $soapaction,
6358 'encodingStyle' => $encodingStyle,
6359 'message' => $name .
'Request',
6364 'encodingStyle' => $encodingStyle,
6365 'message' => $name .
'Response',
6368 'transport' =>
'http://schemas.xmlsoap.org/soap/http',
6369 'documentation' => $documentation);
6374 foreach($in as $pName => $pType)
6376 if(strpos($pType,
':')) {
6379 $this->messages[$name.
'Request'][$pName] = $pType;
6382 $this->messages[$name.
'Request']=
'0';
6386 foreach(
$out as $pName => $pType)
6388 if(strpos($pType,
':')) {
6391 $this->messages[$name.
'Response'][$pName] = $pType;
6394 $this->messages[$name.
'Response']=
'0';
6415 var $xml_encoding =
'';
6417 var $root_struct =
'';
6418 var $root_struct_name =
'';
6419 var $root_struct_namespace =
'';
6420 var $root_header =
'';
6426 var $default_namespace =
'';
6428 var $message =
array();
6431 var $fault_code =
'';
6432 var $fault_str =
'';
6433 var $fault_detail =
'';
6434 var $depth_array =
array();
6435 var $debug_flag =
true;
6436 var $soapresponse = NULL;
6437 var $soapheader = NULL;
6438 var $responseHeaders =
'';
6439 var $body_position = 0;
6444 var $multirefs =
array();
6446 var $decode_utf8 =
true;
6457 function __construct($xml,$encoding=
'UTF-8',$method=
'',$decode_utf8=
true){
6458 parent::__construct();
6460 $this->xml_encoding = $encoding;
6461 $this->method = $method;
6462 $this->decode_utf8 = $decode_utf8;
6467 $pos_xml = strpos($xml,
'<?xml');
6468 if ($pos_xml !== FALSE) {
6469 $xml_decl = substr($xml, $pos_xml, strpos($xml,
'?>', $pos_xml + 2) - $pos_xml + 1);
6470 if (preg_match(
"/encoding=[\"']([^\"']*)[\"']/", $xml_decl,
$res)) {
6471 $xml_encoding =
$res[1];
6472 if (strtoupper($xml_encoding) != $encoding) {
6473 $err =
"Charset from HTTP Content-Type '" . $encoding .
"' does not match encoding from XML declaration '" . $xml_encoding .
"'";
6475 if ($encoding !=
'ISO-8859-1' || strtoupper($xml_encoding) !=
'UTF-8') {
6481 $this->
debug(
'Charset from HTTP Content-Type matches encoding from XML declaration');
6484 $this->
debug(
'No encoding specified in XML declaration');
6487 $this->
debug(
'No XML declaration');
6489 $this->
debug(
'Entering nusoap_parser(), length='.strlen($xml).
', encoding='.$encoding);
6491 $this->parser = xml_parser_create($this->xml_encoding);
6494 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6495 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6497 xml_set_object($this->parser, $this);
6499 xml_set_element_handler($this->parser,
'start_element',
'end_element');
6500 xml_set_character_data_handler($this->parser,
'character_data');
6503 if(!xml_parse($this->parser,$xml,
true)){
6505 $err = sprintf(
'XML error parsing SOAP payload on line %d: %s',
6506 xml_get_current_line_number($this->parser),
6507 xml_error_string(xml_get_error_code($this->parser)));
6509 $this->
debug(
"XML payload:\n" . $xml);
6512 $this->
debug(
'parsed successfully, found root struct: '.$this->root_struct.
' of name '.$this->root_struct_name);
6514 $this->soapresponse = $this->message[$this->root_struct][
'result'];
6516 if($this->root_header !=
'' && isset($this->message[$this->root_header][
'result'])){
6517 $this->soapheader = $this->message[$this->root_header][
'result'];
6520 if(
sizeof($this->multirefs) > 0){
6521 foreach($this->multirefs as $id => $hrefs){
6522 $this->
debug(
'resolving multirefs for id: '.$id);
6523 $idVal = $this->buildVal($this->ids[$id]);
6524 if (is_array($idVal) && isset($idVal[
'!id'])) {
6525 unset($idVal[
'!id']);
6527 foreach($hrefs as $refPos => $ref){
6528 $this->
debug(
'resolving href at pos '.$refPos);
6529 $this->multirefs[$id][$refPos] = $idVal;
6534 xml_parser_free($this->parser);
6536 $this->
debug(
'xml was empty, didn\'t parse!');
6537 $this->
setError(
'xml was empty, didn\'t parse!');
6549 function start_element($parser, $name, $attrs) {
6552 $pos = $this->position++;
6554 $this->message[$pos] =
array(
'pos' => $pos,
'children'=>
'',
'cdata'=>
'');
6557 $this->message[$pos][
'depth'] = $this->depth++;
6561 $this->message[$this->parent][
'children'] .=
'|'.$pos;
6564 $this->message[$pos][
'parent'] = $this->parent;
6568 $this->depth_array[$this->depth] = $pos;
6570 if(strpos($name,
':')){
6572 $prefix = substr($name,0,strpos($name,
':'));
6574 $name = substr(strstr($name,
':'),1);
6577 if($name ==
'Envelope'){
6578 $this->status =
'envelope';
6579 } elseif($name ==
'Header' && $this->status =
'envelope'){
6580 $this->root_header = $pos;
6581 $this->status =
'header';
6582 } elseif($name ==
'Body' && $this->status =
'envelope'){
6583 $this->status =
'body';
6584 $this->body_position = $pos;
6586 } elseif($this->status ==
'body' && $pos == ($this->body_position+1)){
6587 $this->status =
'method';
6588 $this->root_struct_name = $name;
6589 $this->root_struct = $pos;
6590 $this->message[$pos][
'type'] =
'struct';
6591 $this->
debug(
"found root struct $this->root_struct_name, pos $this->root_struct");
6594 $this->message[$pos][
'status'] = $this->status;
6596 $this->message[$pos][
'name'] = htmlspecialchars($name);
6598 $this->message[$pos][
'attrs'] = $attrs;
6602 foreach($attrs as $key => $value){
6606 if($key_prefix ==
'xmlns'){
6607 if(preg_match(
'/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6608 $this->XMLSchemaVersion = $value;
6610 $this->namespaces[
'xsi'] = $this->XMLSchemaVersion.
'-instance';
6612 $this->namespaces[$key_localpart] = $value;
6614 if($name == $this->root_struct_name){
6615 $this->methodNamespace = $value;
6618 } elseif($key_localpart ==
'type'){
6619 if (isset($this->message[$pos][
'type']) && $this->message[$pos][
'type'] ==
'array') {
6622 $value_prefix = $this->
getPrefix($value);
6624 $this->message[$pos][
'type'] = $value_localpart;
6625 $this->message[$pos][
'typePrefix'] = $value_prefix;
6626 if(isset($this->namespaces[$value_prefix])){
6627 $this->message[$pos][
'type_namespace'] = $this->namespaces[$value_prefix];
6628 }
else if(isset($attrs[
'xmlns:'.$value_prefix])) {
6629 $this->message[$pos][
'type_namespace'] = $attrs[
'xmlns:'.$value_prefix];
6633 } elseif($key_localpart ==
'arrayType'){
6634 $this->message[$pos][
'type'] =
'array';
6643 $expr =
'/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6644 if(preg_match($expr,$value,$regs)){
6645 $this->message[$pos][
'typePrefix'] = $regs[1];
6646 $this->message[$pos][
'arrayTypePrefix'] = $regs[1];
6647 if (isset($this->namespaces[$regs[1]])) {
6648 $this->message[$pos][
'arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6649 }
else if (isset($attrs[
'xmlns:'.$regs[1]])) {
6650 $this->message[$pos][
'arrayTypeNamespace'] = $attrs[
'xmlns:'.$regs[1]];
6652 $this->message[$pos][
'arrayType'] = $regs[2];
6653 $this->message[$pos][
'arraySize'] = $regs[3];
6654 $this->message[$pos][
'arrayCols'] = $regs[4];
6657 } elseif ($key_localpart ==
'nil'){
6658 $this->message[$pos][
'nil'] = ($value ==
'true' || $value ==
'1');
6660 } elseif ($key !=
'href' && $key !=
'xmlns' && $key_localpart !=
'encodingStyle' && $key_localpart !=
'root') {
6661 $this->message[$pos][
'xattrs'][
'!' . $key] = $value;
6664 if ($key ==
'xmlns') {
6665 $this->default_namespace = $value;
6669 $this->ids[$value] = $pos;
6672 if($key_localpart ==
'root' && $value == 1){
6673 $this->status =
'method';
6674 $this->root_struct_name = $name;
6675 $this->root_struct = $pos;
6676 $this->
debug(
"found root struct $this->root_struct_name, pos $pos");
6679 $attstr .=
" $key=\"$value\"";
6683 $this->message[$pos][
'namespace'] = $this->namespaces[$prefix];
6684 $this->default_namespace = $this->namespaces[$prefix];
6686 $this->message[$pos][
'namespace'] = $this->default_namespace;
6688 if($this->status ==
'header'){
6689 if ($this->root_header != $pos) {
6690 $this->responseHeaders .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6692 } elseif($this->root_struct_name !=
''){
6693 $this->document .=
"<" . (isset($prefix) ? $prefix .
':' :
'') .
"$name$attstr>";
6704 function end_element($parser, $name) {
6706 $pos = $this->depth_array[$this->depth--];
6709 if(strpos($name,
':')){
6711 $prefix = substr($name,0,strpos($name,
':'));
6713 $name = substr(strstr($name,
':'),1);
6717 if(isset($this->body_position) && $pos > $this->body_position){
6719 if(isset($this->message[$pos][
'attrs'][
'href'])){
6721 $id = substr($this->message[$pos][
'attrs'][
'href'],1);
6723 $this->multirefs[$id][$pos] =
'placeholder';
6725 $this->message[$pos][
'result'] =& $this->multirefs[$id][$pos];
6727 } elseif($this->message[$pos][
'children'] !=
''){
6729 if(!isset($this->message[$pos][
'result'])){
6730 $this->message[$pos][
'result'] = $this->buildVal($pos);
6733 } elseif (isset($this->message[$pos][
'xattrs'])) {
6734 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6735 $this->message[$pos][
'xattrs'][
'!'] = null;
6736 } elseif (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6737 if (isset($this->message[$pos][
'type'])) {
6738 $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'] :
'');
6740 $parent = $this->message[$pos][
'parent'];
6741 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6742 $this->message[$pos][
'xattrs'][
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6744 $this->message[$pos][
'xattrs'][
'!'] = $this->message[$pos][
'cdata'];
6748 $this->message[$pos][
'result'] = $this->message[$pos][
'xattrs'];
6752 if (isset($this->message[$pos][
'nil']) && $this->message[$pos][
'nil']) {
6753 $this->message[$pos][
'xattrs'][
'!'] = null;
6754 } elseif (isset($this->message[$pos][
'type'])) {
6755 $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'] :
'');
6757 $parent = $this->message[$pos][
'parent'];
6758 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6759 $this->message[$pos][
'result'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
6761 $this->message[$pos][
'result'] = $this->message[$pos][
'cdata'];
6779 if($this->status ==
'header'){
6780 if ($this->root_header != $pos) {
6781 $this->responseHeaders .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6783 } elseif($pos >= $this->root_struct){
6784 $this->document .=
"</" . (isset($prefix) ? $prefix .
':' :
'') .
"$name>";
6787 if($pos == $this->root_struct){
6788 $this->status =
'body';
6789 $this->root_struct_namespace = $this->message[$pos][
'namespace'];
6790 } elseif($name ==
'Body'){
6791 $this->status =
'envelope';
6792 } elseif($name ==
'Header'){
6793 $this->status =
'envelope';
6794 } elseif($name ==
'Envelope'){
6798 $this->
parent = $this->message[$pos][
'parent'];
6808 function character_data($parser,
$data){
6809 $pos = $this->depth_array[$this->depth];
6810 if ($this->xml_encoding==
'UTF-8'){
6814 if($this->decode_utf8){
6818 $this->message[$pos][
'cdata'] .=
$data;
6820 if($this->status ==
'header'){
6821 $this->responseHeaders .=
$data;
6823 $this->document .=
$data;
6834 function get_response(){
6835 return $this->soapresponse;
6844 function get_soapbody(){
6845 return $this->soapresponse;
6854 function get_soapheader(){
6855 return $this->soapheader;
6864 function getHeaders(){
6865 return $this->responseHeaders;
6877 function decodeSimple($value, $type, $typens) {
6879 if ((!isset($type)) || $type ==
'string' || $type ==
'long' || $type ==
'unsignedLong') {
6880 return (
string) $value;
6882 if ($type ==
'int' || $type ==
'integer' || $type ==
'short' || $type ==
'byte') {
6883 return (
int) $value;
6885 if ($type ==
'float' || $type ==
'double' || $type ==
'decimal') {
6886 return (
double) $value;
6888 if ($type ==
'boolean') {
6889 if (strtolower($value) ==
'false' || strtolower($value) ==
'f') {
6892 return (
boolean) $value;
6894 if ($type ==
'base64' || $type ==
'base64Binary') {
6895 $this->
debug(
'Decode base64 value');
6896 return base64_decode($value);
6899 if ($type ==
'nonPositiveInteger' || $type ==
'negativeInteger' 6900 || $type ==
'nonNegativeInteger' || $type ==
'positiveInteger' 6901 || $type ==
'unsignedInt' 6902 || $type ==
'unsignedShort' || $type ==
'unsignedByte') {
6903 return (
int) $value;
6906 if ($type ==
'array') {
6910 return (
string) $value;
6921 function buildVal($pos){
6922 if(!isset($this->message[$pos][
'type'])){
6923 $this->message[$pos][
'type'] =
'';
6925 $this->
debug(
'in buildVal() for '.$this->message[$pos][
'name'].
"(pos $pos) of type ".$this->message[$pos][
'type']);
6927 if($this->message[$pos][
'children'] !=
''){
6928 $this->
debug(
'in buildVal, there are children');
6929 $children = explode(
'|',$this->message[$pos][
'children']);
6930 array_shift($children);
6932 if(isset($this->message[$pos][
'arrayCols']) && $this->message[$pos][
'arrayCols'] !=
''){
6935 foreach($children as $child_pos){
6936 $this->
debug(
"in buildVal, got an MD array element: $r, $c");
6937 $params[
$r][] = $this->message[$child_pos][
'result'];
6939 if($c == $this->message[$pos][
'arrayCols']){
6945 } elseif($this->message[$pos][
'type'] ==
'array' || $this->message[$pos][
'type'] ==
'Array'){
6946 $this->
debug(
'in buildVal, adding array '.$this->message[$pos][
'name']);
6947 foreach($children as $child_pos){
6948 $params[] = &$this->message[$child_pos][
'result'];
6951 } elseif($this->message[$pos][
'type'] ==
'Map' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap'){
6952 $this->
debug(
'in buildVal, Java Map '.$this->message[$pos][
'name']);
6953 foreach($children as $child_pos){
6954 $kv = explode(
"|",$this->message[$child_pos][
'children']);
6955 $params[$this->message[$kv[1]][
'result']] = &$this->message[$kv[2]][
'result'];
6961 $this->
debug(
'in buildVal, adding Java Vector or generic compound type '.$this->message[$pos][
'name']);
6962 if ($this->message[$pos][
'type'] ==
'Vector' && $this->message[$pos][
'type_namespace'] ==
'http://xml.apache.org/xml-soap') {
6968 foreach($children as $child_pos){
6970 $params[] = &$this->message[$child_pos][
'result'];
6972 if (isset(
$params[$this->message[$child_pos][
'name']])) {
6974 if ((!is_array(
$params[$this->message[$child_pos][
'name']])) || (!isset(
$params[$this->message[$child_pos][
'name']][0]))) {
6975 $params[$this->message[$child_pos][
'name']] =
array(
$params[$this->message[$child_pos][
'name']]);
6977 $params[$this->message[$child_pos][
'name']][] = &$this->message[$child_pos][
'result'];
6979 $params[$this->message[$child_pos][
'name']] = &$this->message[$child_pos][
'result'];
6984 if (isset($this->message[$pos][
'xattrs'])) {
6985 $this->
debug(
'in buildVal, handling attributes');
6986 foreach ($this->message[$pos][
'xattrs'] as
$n => $v) {
6991 if (isset($this->message[$pos][
'cdata']) && trim($this->message[$pos][
'cdata']) !=
'') {
6992 $this->
debug(
'in buildVal, handling simpleContent');
6993 if (isset($this->message[$pos][
'type'])) {
6994 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
6996 $parent = $this->message[$pos][
'parent'];
6997 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
6998 $params[
'!'] = $this->decodeSimple($this->message[$pos][
'cdata'], $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7000 $params[
'!'] = $this->message[$pos][
'cdata'];
7005 $this->
debug(
'in buildVal, return:');
7009 $this->
debug(
'in buildVal, no children, building scalar');
7010 $cdata = isset($this->message[$pos][
'cdata']) ? $this->message[$pos][
'cdata'] :
'';
7011 if (isset($this->message[$pos][
'type'])) {
7012 $ret = $this->decodeSimple($cdata, $this->message[$pos][
'type'], isset($this->message[$pos][
'type_namespace']) ? $this->message[$pos][
'type_namespace'] :
'');
7013 $this->
debug(
"in buildVal, return: $ret");
7016 $parent = $this->message[$pos][
'parent'];
7017 if (isset($this->message[$parent][
'type']) && ($this->message[$parent][
'type'] ==
'array') && isset($this->message[$parent][
'arrayType'])) {
7018 $ret = $this->decodeSimple($cdata, $this->message[$parent][
'arrayType'], isset($this->message[$parent][
'arrayTypeNamespace']) ? $this->message[$parent][
'arrayTypeNamespace'] :
'');
7019 $this->
debug(
"in buildVal, return: $ret");
7022 $ret = $this->message[$pos][
'cdata'];
7023 $this->
debug(
"in buildVal, return: $ret");
7064 var $certRequest =
array();
7065 var $requestHeaders =
false;
7066 var $responseHeaders =
'';
7067 var $responseHeader = NULL;
7070 var $forceEndpoint =
'';
7071 var $proxyhost =
'';
7072 var $proxyport =
'';
7073 var $proxyusername =
'';
7074 var $proxypassword =
'';
7075 var $xml_encoding =
'';
7076 var $http_encoding =
false;
7078 var $response_timeout = 30;
7079 var $endpointType =
'';
7080 var $persistentConnection =
false;
7081 var $defaultRpcParams =
false;
7084 var $responseData =
'';
7085 var $cookies =
array();
7086 var $decode_utf8 =
true;
7087 var $operations =
array();
7088 var $curl_options =
array();
7089 var $bindingType =
'';
7090 var $use_curl =
false;
7130 function __construct($endpoint,$wsdl =
false,$proxyhost =
false,$proxyport =
false,$proxyusername =
false, $proxypassword =
false, $timeout = 0, $response_timeout = 30){
7131 parent::__construct();
7132 $this->endpoint = $endpoint;
7133 $this->proxyhost = $proxyhost;
7134 $this->proxyport = $proxyport;
7135 $this->proxyusername = $proxyusername;
7136 $this->proxypassword = $proxypassword;
7137 $this->timeout = $timeout;
7138 $this->response_timeout = $response_timeout;
7140 $this->
debug(
"ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7145 if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
7146 $this->
wsdl = $endpoint;
7147 $this->endpoint = $this->
wsdl->
wsdl;
7148 $this->wsdlFile = $this->endpoint;
7149 $this->
debug(
'existing wsdl instance created from ' . $this->endpoint);
7152 $this->wsdlFile = $this->endpoint;
7154 $this->
debug(
'will use lazy evaluation of wsdl from ' . $this->endpoint);
7156 $this->endpointType =
'wsdl';
7158 $this->
debug(
"instantiate SOAP with endpoint at $endpoint");
7159 $this->endpointType =
'soap';
7188 function call($operation,
$params=
array(),
$namespace=
'http://tempuri.org',$soapAction=
'',$headers=
false,$rpcParams=null,
$style=
'rpc',$use=
'encoded'){
7189 $this->operation = $operation;
7190 $this->fault =
false;
7192 $this->request =
'';
7193 $this->response =
'';
7194 $this->responseData =
'';
7195 $this->faultstring =
'';
7196 $this->faultcode =
'';
7197 $this->opData =
array();
7199 $this->
debug(
"call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7203 $this->requestHeaders = $headers;
7205 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7211 if($this->endpointType ==
'wsdl' && $opData = $this->getOperationData($operation)){
7213 $this->opData = $opData;
7214 $this->
debug(
"found operation");
7216 if (isset($opData[
'soapAction'])) {
7217 $soapAction = $opData[
'soapAction'];
7219 if (! $this->forceEndpoint) {
7220 $this->endpoint = $opData[
'endpoint'];
7222 $this->endpoint = $this->forceEndpoint;
7224 $namespace = isset($opData[
'input'][
'namespace']) ? $opData[
'input'][
'namespace'] :
$namespace;
7225 $style = $opData[
'style'];
7226 $use = $opData[
'input'][
'use'];
7229 $nsPrefix =
'ns' . rand(1000, 9999);
7235 $this->
debug(
"serializing param string for WSDL operation $operation");
7237 } elseif (is_array(
$params)) {
7238 $this->
debug(
"serializing param array for WSDL operation $operation");
7241 $this->
debug(
'params must be array or string');
7242 $this->
setError(
'params must be array or string');
7246 if (isset($opData[
'input'][
'encodingStyle'])) {
7247 $encodingStyle = $opData[
'input'][
'encodingStyle'];
7249 $encodingStyle =
'';
7254 $this->
debug(
'got wsdl error: '.$errstr);
7255 $this->
setError(
'wsdl error: '.$errstr);
7258 } elseif($this->endpointType ==
'wsdl') {
7262 $this->
setError(
'operation '.$operation.
' not present.');
7263 $this->
debug(
"operation '$operation' not present.");
7268 $nsPrefix =
'ns' . rand(1000, 9999);
7272 $this->
debug(
"serializing param string for operation $operation");
7274 } elseif (is_array(
$params)) {
7275 $this->
debug(
"serializing param array for operation $operation");
7277 $payload .= $this->
serialize_val($v,$k,
false,
false,
false,
false,$use);
7280 $this->
debug(
'params must be array or string');
7281 $this->
setError(
'params must be array or string');
7285 if ($use ==
'encoded') {
7286 $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
7288 $encodingStyle =
'';
7293 if ($use ==
'literal') {
7294 $this->
debug(
"wrapping RPC request with literal method element");
7297 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7299 "</$nsPrefix:$operation>";
7301 $payload =
"<$operation>" . $payload .
"</$operation>";
7304 $this->
debug(
"wrapping RPC request with encoded method element");
7306 $payload =
"<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7308 "</$nsPrefix:$operation>";
7310 $payload =
"<$operation>" .
7318 $this->
debug(
"endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7319 $this->
debug(
'SOAP message length=' . strlen($soapmsg) .
' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7321 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7323 $this->
debug(
'Error: '.$errstr);
7326 $this->
return = $return;
7327 $this->
debug(
'sent message successfully and got a(n) '.gettype($return));
7331 if(is_array($return) && isset($return[
'faultcode'])){
7332 $this->
debug(
'got fault');
7333 $this->
setError($return[
'faultcode'].
': '.$return[
'faultstring']);
7334 $this->fault =
true;
7335 foreach($return as $k => $v){
7337 $this->
debug(
"$k = $v<br>");
7340 } elseif (
$style ==
'document') {
7346 if(is_array($return)){
7349 if(
sizeof($return) > 1){
7353 $return = array_shift($return);
7354 $this->
debug(
'return shifted value: ');
7370 function checkWSDL() {
7373 $this->
debug(
'checkWSDL');
7376 $this->
debug(
'got wsdl error: '.$errstr);
7377 $this->
setError(
'wsdl error: '.$errstr);
7379 $this->bindingType =
'soap';
7380 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7382 $this->bindingType =
'soap12';
7383 $this->
debug(
'got '.count($this->operations).
' operations from wsdl '.$this->wsdlFile.
' for binding type '.$this->bindingType);
7384 $this->
debug(
'**************** WARNING: SOAP 1.2 BINDING *****************');
7386 $this->
debug(
'getOperations returned false');
7387 $this->
setError(
'no operations defined in the WSDL document!');
7396 function loadWSDL() {
7397 $this->
debug(
'instantiating wsdl class with doc: '.$this->wsdlFile);
7398 $this->
wsdl =
new wsdl(
'',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7399 $this->
wsdl->
setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7411 function getOperationData($operation){
7412 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7417 if(isset($this->operations[$operation])){
7418 return $this->operations[$operation];
7420 $this->
debug(
"No data for operation: $operation");
7437 function send($msg, $soapaction =
'', $timeout=0, $response_timeout=30) {
7438 $this->checkCookies();
7442 case preg_match(
'/^http/',$this->endpoint):
7443 $this->
debug(
'transporting via HTTP');
7444 if($this->persistentConnection ==
true && is_object($this->persistentConnection)){
7445 $http =& $this->persistentConnection;
7448 if ($this->persistentConnection) {
7449 $http->usePersistentConnection();
7452 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7453 $http->setSOAPAction($soapaction);
7454 if($this->proxyhost && $this->proxyport){
7455 $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7457 if($this->authtype !=
'') {
7458 $http->setCredentials($this->username, $this->password, $this->authtype,
array(), $this->certRequest);
7460 if($this->http_encoding !=
''){
7461 $http->setEncoding($this->http_encoding);
7463 $this->
debug(
'sending message, length='.strlen($msg));
7464 if(preg_match(
'/^http:/',$this->endpoint)){
7466 $this->responseData =
$http->send($msg,$timeout,$response_timeout,$this->cookies);
7467 } elseif(preg_match(
'/^https/',$this->endpoint)){
7474 $this->responseData =
$http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7476 $this->
setError(
'no http/s in endpoint url');
7478 $this->request =
$http->outgoing_payload;
7479 $this->response =
$http->incoming_payload;
7481 $this->UpdateCookies(
$http->incoming_cookies);
7484 if ($this->persistentConnection) {
7485 $http->clearDebug();
7486 if (!is_object($this->persistentConnection)) {
7487 $this->persistentConnection =
$http;
7491 if($err =
$http->getError()){
7492 $this->
setError(
'HTTP Error: '.$err);
7497 $this->
debug(
'got response, length='. strlen($this->responseData).
' type='.
$http->incoming_headers[
'content-type']);
7498 return $this->parseResponse(
$http->incoming_headers, $this->responseData);
7502 $this->
setError(
'no transport found, or selected transport is not yet supported!');
7516 function parseResponse($headers,
$data) {
7517 $this->
debug(
'Entering parseResponse() for data of length ' . strlen(
$data) .
' headers:');
7519 if (!strstr($headers[
'content-type'],
'text/xml')) {
7520 $this->
setError(
'Response not of type text/xml: ' . $headers[
'content-type']);
7523 if (strpos($headers[
'content-type'],
'=')) {
7524 $enc = str_replace(
'"',
'', substr(strstr($headers[
"content-type"],
'='), 1));
7525 $this->
debug(
'Got response encoding: ' . $enc);
7526 if(preg_match(
'/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7527 $this->xml_encoding = strtoupper($enc);
7529 $this->xml_encoding =
'US-ASCII';
7533 $this->xml_encoding =
'ISO-8859-1';
7535 $this->
debug(
'Use encoding: ' . $this->xml_encoding .
' when creating nusoap_parser');
7536 $parser =
new nusoap_parser(
$data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7540 if($errstr = $parser->getError()){
7547 $this->responseHeaders = $parser->getHeaders();
7549 $this->responseHeader = $parser->get_soapheader();
7551 $return = $parser->get_soapbody();
7553 $this->document = $parser->document;
7568 function setCurlOption($option, $value) {
7569 $this->
debug(
"setCurlOption option=$option, value=");
7571 $this->curl_options[$option] = $value;
7580 function setEndpoint($endpoint) {
7581 $this->
debug(
"setEndpoint(\"$endpoint\")");
7582 $this->forceEndpoint = $endpoint;
7591 function setHeaders($headers){
7592 $this->
debug(
"setHeaders headers=");
7594 $this->requestHeaders = $headers;
7603 function getHeaders(){
7604 return $this->responseHeaders;
7613 function getHeader(){
7614 return $this->responseHeader;
7626 function setHTTPProxy($proxyhost, $proxyport, $proxyusername =
'', $proxypassword =
'') {
7627 $this->proxyhost = $proxyhost;
7628 $this->proxyport = $proxyport;
7629 $this->proxyusername = $proxyusername;
7630 $this->proxypassword = $proxypassword;
7642 function setCredentials($username, $password, $authtype =
'basic', $certRequest =
array()) {
7643 $this->
debug(
"setCredentials username=$username authtype=$authtype certRequest=");
7645 $this->username = $username;
7646 $this->password = $password;
7647 $this->authtype = $authtype;
7648 $this->certRequest = $certRequest;
7657 function setHTTPEncoding($enc=
'gzip, deflate'){
7658 $this->
debug(
"setHTTPEncoding(\"$enc\")");
7659 $this->http_encoding = $enc;
7668 function setUseCURL($use) {
7669 $this->
debug(
"setUseCURL($use)");
7670 $this->use_curl = $use;
7678 function useHTTPPersistentConnection(){
7679 $this->
debug(
"useHTTPPersistentConnection");
7680 $this->persistentConnection =
true;
7694 function getDefaultRpcParams() {
7695 return $this->defaultRpcParams;
7709 function setDefaultRpcParams($rpcParams) {
7710 $this->defaultRpcParams = $rpcParams;
7720 function getProxy() {
7722 $evalStr = $this->_getProxyClassCode(
$r);
7725 $this->
debug(
"Error from _getProxyClassCode, so return NULL");
7731 eval(
"\$proxy = new nusoap_proxy_$r('');");
7733 $proxy->endpointType =
'wsdl';
7734 $proxy->wsdlFile = $this->wsdlFile;
7735 $proxy->wsdl = $this->wsdl;
7736 $proxy->operations = $this->operations;
7737 $proxy->defaultRpcParams = $this->defaultRpcParams;
7740 $proxy->username = $this->username;
7741 $proxy->password = $this->password;
7742 $proxy->authtype = $this->authtype;
7743 $proxy->certRequest = $this->certRequest;
7744 $proxy->requestHeaders = $this->requestHeaders;
7745 $proxy->endpoint = $this->endpoint;
7746 $proxy->forceEndpoint = $this->forceEndpoint;
7747 $proxy->proxyhost = $this->proxyhost;
7748 $proxy->proxyport = $this->proxyport;
7749 $proxy->proxyusername = $this->proxyusername;
7750 $proxy->proxypassword = $this->proxypassword;
7751 $proxy->http_encoding = $this->http_encoding;
7752 $proxy->timeout = $this->timeout;
7753 $proxy->response_timeout = $this->response_timeout;
7754 $proxy->persistentConnection = &$this->persistentConnection;
7755 $proxy->decode_utf8 = $this->decode_utf8;
7756 $proxy->curl_options = $this->curl_options;
7757 $proxy->bindingType = $this->bindingType;
7758 $proxy->use_curl = $this->use_curl;
7768 function _getProxyClassCode(
$r) {
7769 $this->
debug(
"in getProxy endpointType=$this->endpointType");
7771 if ($this->endpointType !=
'wsdl') {
7772 $evalStr =
'A proxy can only be created for a WSDL client';
7774 $evalStr =
"echo \"$evalStr\";";
7777 if ($this->endpointType ==
'wsdl' && is_null($this->
wsdl)) {
7780 return "echo \"" . $this->
getError() .
"\";";
7784 foreach ($this->operations as $operation => $opData) {
7785 if ($operation !=
'') {
7787 if (
sizeof($opData[
'input'][
'parts']) > 0) {
7789 $paramArrayStr =
'';
7790 $paramCommentStr =
'';
7791 foreach ($opData[
'input'][
'parts'] as $name => $type) {
7792 $paramStr .=
"\$$name, ";
7793 $paramArrayStr .=
"'$name' => \$$name, ";
7794 $paramCommentStr .=
"$type \$$name, ";
7796 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7797 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7798 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7801 $paramArrayStr =
'';
7802 $paramCommentStr =
'void';
7804 $opData[
'namespace'] = !isset($opData[
'namespace']) ?
'http://testuri.com' : $opData[
'namespace'];
7805 $evalStr .=
"// $paramCommentStr 7806 function " . str_replace(
'.',
'__', $operation) .
"($paramStr) { 7807 \$params = array($paramArrayStr); 7808 return \$this->call('$operation', \$params, '".$opData[
'namespace'].
"', '".(isset($opData[
'soapAction']) ? $opData[
'soapAction'] :
'').
"'); 7812 unset($paramCommentStr);
7815 $evalStr =
'class nusoap_proxy_'.$r.
' extends nusoap_client { 7827 function getProxyClassCode() {
7829 return $this->_getProxyClassCode(
$r);
7839 function getHTTPBody($soapmsg) {
7851 function getHTTPContentType() {
7864 function getHTTPContentTypeCharset() {
7874 function decodeUTF8($bool){
7875 $this->decode_utf8 = $bool;
7887 function setCookie($name, $value) {
7888 if (strlen($name) == 0) {
7891 $this->cookies[] =
array(
'name' => $name,
'value' => $value);
7901 function getCookies() {
7902 return $this->cookies;
7911 function checkCookies() {
7912 if (
sizeof($this->cookies) == 0) {
7915 $this->
debug(
'checkCookie: check ' .
sizeof($this->cookies) .
' cookies');
7916 $curr_cookies = $this->cookies;
7917 $this->cookies =
array();
7918 foreach ($curr_cookies as $cookie) {
7919 if (! is_array($cookie)) {
7920 $this->
debug(
'Remove cookie that is not an array');
7923 if ((isset($cookie[
'expires'])) && (! empty($cookie[
'expires']))) {
7924 if (strtotime($cookie[
'expires']) >
time()) {
7925 $this->cookies[] = $cookie;
7927 $this->
debug(
'Remove expired cookie ' . $cookie[
'name']);
7930 $this->cookies[] = $cookie;
7933 $this->
debug(
'checkCookie: '.
sizeof($this->cookies).
' cookies left in array');
7944 function UpdateCookies($cookies) {
7945 if (
sizeof($this->cookies) == 0) {
7947 if (
sizeof($cookies) > 0) {
7948 $this->
debug(
'Setting new cookie(s)');
7949 $this->cookies = $cookies;
7953 if (
sizeof($cookies) == 0) {
7958 foreach ($cookies as $newCookie) {
7959 if (!is_array($newCookie)) {
7962 if ((!isset($newCookie[
'name'])) || (!isset($newCookie[
'value']))) {
7965 $newName = $newCookie[
'name'];
7968 for ($i = 0; $i < count($this->cookies); $i++) {
7969 $cookie = $this->cookies[$i];
7970 if (!is_array($cookie)) {
7973 if (!isset($cookie[
'name'])) {
7976 if ($newName != $cookie[
'name']) {
7979 $newDomain = isset($newCookie[
'domain']) ? $newCookie[
'domain'] :
'NODOMAIN';
7980 $domain = isset($cookie[
'domain']) ? $cookie[
'domain'] :
'NODOMAIN';
7981 if ($newDomain != $domain) {
7984 $newPath = isset($newCookie[
'path']) ? $newCookie[
'path'] :
'NOPATH';
7985 $path = isset($cookie[
'path']) ? $cookie[
'path'] :
'NOPATH';
7986 if ($newPath != $path) {
7989 $this->cookies[$i] = $newCookie;
7991 $this->
debug(
'Update cookie ' . $newName .
'=' . $newCookie[
'value']);
7995 $this->
debug(
'Add cookie ' . $newName .
'=' . $newCookie[
'value']);
7996 $this->cookies[] = $newCookie;
8003 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
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
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
soap_fault class, allows for creation of faults mainly used for returning faults from deployed functi...
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
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
soap_parser class parses SOAP XML messages into native PHP values
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.
Reload workbook from saved file
wsdl($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
Add a drawing to the header
Create styles array
The data for the language used.
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
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
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
clearDebug()
clears the current debug data for this instance
fetchWSDL($wsdl)
fetches the WSDL document and parses it