ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
nusoap.php File Reference

Go to the source code of this file.

Data Structures

class  nusoap_base
 nusoap_base More...
 
class  nusoap_fault
 Contains information for a SOAP fault. More...
 
class  soap_fault
 Backward compatibility. More...
 
class  nusoap_xmlschema
 parses an XML Schema, allows access to it's data, other utility methods. More...
 
class  XMLSchema
 Backward compatibility. More...
 
class  soapval
 For creating serializable abstractions of native PHP types. More...
 
class  soap_transport_http
 transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CURL extension for HTTPS support More...
 
class  nusoap_server
 nusoap_server allows the user to create a SOAP server that is capable of receiving messages and returning responses More...
 
class  soap_server
 Backward compatibility. More...
 
class  wsdl
 parses a WSDL file, allows access to it's data, other utility methods. More...
 
class  nusoap_parser
 nusoap_parser class parses SOAP XML messages into native PHP values More...
 
class  soap_parser
 Backward compatibility. More...
 
class  nusoap_client
 [nu]soapclient higher level class for easy usage. More...
 

Functions

 timestamp_to_iso8601 ($timestamp, $utc=true)
 convert unix timestamp to ISO 8601 compliant date string More...
 
 iso8601_to_timestamp ($datestr)
 convert ISO 8601 compliant date string to unix timestamp More...
 
 usleepWindows ($usec)
 sleeps some number of microseconds More...
 

Variables

if(!isset($GLOBALS['_transient'])||!isset($GLOBALS['_transient']['static'])||!isset($GLOBALS['_transient']['static']['nusoap_base'])||!is_object($GLOBALS['_transient']['static']['nusoap_base'])) $GLOBALS[ '_transient'][ 'static'][ 'nusoap_base'] globalDebugLevel = 0
 This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V. More...
 

Function Documentation

◆ iso8601_to_timestamp()

iso8601_to_timestamp (   $datestr)

convert ISO 8601 compliant date string to unix timestamp

Parameters
string$datestrISO 8601 compliant date string @access public

Definition at line 929 of file nusoap.php.

930{
931 $pattern = '/' .
932 '([0-9]{4})-' . // centuries & years CCYY-
933 '([0-9]{2})-' . // months MM-
934 '([0-9]{2})' . // days DD
935 'T' . // separator T
936 '([0-9]{2}):' . // hours hh:
937 '([0-9]{2}):' . // minutes mm:
938 '([0-9]{2})(\.[0-9]+)?' . // seconds ss.ss...
939 '(Z|[+\-][0-9]{2}:?[0-9]{2})?' . // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
940 '/';
941
942 if (preg_match($pattern, $datestr, $regs)) {
943 // not utc
944 if ($regs[8] != 'Z') {
945 $op = substr($regs[8], 0, 1);
946 $h = substr($regs[8], 1, 2);
947 $m = substr($regs[8], strlen($regs[8]) - 2, 2);
948 if ($op == '-') {
949 $regs[4] = $regs[4] + $h;
950 $regs[5] = $regs[5] + $m;
951 } elseif ($op == '+') {
952 $regs[4] = $regs[4] - $h;
953 $regs[5] = $regs[5] - $m;
954 }
955 }
956 return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
957 // return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
958 } else {
959 return false;
960 }
961}

◆ timestamp_to_iso8601()

timestamp_to_iso8601 (   $timestamp,
  $utc = true 
)

convert unix timestamp to ISO 8601 compliant date string

Parameters
string$timestampUnix time stamp
boolean$utcWhether the time stamp is UTC or local @access public

Definition at line 899 of file nusoap.php.

900{
901 $datestr = date('Y-m-d\TH:i:sO', $timestamp);
902 if ($utc) {
903 $pattern = '/' .
904 '([0-9]{4})-' . // centuries & years CCYY-
905 '([0-9]{2})-' . // months MM-
906 '([0-9]{2})' . // days DD
907 'T' . // separator T
908 '([0-9]{2}):' . // hours hh:
909 '([0-9]{2}):' . // minutes mm:
910 '([0-9]{2})(\.[0-9]*)?' . // seconds ss.ss...
911 '(Z|[+\-][0-9]{2}:?[0-9]{2})?' . // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
912 '/';
913
914 if (preg_match($pattern, $datestr, $regs)) {
915 return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', $regs[1], $regs[2], $regs[3], $regs[4], $regs[5], $regs[6]);
916 }
917 return false;
918 } else {
919 return $datestr;
920 }
921}
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70

References $timestamp.

◆ usleepWindows()

usleepWindows (   $usec)

sleeps some number of microseconds

Parameters
string$usecthe number of microseconds to sleep @access public
Deprecated:

For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.

Definition at line 970 of file nusoap.php.

971{
972 $start = gettimeofday();
973
974 do {
975 $stop = gettimeofday();
976 $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
977 + $stop['usec'] - $start['usec'];
978 } while ($timePassed < $usec);
979}
980
981?><?php
982
983
984
993class nusoap_fault extends nusoap_base
994{
1000 public $faultcode;
1006 public $faultactor;
1012 public $faultstring;
1018 public $faultdetail;
1019
1028 public function __construct($faultcode, $faultactor = '', $faultstring = '', $faultdetail = '')
1029 {
1031 $this->faultcode = $faultcode;
1032 $this->faultactor = $faultactor;
1033 $this->faultstring = $faultstring;
1034 $this->faultdetail = $faultdetail;
1035 }
1036
1043 public function serialize()
1044 {
1045 $ns_string = '';
1046 foreach ($this->namespaces as $k => $v) {
1047 $ns_string .= "\n xmlns:$k=\"$v\"";
1048 }
1049 $return_msg =
1050 '<?xml version="1.0" encoding="' . $this->soap_defencoding . '"?>' .
1051 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"' . $ns_string . ">\n" .
1052 '<SOAP-ENV:Body>' .
1053 '<SOAP-ENV:Fault>' .
1054 $this->serialize_val($this->faultcode, 'faultcode') .
1055 $this->serialize_val($this->faultstring, 'faultstring') .
1056 $this->serialize_val($this->faultactor, 'faultactor') .
1057 $this->serialize_val($this->faultdetail, 'detail') .
1058 '</SOAP-ENV:Fault>' .
1059 '</SOAP-ENV:Body>' .
1060 '</SOAP-ENV:Envelope>';
1061 return $return_msg;
1062 }
1063}
1064
1068class soap_fault extends nusoap_fault
1069{
1070}
1071
1072?><?php
1073
1074
1075
1085class nusoap_xmlschema extends nusoap_base
1086{
1087 // files
1088 public $schema = '';
1089 public $xml = '';
1090 // namespaces
1091 public $enclosingNamespaces;
1092 // schema info
1093 public $schemaInfo = array();
1094 public $schemaTargetNamespace = '';
1095 // types, elements, attributes defined by the schema
1096 public $attributes = array();
1097 public $complexTypes = array();
1098 public $complexTypeStack = array();
1099 public $currentComplexType = null;
1100 public $elements = array();
1101 public $elementStack = array();
1102 public $currentElement = null;
1103 public $simpleTypes = array();
1104 public $simpleTypeStack = array();
1105 public $currentSimpleType = null;
1106 // imports
1107 public $imports = array();
1108 // parser vars
1109 public $parser;
1110 public $position = 0;
1111 public $depth = 0;
1112 public $depth_array = array();
1113 public $message = array();
1114 public $defaultNamespace = array();
1115
1124 public function __construct($schema = '', $xml = '', $namespaces = array())
1125 {
1127 $this->debug('nusoap_xmlschema class instantiated, inside constructor');
1128 // files
1129 $this->schema = $schema;
1130 $this->xml = $xml;
1131
1132 // namespaces
1133 $this->enclosingNamespaces = $namespaces;
1134 $this->namespaces = array_merge($this->namespaces, $namespaces);
1135
1136 // parse schema file
1137 if ($schema != '') {
1138 $this->debug('initial schema file: ' . $schema);
1139 $this->parseFile($schema, 'schema');
1140 }
1141
1142 // parse xml file
1143 if ($xml != '') {
1144 $this->debug('initial xml file: ' . $xml);
1145 $this->parseFile($xml, 'xml');
1146 }
1147 }
1148
1157 public function parseFile($xml, $type)
1158 {
1159 // parse xml file
1160 if ($xml != "") {
1161 $xmlStr = @join("", @file($xml));
1162 if ($xmlStr == "") {
1163 $msg = 'Error reading XML from ' . $xml;
1164 $this->setError($msg);
1165 $this->debug($msg);
1166 return false;
1167 } else {
1168 $this->debug("parsing $xml");
1169 $this->parseString($xmlStr, $type);
1170 $this->debug("done parsing $xml");
1171 return true;
1172 }
1173 }
1174 return false;
1175 }
1176
1184 public function parseString($xml, $type)
1185 {
1186 // parse xml string
1187 if ($xml != "") {
1188 // Create an XML parser.
1189 $this->parser = xml_parser_create();
1190 // Set the options for parsing the XML data.
1191 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1192
1193 // Set the element handlers for the parser.
1194 if ($type == "schema") {
1195 xml_set_element_handler($this->parser, $this->schemaStartElement(...), $this->schemaEndElement(...));
1196 xml_set_character_data_handler($this->parser, $this->schemaCharacterData(...));
1197 } elseif ($type == "xml") {
1198 xml_set_element_handler($this->parser, $this->xmlStartElement(...), $this->xmlEndElement(...));
1199 xml_set_character_data_handler($this->parser, $this->xmlCharacterData(...));
1200 }
1201
1202 // Parse the XML file.
1203 if (!xml_parse($this->parser, $xml, true)) {
1204 // Display an error message.
1205 $errstr = sprintf(
1206 'XML error parsing XML schema on line %d: %s',
1207 xml_get_current_line_number($this->parser),
1208 xml_error_string(xml_get_error_code($this->parser))
1209 );
1210 $this->debug($errstr);
1211 $this->debug("XML payload:\n" . $xml);
1212 $this->setError($errstr);
1213 }
1214 } else {
1215 $this->debug('no xml passed to parseString()!!');
1216 $this->setError('no xml passed to parseString()!!');
1217 }
1218 }
1219
1227 public function CreateTypeName($ename)
1228 {
1229 $scope = '';
1230 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1231 $scope .= $this->complexTypeStack[$i] . '_';
1232 }
1233 return $scope . $ename . '_ContainedType';
1234 }
1235
1244 public function schemaStartElement($parser, $name, $attrs)
1245 {
1246
1247 // position in the total number of elements, starting from 0
1248 $pos = $this->position++;
1249 $depth = $this->depth++;
1250 // set self as current value for this depth
1251 $this->depth_array[$depth] = $pos;
1252 $this->message[$pos] = array('cdata' => '');
1253 if ($depth > 0) {
1254 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1255 } else {
1256 $this->defaultNamespace[$pos] = false;
1257 }
1258
1259 // get element prefix
1260 if ($prefix = $this->getPrefix($name)) {
1261 // get unqualified name
1262 $name = $this->getLocalPart($name);
1263 } else {
1264 $prefix = '';
1265 }
1266
1267 // loop thru attributes, expanding, and registering namespace declarations
1268 if (count($attrs) > 0) {
1269 foreach ($attrs as $k => $v) {
1270 // if ns declarations, add to class level array of valid namespaces
1271 if (preg_match('/^xmlns/', $k)) {
1272 //$this->xdebug("$k: $v");
1273 //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
1274 if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
1275 //$this->xdebug("Add namespace[$ns_prefix] = $v");
1276 $this->namespaces[$ns_prefix] = $v;
1277 } else {
1278 $this->defaultNamespace[$pos] = $v;
1279 if (! $this->getPrefixFromNamespace($v)) {
1280 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
1281 }
1282 }
1283 if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
1284 $this->XMLSchemaVersion = $v;
1285 $this->namespaces['xsi'] = $v . '-instance';
1286 }
1287 }
1288 }
1289 foreach ($attrs as $k => $v) {
1290 // expand each attribute
1291 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
1292 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
1293 $eAttrs[$k] = $v;
1294 }
1295 $attrs = $eAttrs;
1296 } else {
1297 $attrs = array();
1298 }
1299 // find status, register data
1300 switch ($name) {
1301 case 'all': // (optional) compositor content for a complexType
1302 case 'choice':
1303 case 'group':
1304 case 'sequence':
1305 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
1306 $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
1307 //if($name == 'all' || $name == 'sequence'){
1308 // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1309 //}
1310 break;
1311 case 'attribute': // complexType attribute
1312 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
1313 $this->xdebug("parsing attribute:");
1314 $this->appendDebug($this->varDump($attrs));
1315 if (!isset($attrs['form'])) {
1316 $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
1317 }
1318 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1319 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1320 if (!strpos($v, ':')) {
1321 // no namespace in arrayType attribute value...
1322 if ($this->defaultNamespace[$pos]) {
1323 // ...so use the default
1324 $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1325 }
1326 }
1327 }
1328 if (isset($attrs['name'])) {
1329 $this->attributes[$attrs['name']] = $attrs;
1330 $aname = $attrs['name'];
1331 } elseif (isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
1332 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1333 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1334 } else {
1335 $aname = '';
1336 }
1337 } elseif (isset($attrs['ref'])) {
1338 $aname = $attrs['ref'];
1339 $this->attributes[$attrs['ref']] = $attrs;
1340 }
1341
1342 if ($this->currentComplexType) { // This should *always* be
1343 $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
1344 }
1345 // arrayType attribute
1346 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType') {
1347 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1348 $prefix = $this->getPrefix($aname);
1349 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1350 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1351 } else {
1352 $v = '';
1353 }
1354 if (strpos($v, '[,]')) {
1355 $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
1356 }
1357 $v = substr($v, 0, strpos($v, '[')); // clip the []
1358 if (!strpos($v, ':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
1359 $v = $this->XMLSchemaVersion . ':' . $v;
1360 }
1361 $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
1362 }
1363 break;
1364 case 'complexContent': // (optional) content for a complexType
1365 break;
1366 case 'complexType':
1367 array_push($this->complexTypeStack, $this->currentComplexType);
1368 if (isset($attrs['name'])) {
1369 // TODO: what is the scope of named complexTypes that appear
1370 // nested within other c complexTypes?
1371 $this->xdebug('processing named complexType ' . $attrs['name']);
1372 //$this->currentElement = false;
1373 $this->currentComplexType = $attrs['name'];
1374 $this->complexTypes[$this->currentComplexType] = $attrs;
1375 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1376 // This is for constructs like
1377 // <complexType name="ListOfString" base="soap:Array">
1378 // <sequence>
1379 // <element name="string" type="xsd:string"
1380 // minOccurs="0" maxOccurs="unbounded" />
1381 // </sequence>
1382 // </complexType>
1383 if (isset($attrs['base']) && preg_match('/:Array$/', $attrs['base'])) {
1384 $this->xdebug('complexType is unusual array');
1385 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1386 } else {
1387 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1388 }
1389 } else {
1390 $name = $this->CreateTypeName($this->currentElement);
1391 $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
1392 $this->currentComplexType = $name;
1393 //$this->currentElement = false;
1394 $this->complexTypes[$this->currentComplexType] = $attrs;
1395 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1396 // This is for constructs like
1397 // <complexType name="ListOfString" base="soap:Array">
1398 // <sequence>
1399 // <element name="string" type="xsd:string"
1400 // minOccurs="0" maxOccurs="unbounded" />
1401 // </sequence>
1402 // </complexType>
1403 if (isset($attrs['base']) && preg_match('/:Array$/', $attrs['base'])) {
1404 $this->xdebug('complexType is unusual array');
1405 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1406 } else {
1407 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1408 }
1409 }
1410 break;
1411 case 'element':
1412 array_push($this->elementStack, $this->currentElement);
1413 if (!isset($attrs['form'])) {
1414 $attrs['form'] = $this->schemaInfo['elementFormDefault'];
1415 }
1416 if (isset($attrs['type'])) {
1417 $this->xdebug("processing typed element " . $attrs['name'] . " of type " . $attrs['type']);
1418 if (! $this->getPrefix($attrs['type'])) {
1419 if ($this->defaultNamespace[$pos]) {
1420 $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
1421 $this->xdebug('used default namespace to make type ' . $attrs['type']);
1422 }
1423 }
1424 // This is for constructs like
1425 // <complexType name="ListOfString" base="soap:Array">
1426 // <sequence>
1427 // <element name="string" type="xsd:string"
1428 // minOccurs="0" maxOccurs="unbounded" />
1429 // </sequence>
1430 // </complexType>
1431 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
1432 $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
1433 $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
1434 }
1435 $this->currentElement = $attrs['name'];
1436 $ename = $attrs['name'];
1437 } elseif (isset($attrs['ref'])) {
1438 $this->xdebug("processing element as ref to " . $attrs['ref']);
1439 $this->currentElement = "ref to " . $attrs['ref'];
1440 $ename = $this->getLocalPart($attrs['ref']);
1441 } else {
1442 $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
1443 $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
1444 $this->currentElement = $attrs['name'];
1445 $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
1446 $ename = $attrs['name'];
1447 }
1448 if (isset($ename) && $this->currentComplexType) {
1449 $this->xdebug("add element $ename to complexType $this->currentComplexType");
1450 $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
1451 } elseif (!isset($attrs['ref'])) {
1452 $this->xdebug("add element $ename to elements array");
1453 $this->elements[ $attrs['name'] ] = $attrs;
1454 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
1455 }
1456 break;
1457 case 'enumeration': // restriction value list member
1458 $this->xdebug('enumeration ' . $attrs['value']);
1459 if ($this->currentSimpleType) {
1460 $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
1461 } elseif ($this->currentComplexType) {
1462 $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
1463 }
1464 break;
1465 case 'extension': // simpleContent or complexContent type extension
1466 $this->xdebug('extension ' . $attrs['base']);
1467 if ($this->currentComplexType) {
1468 $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
1469 }
1470 break;
1471 case 'import':
1472 if (isset($attrs['schemaLocation'])) {
1473 //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
1474 $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
1475 } else {
1476 //$this->xdebug('import namespace ' . $attrs['namespace']);
1477 $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
1478 if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
1479 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $attrs['namespace'];
1480 }
1481 }
1482 break;
1483 case 'list': // simpleType value list
1484 break;
1485 case 'restriction': // simpleType, simpleContent or complexContent value restriction
1486 $this->xdebug('restriction ' . $attrs['base']);
1487 if ($this->currentSimpleType) {
1488 $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
1489 } elseif ($this->currentComplexType) {
1490 $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
1491 if (strstr($attrs['base'], ':') == ':Array') {
1492 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1493 }
1494 }
1495 break;
1496 case 'schema':
1497 $this->schemaInfo = $attrs;
1498 $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
1499 if (isset($attrs['targetNamespace'])) {
1500 $this->schemaTargetNamespace = $attrs['targetNamespace'];
1501 }
1502 if (!isset($attrs['elementFormDefault'])) {
1503 $this->schemaInfo['elementFormDefault'] = 'unqualified';
1504 }
1505 if (!isset($attrs['attributeFormDefault'])) {
1506 $this->schemaInfo['attributeFormDefault'] = 'unqualified';
1507 }
1508 break;
1509 case 'simpleContent': // (optional) content for a complexType
1510 break;
1511 case 'simpleType':
1512 array_push($this->simpleTypeStack, $this->currentSimpleType);
1513 if (isset($attrs['name'])) {
1514 $this->xdebug("processing simpleType for name " . $attrs['name']);
1515 $this->currentSimpleType = $attrs['name'];
1516 $this->simpleTypes[ $attrs['name'] ] = $attrs;
1517 $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
1518 $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
1519 } else {
1520 $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
1521 $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
1522 $this->currentSimpleType = $name;
1523 //$this->currentElement = false;
1524 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1525 $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
1526 }
1527 break;
1528 case 'union': // simpleType type list
1529 break;
1530 default:
1531 //$this->xdebug("do not have anything to do for element $name");
1532 }
1533 }
1534
1542 public function schemaEndElement($parser, $name)
1543 {
1544 // bring depth down a notch
1545 $this->depth--;
1546 // position of current element is equal to the last value left in depth_array for my depth
1547 if (isset($this->depth_array[$this->depth])) {
1548 $pos = $this->depth_array[$this->depth];
1549 }
1550 // get element prefix
1551 if ($prefix = $this->getPrefix($name)) {
1552 // get unqualified name
1553 $name = $this->getLocalPart($name);
1554 } else {
1555 $prefix = '';
1556 }
1557 // move on...
1558 if ($name == 'complexType') {
1559 $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
1560 $this->currentComplexType = array_pop($this->complexTypeStack);
1561 //$this->currentElement = false;
1562 }
1563 if ($name == 'element') {
1564 $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
1565 $this->currentElement = array_pop($this->elementStack);
1566 }
1567 if ($name == 'simpleType') {
1568 $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
1569 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1570 }
1571 }
1572
1580 public function schemaCharacterData($parser, $data)
1581 {
1582 $pos = $this->depth_array[$this->depth - 1];
1583 $this->message[$pos]['cdata'] .= $data;
1584 }
1585
1591 public function serializeSchema()
1592 {
1593 $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
1594 $xml = '';
1595 // imports
1596 if (sizeof($this->imports) > 0) {
1597 foreach ($this->imports as $ns => $list) {
1598 foreach ($list as $ii) {
1599 if ($ii['location'] != '') {
1600 $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
1601 } else {
1602 $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
1603 }
1604 }
1605 }
1606 }
1607 // complex types
1608 foreach ($this->complexTypes as $typeName => $attrs) {
1609 $contentStr = '';
1610 // serialize child elements
1611 if (isset($attrs['elements']) && (count($attrs['elements']) > 0)) {
1612 foreach ($attrs['elements'] as $element => $eParts) {
1613 if (isset($eParts['ref'])) {
1614 $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
1615 } else {
1616 $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
1617 foreach ($eParts as $aName => $aValue) {
1618 // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
1619 if ($aName != 'name' && $aName != 'type') {
1620 $contentStr .= " $aName=\"$aValue\"";
1621 }
1622 }
1623 $contentStr .= "/>\n";
1624 }
1625 }
1626 // compositor wraps elements
1627 if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
1628 $contentStr = " <$schemaPrefix:$attrs[compositor]>\n" . $contentStr . " </$schemaPrefix:$attrs[compositor]>\n";
1629 }
1630 }
1631 // attributes
1632 if (isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)) {
1633 foreach ($attrs['attrs'] as $attr => $aParts) {
1634 $contentStr .= " <$schemaPrefix:attribute";
1635 foreach ($aParts as $a => $v) {
1636 if ($a == 'ref' || $a == 'type') {
1637 $contentStr .= " $a=\"" . $this->contractQName($v) . '"';
1638 } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1639 $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
1640 $contentStr .= ' wsdl:arrayType="' . $this->contractQName($v) . '"';
1641 } else {
1642 $contentStr .= " $a=\"$v\"";
1643 }
1644 }
1645 $contentStr .= "/>\n";
1646 }
1647 }
1648 // if restriction
1649 if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != '') {
1650 $contentStr = " <$schemaPrefix:restriction base=\"" . $this->contractQName($attrs['restrictionBase']) . "\">\n" . $contentStr . " </$schemaPrefix:restriction>\n";
1651 // complex or simple content
1652 if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)) {
1653 $contentStr = " <$schemaPrefix:complexContent>\n" . $contentStr . " </$schemaPrefix:complexContent>\n";
1654 }
1655 }
1656 // finalize complex type
1657 if ($contentStr != '') {
1658 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n" . $contentStr . " </$schemaPrefix:complexType>\n";
1659 } else {
1660 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1661 }
1662 $xml .= $contentStr;
1663 }
1664 // simple types
1665 if (isset($this->simpleTypes) && count($this->simpleTypes) > 0) {
1666 foreach ($this->simpleTypes as $typeName => $eParts) {
1667 $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"" . $this->contractQName($eParts['type']) . "\">\n";
1668 if (isset($eParts['enumeration'])) {
1669 foreach ($eParts['enumeration'] as $e) {
1670 $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
1671 }
1672 }
1673 $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1674 }
1675 }
1676 // elements
1677 if (isset($this->elements) && count($this->elements) > 0) {
1678 foreach ($this->elements as $element => $eParts) {
1679 $xml .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"/>\n";
1680 }
1681 }
1682 // attributes
1683 if (isset($this->attributes) && count($this->attributes) > 0) {
1684 foreach ($this->attributes as $attr => $aParts) {
1685 $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"" . $this->contractQName($aParts['type']) . "\"\n/>";
1686 }
1687 }
1688 // finish 'er up
1689 $attr = '';
1690 foreach ($this->schemaInfo as $k => $v) {
1691 if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
1692 $attr .= " $k=\"$v\"";
1693 }
1694 }
1695 $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1696 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1697 $el .= " xmlns:$nsp=\"$ns\"";
1698 }
1699 $xml = $el . ">\n" . $xml . "</$schemaPrefix:schema>\n";
1700 return $xml;
1701 }
1702
1709 public function xdebug($string)
1710 {
1711 $this->debug('<' . $this->schemaTargetNamespace . '> ' . $string);
1712 }
1713
1726 public function getPHPType($type, $ns)
1727 {
1728 if (isset($this->typemap[$ns][$type])) {
1729 //print "found type '$type' and ns $ns in typemap<br>";
1730 return $this->typemap[$ns][$type];
1731 } elseif (isset($this->complexTypes[$type])) {
1732 //print "getting type '$type' and ns $ns from complexTypes array<br>";
1733 return $this->complexTypes[$type]['phpType'];
1734 }
1735 return false;
1736 }
1737
1760 public function getTypeDef($type)
1761 {
1762 //$this->debug("in getTypeDef for type $type");
1763 if (substr($type, -1) == '^') {
1764 $is_element = 1;
1765 $type = substr($type, 0, -1);
1766 } else {
1767 $is_element = 0;
1768 }
1769
1770 if ((! $is_element) && isset($this->complexTypes[$type])) {
1771 $this->xdebug("in getTypeDef, found complexType $type");
1772 return $this->complexTypes[$type];
1773 } elseif ((! $is_element) && isset($this->simpleTypes[$type])) {
1774 $this->xdebug("in getTypeDef, found simpleType $type");
1775 if (!isset($this->simpleTypes[$type]['phpType'])) {
1776 // get info for type to tack onto the simple type
1777 // TODO: can this ever really apply (i.e. what is a simpleType really?)
1778 $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
1779 $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
1780 $etype = $this->getTypeDef($uqType);
1781 if ($etype) {
1782 $this->xdebug("in getTypeDef, found type for simpleType $type:");
1783 $this->xdebug($this->varDump($etype));
1784 if (isset($etype['phpType'])) {
1785 $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
1786 }
1787 if (isset($etype['elements'])) {
1788 $this->simpleTypes[$type]['elements'] = $etype['elements'];
1789 }
1790 }
1791 }
1792 return $this->simpleTypes[$type];
1793 } elseif (isset($this->elements[$type])) {
1794 $this->xdebug("in getTypeDef, found element $type");
1795 if (!isset($this->elements[$type]['phpType'])) {
1796 // get info for type to tack onto the element
1797 $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
1798 $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
1799 $etype = $this->getTypeDef($uqType);
1800 if ($etype) {
1801 $this->xdebug("in getTypeDef, found type for element $type:");
1802 $this->xdebug($this->varDump($etype));
1803 if (isset($etype['phpType'])) {
1804 $this->elements[$type]['phpType'] = $etype['phpType'];
1805 }
1806 if (isset($etype['elements'])) {
1807 $this->elements[$type]['elements'] = $etype['elements'];
1808 }
1809 } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
1810 $this->xdebug("in getTypeDef, element $type is an XSD type");
1811 $this->elements[$type]['phpType'] = 'scalar';
1812 }
1813 }
1814 return $this->elements[$type];
1815 } elseif (isset($this->attributes[$type])) {
1816 $this->xdebug("in getTypeDef, found attribute $type");
1817 return $this->attributes[$type];
1818 } elseif (preg_match('/_ContainedType$/', $type)) {
1819 $this->xdebug("in getTypeDef, have an untyped element $type");
1820 $typeDef['typeClass'] = 'simpleType';
1821 $typeDef['phpType'] = 'scalar';
1822 $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
1823 return $typeDef;
1824 }
1825 $this->xdebug("in getTypeDef, did not find $type");
1826 return false;
1827 }
1828
1837 public function serializeTypeDef($type)
1838 {
1839 //print "in sTD() for type $type<br>";
1840 if ($typeDef = $this->getTypeDef($type)) {
1841 $str .= '<' . $type;
1842 if (is_array($typeDef['attrs'])) {
1843 foreach ($typeDef['attrs'] as $attName => $data) {
1844 $str .= " $attName=\"{type = " . $data['type'] . "}\"";
1845 }
1846 }
1847 $str .= " xmlns=\"" . $this->schema['targetNamespace'] . "\"";
1848 if (count($typeDef['elements']) > 0) {
1849 $str .= ">";
1850 foreach ($typeDef['elements'] as $element => $eData) {
1851 $str .= $this->serializeTypeDef($element);
1852 }
1853 $str .= "</$type>";
1854 } elseif ($typeDef['typeClass'] == 'element') {
1855 $str .= "></$type>";
1856 } else {
1857 $str .= "/>";
1858 }
1859 return $str;
1860 }
1861 return false;
1862 }
1863
1874 public function typeToForm($name, $type)
1875 {
1876 // get typedef
1877 if ($typeDef = $this->getTypeDef($type)) {
1878 // if struct
1879 if ($typeDef['phpType'] == 'struct') {
1880 $buffer .= '<table>';
1881 foreach ($typeDef['elements'] as $child => $childDef) {
1882 $buffer .= "
1883 <tr><td align='right'>$childDef[name] (type: " . $this->getLocalPart($childDef['type']) . "):</td>
1884 <td><input type='text' name='parameters[" . $name . "][$childDef[name]]'></td></tr>";
1885 }
1886 $buffer .= '</table>';
1887 // if array
1888 } elseif ($typeDef['phpType'] == 'array') {
1889 $buffer .= '<table>';
1890 for ($i = 0;$i < 3; $i++) {
1891 $buffer .= "
1892 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
1893 <td><input type='text' name='parameters[" . $name . "][]'></td></tr>";
1894 }
1895 $buffer .= '</table>';
1896 // if scalar
1897 } else {
1898 $buffer .= "<input type='text' name='parameters[$name]'>";
1899 }
1900 } else {
1901 $buffer .= "<input type='text' name='parameters[$name]'>";
1902 }
1903 return $buffer;
1904 }
1905
1947 public function addComplexType($name, $typeClass = 'complexType', $phpType = 'array', $compositor = '', $restrictionBase = '', $elements = array(), $attrs = array(), $arrayType = '')
1948 {
1949 $this->complexTypes[$name] = array(
1950 'name' => $name,
1951 'typeClass' => $typeClass,
1952 'phpType' => $phpType,
1953 'compositor' => $compositor,
1954 'restrictionBase' => $restrictionBase,
1955 'elements' => $elements,
1956 'attrs' => $attrs,
1957 'arrayType' => $arrayType
1958 );
1959
1960 $this->xdebug("addComplexType $name:");
1961 $this->appendDebug($this->varDump($this->complexTypes[$name]));
1962 }
1963
1976 public function addSimpleType($name, $restrictionBase = '', $typeClass = 'simpleType', $phpType = 'scalar', $enumeration = array())
1977 {
1978 $this->simpleTypes[$name] = array(
1979 'name' => $name,
1980 'typeClass' => $typeClass,
1981 'phpType' => $phpType,
1982 'type' => $restrictionBase,
1983 'enumeration' => $enumeration
1984 );
1985
1986 $this->xdebug("addSimpleType $name:");
1987 $this->appendDebug($this->varDump($this->simpleTypes[$name]));
1988 }
1989
1997 public function addElement($attrs)
1998 {
1999 if (! $this->getPrefix($attrs['type'])) {
2000 $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
2001 }
2002 $this->elements[ $attrs['name'] ] = $attrs;
2003 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
2004
2005 $this->xdebug("addElement " . $attrs['name']);
2006 $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
2007 }
2008}
2009
2013class XMLSchema extends nusoap_xmlschema
2014{
2015}
2016
2017?><?php
2018
2019
2020
2032class soapval extends nusoap_base
2033{
2040 public $name;
2047 public $type;
2054 public $value;
2061 public $element_ns;
2068 public $type_ns;
2075 public $attributes;
2076
2088 public function __construct($name = 'soapval', $type = false, $value = -1, $element_ns = false, $type_ns = false, $attributes = false)
2089 {
2091 $this->name = $name;
2092 $this->type = $type;
2093 $this->value = $value;
2094 $this->element_ns = $element_ns;
2095 $this->type_ns = $type_ns;
2096 $this->attributes = $attributes;
2097 }
2098
2106 public function serialize($use = 'encoded')
2107 {
2108 return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
2109 }
2110
2117 public function decode()
2118 {
2119 return $this->value;
2120 }
2121}
2122
2123
2124
2125?><?php
2126
2127
2128
2138class soap_transport_http extends nusoap_base
2139{
2140 public $fp;
2141 public $tryagain;
2142 public $url = '';
2143 public $uri = '';
2144 public $digest_uri = '';
2145 public $scheme = '';
2146 public $host = '';
2147 public $port = '';
2148 public $path = '';
2149 public $request_method = 'POST';
2150 public $protocol_version = '1.0';
2151 public $encoding = '';
2152 public $outgoing_headers = array();
2153 public $incoming_headers = array();
2154 public $incoming_cookies = array();
2155 public $outgoing_payload = '';
2156 public $incoming_payload = '';
2157 public $response_status_line; // HTTP response status line
2158 public $useSOAPAction = true;
2159 public $persistentConnection = false;
2160 public $ch = false; // cURL handle
2161 public $ch_options = array(); // cURL custom options
2162 public $use_curl = false; // force cURL use
2163 public $proxy = null; // proxy information (associative array)
2164 public $username = '';
2165 public $password = '';
2166 public $authtype = '';
2167 public $digestRequest = array();
2168 public $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional)
2169 // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
2170 // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
2171 // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
2172 // passphrase: SSL key password/passphrase
2173 // certpassword: SSL certificate password
2174 // verifypeer: default is 1
2175 // verifyhost: default is 1
2176
2185 public function __construct($url, $curl_options = null, $use_curl = false)
2186 {
2188 $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
2189 $this->appendDebug($this->varDump($curl_options));
2190 $this->setURL($url);
2191 if (is_array($curl_options)) {
2192 $this->ch_options = $curl_options;
2193 }
2194 $this->use_curl = $use_curl;
2195 preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
2196 // begin-patch php8
2197 $this->setHeader('User-Agent', $this->title . '/' . $this->version . ' (' . ($rev[1] ?? '1.1') . ')');
2198 }
2199
2207 public function setCurlOption($option, $value)
2208 {
2209 $this->debug("setCurlOption option=$option, value=");
2210 $this->appendDebug($this->varDump($value));
2211 curl_setopt($this->ch, $option, $value);
2212 }
2213
2221 public function setHeader($name, $value)
2222 {
2223 $this->outgoing_headers[$name] = $value;
2224 $this->debug("set header $name: $value");
2225 }
2226
2233 public function unsetHeader($name)
2234 {
2235 if (isset($this->outgoing_headers[$name])) {
2236 $this->debug("unset header $name");
2237 unset($this->outgoing_headers[$name]);
2238 }
2239 }
2240
2247 public function setURL($url)
2248 {
2249 $this->url = $url;
2250
2251 $u = parse_url($url);
2252 foreach ($u as $k => $v) {
2253 $this->debug("parsed URL $k = $v");
2254 $this->$k = $v;
2255 }
2256
2257 // add any GET params to path
2258 if (isset($u['query']) && $u['query'] != '') {
2259 $this->path .= '?' . $u['query'];
2260 }
2261
2262 // set default port
2263 if (!isset($u['port'])) {
2264 if ($u['scheme'] == 'https') {
2265 $this->port = 443;
2266 } else {
2267 $this->port = 80;
2268 }
2269 }
2270
2271 $this->uri = $this->path;
2272 $this->digest_uri = $this->uri;
2273
2274 // build headers
2275 if (!isset($u['port'])) {
2276 $this->setHeader('Host', $this->host);
2277 } else {
2278 $this->setHeader('Host', $this->host . ':' . $this->port);
2279 }
2280
2281 if (isset($u['user']) && $u['user'] != '') {
2282 $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
2283 }
2284 }
2285
2292 public function io_method()
2293 {
2294 if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm')) {
2295 return 'curl';
2296 }
2297 if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm')) {
2298 return 'socket';
2299 }
2300 return 'unknown';
2301 }
2302
2311 public function connect($connection_timeout = 0, $response_timeout = 30)
2312 {
2313 // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
2314 // "regular" socket.
2315 // TODO: disabled for now because OpenSSL must be *compiled* in (not just
2316 // loaded), and until PHP5 stream_get_wrappers is not available.
2317 // if ($this->scheme == 'https') {
2318 // if (version_compare(phpversion(), '4.3.0') >= 0) {
2319 // if (extension_loaded('openssl')) {
2320 // $this->scheme = 'ssl';
2321 // $this->debug('Using SSL over OpenSSL');
2322 // }
2323 // }
2324 // }
2325 $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2326 if ($this->io_method() == 'socket') {
2327 if (!is_array($this->proxy)) {
2330 } else {
2331 $host = $this->proxy['host'];
2332 $port = $this->proxy['port'];
2333 }
2334
2335 // use persistent connection
2336 if ($this->persistentConnection && isset($this->fp) && is_resource($this->fp)) {
2337 if (!feof($this->fp)) {
2338 $this->debug('Re-use persistent connection');
2339 return true;
2340 }
2341 fclose($this->fp);
2342 $this->debug('Closed persistent connection at EOF');
2343 }
2344
2345 // munge host if using OpenSSL
2346 if ($this->scheme == 'ssl') {
2347 $host = 'ssl://' . $host;
2348 }
2349 $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
2350
2351 // open socket
2352 if ($connection_timeout > 0) {
2353 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2354 } else {
2355 $this->fp = @fsockopen($host, $this->port, $this->errno, $this->error_str);
2356 }
2357
2358 // test pointer
2359 if (!$this->fp) {
2360 $msg = 'Couldn\'t open socket connection to server ' . $this->url;
2361 if ($this->errno) {
2362 $msg .= ', Error (' . $this->errno . '): ' . $this->error_str;
2363 } else {
2364 $msg .= ' prior to connect(). This is often a problem looking up the host name.';
2365 }
2366 $this->debug($msg);
2367 $this->setError($msg);
2368 return false;
2369 }
2370
2371 // set response timeout
2372 $this->debug('set response timeout to ' . $response_timeout);
2373 socket_set_timeout($this->fp, $response_timeout);
2374
2375 $this->debug('socket connected');
2376 return true;
2377 } elseif ($this->io_method() == 'curl') {
2378 if (!extension_loaded('curl')) {
2379 // $this->setError('cURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
2380 $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.');
2381 return false;
2382 }
2383 // Avoid warnings when PHP does not have these options
2384 if (defined('CURLOPT_CONNECTIONTIMEOUT')) {
2385 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2386 } else {
2387 $CURLOPT_CONNECTIONTIMEOUT = 78;
2388 }
2389 if (defined('CURLOPT_HTTPAUTH')) {
2390 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2391 } else {
2392 $CURLOPT_HTTPAUTH = 107;
2393 }
2394 if (defined('CURLOPT_PROXYAUTH')) {
2395 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2396 } else {
2397 $CURLOPT_PROXYAUTH = 111;
2398 }
2399 if (defined('CURLAUTH_BASIC')) {
2400 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2401 } else {
2402 $CURLAUTH_BASIC = 1;
2403 }
2404 if (defined('CURLAUTH_DIGEST')) {
2405 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2406 } else {
2407 $CURLAUTH_DIGEST = 2;
2408 }
2409 if (defined('CURLAUTH_NTLM')) {
2410 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2411 } else {
2412 $CURLAUTH_NTLM = 8;
2413 }
2414
2415 $this->debug('connect using cURL');
2416 // init CURL
2417 $this->ch = curl_init();
2418 // set url
2419 $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
2420 // add path
2421 $hostURL .= $this->path;
2422 $this->setCurlOption(CURLOPT_URL, $hostURL);
2423 // follow location headers (re-directs)
2424 if (ini_get('safe_mode') || ini_get('open_basedir')) {
2425 $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2426 $this->debug('safe_mode = ');
2427 $this->appendDebug($this->varDump(ini_get('safe_mode')));
2428 $this->debug('open_basedir = ');
2429 $this->appendDebug($this->varDump(ini_get('open_basedir')));
2430 } else {
2431 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2432 }
2433 // ask for headers in the response output
2434 $this->setCurlOption(CURLOPT_HEADER, 1);
2435 // ask for the response output as the return value
2436 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2437 // encode
2438 // We manage this ourselves through headers and encoding
2439 // if(function_exists('gzuncompress')){
2440 // $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
2441 // }
2442 // persistent connection
2443 if ($this->persistentConnection) {
2444 // I believe the following comment is now bogus, having applied to
2445 // the code when it used CURLOPT_CUSTOMREQUEST to send the request.
2446 // The way we send data, we cannot use persistent connections, since
2447 // there will be some "junk" at the end of our request.
2448 //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
2449 $this->persistentConnection = false;
2450 $this->setHeader('Connection', 'close');
2451 }
2452 // set timeouts
2453 if ($connection_timeout != 0) {
2454 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2455 }
2456 if ($response_timeout != 0) {
2457 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2458 }
2459
2460 if ($this->scheme == 'https') {
2461 $this->debug('set cURL SSL verify options');
2462 // recent versions of cURL turn on peer/host checking by default,
2463 // while PHP binaries are not compiled with a default location for the
2464 // CA cert bundle, so disable peer/host checking.
2465 //$this->setCurlOption(CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
2466 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2467 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2468
2469 // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
2470 if ($this->authtype == 'certificate') {
2471 $this->debug('set cURL certificate options');
2472 if (isset($this->certRequest['cainfofile'])) {
2473 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
2474 }
2475 if (isset($this->certRequest['verifypeer'])) {
2476 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
2477 } else {
2478 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2479 }
2480 if (isset($this->certRequest['verifyhost'])) {
2481 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
2482 } else {
2483 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2484 }
2485 if (isset($this->certRequest['sslcertfile'])) {
2486 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
2487 }
2488 if (isset($this->certRequest['sslkeyfile'])) {
2489 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
2490 }
2491 if (isset($this->certRequest['passphrase'])) {
2492 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
2493 }
2494 if (isset($this->certRequest['certpassword'])) {
2495 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
2496 }
2497 }
2498 }
2499 if ($this->authtype && ($this->authtype != 'certificate')) {
2500 if ($this->username) {
2501 $this->debug('set cURL username/password');
2502 $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
2503 }
2504 if ($this->authtype == 'basic') {
2505 $this->debug('set cURL for Basic authentication');
2506 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2507 }
2508 if ($this->authtype == 'digest') {
2509 $this->debug('set cURL for digest authentication');
2510 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2511 }
2512 if ($this->authtype == 'ntlm') {
2513 $this->debug('set cURL for NTLM authentication');
2514 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2515 }
2516 }
2517 if (is_array($this->proxy)) {
2518 $this->debug('set cURL proxy options');
2519 if ($this->proxy['port'] != '') {
2520 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'] . ':' . $this->proxy['port']);
2521 } else {
2522 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
2523 }
2524 if ($this->proxy['username'] || $this->proxy['password']) {
2525 $this->debug('set cURL proxy authentication options');
2526 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'] . ':' . $this->proxy['password']);
2527 if ($this->proxy['authtype'] == 'basic') {
2528 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2529 }
2530 if ($this->proxy['authtype'] == 'ntlm') {
2531 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2532 }
2533 }
2534 }
2535 $this->debug('cURL connection set up');
2536 return true;
2537 } else {
2538 $this->setError('Unknown scheme ' . $this->scheme);
2539 $this->debug('Unknown scheme ' . $this->scheme);
2540 return false;
2541 }
2542 }
2543
2554 public function send($data, $timeout = 0, $response_timeout = 30, $cookies = null)
2555 {
2556 $this->debug('entered send() with data of length: ' . strlen($data));
2557
2558 $this->tryagain = true;
2559 $tries = 0;
2560 while ($this->tryagain) {
2561 $this->tryagain = false;
2562 if ($tries++ < 2) {
2563 // make connnection
2564 if (!$this->connect($timeout, $response_timeout)) {
2565 return false;
2566 }
2567
2568 // send request
2569 if (!$this->sendRequest($data, $cookies)) {
2570 return false;
2571 }
2572
2573 // get response
2574 $respdata = $this->getResponse();
2575 } else {
2576 $this->setError("Too many tries to get an OK response ($this->response_status_line)");
2577 }
2578 }
2579 $this->debug('end of send()');
2580 return $respdata;
2581 }
2582
2583
2595 public function sendHTTPS($data, $timeout = 0, $response_timeout = 30, $cookies = null)
2596 {
2597 return $this->send($data, $timeout, $response_timeout, $cookies);
2598 }
2599
2610 public function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array())
2611 {
2612 $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
2613 $this->appendDebug($this->varDump($digestRequest));
2614 $this->debug("certRequest=");
2615 $this->appendDebug($this->varDump($certRequest));
2616 // cf. RFC 2617
2617 if ($authtype == 'basic') {
2618 $this->setHeader('Authorization', 'Basic ' . base64_encode(str_replace(':', '', $username) . ':' . $password));
2619 } elseif ($authtype == 'digest') {
2620 if (isset($digestRequest['nonce'])) {
2621 $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
2622
2623 // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
2624
2625 // A1 = unq(username-value) ":" unq(realm-value) ":" passwd
2626 $A1 = $username . ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
2627
2628 // H(A1) = MD5(A1)
2629 $HA1 = md5($A1);
2630
2631 // A2 = Method ":" digest-uri-value
2632 $A2 = $this->request_method . ':' . $this->digest_uri;
2633
2634 // H(A2)
2635 $HA2 = md5($A2);
2636
2637 // KD(secret, data) = H(concat(secret, ":", data))
2638 // if qop == auth:
2639 // request-digest = <"> < KD ( H(A1), unq(nonce-value)
2640 // ":" nc-value
2641 // ":" unq(cnonce-value)
2642 // ":" unq(qop-value)
2643 // ":" H(A2)
2644 // ) <">
2645 // if qop is missing,
2646 // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
2647
2648 $unhashedDigest = '';
2649 $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
2650 $cnonce = $nonce;
2651 if ($digestRequest['qop'] != '') {
2652 $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
2653 } else {
2654 $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
2655 }
2656
2657 $hashedDigest = md5($unhashedDigest);
2658
2659 $opaque = '';
2660 if (isset($digestRequest['opaque'])) {
2661 $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
2662 }
2663
2664 $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 . '"');
2665 }
2666 } elseif ($authtype == 'certificate') {
2667 $this->certRequest = $certRequest;
2668 $this->debug('Authorization header not set for certificate');
2669 } elseif ($authtype == 'ntlm') {
2670 // do nothing
2671 $this->debug('Authorization header not set for ntlm');
2672 }
2673 $this->username = $username;
2674 $this->password = $password;
2675 $this->authtype = $authtype;
2676 $this->digestRequest = $digestRequest;
2677 }
2678
2685 public function setSOAPAction($soapaction)
2686 {
2687 $this->setHeader('SOAPAction', '"' . $soapaction . '"');
2688 }
2689
2696 public function setEncoding($enc = 'gzip, deflate')
2697 {
2698 if (function_exists('gzdeflate')) {
2699 $this->protocol_version = '1.1';
2700 $this->setHeader('Accept-Encoding', $enc);
2701 if (!isset($this->outgoing_headers['Connection'])) {
2702 $this->setHeader('Connection', 'close');
2703 $this->persistentConnection = false;
2704 }
2705 #set_magic_quotes_runtime(0);
2706 // deprecated
2707 $this->encoding = $enc;
2708 }
2709 }
2710
2721 public function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic')
2722 {
2723 if ($proxyhost) {
2724 $this->proxy = array(
2725 'host' => $proxyhost,
2726 'port' => $proxyport,
2727 'username' => $proxyusername,
2728 'password' => $proxypassword,
2729 'authtype' => $proxyauthtype
2730 );
2731 if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
2732 $this->setHeader('Proxy-Authorization', ' Basic ' . base64_encode($proxyusername . ':' . $proxypassword));
2733 }
2734 } else {
2735 $this->debug('remove proxy');
2736 $proxy = null;
2737 unsetHeader('Proxy-Authorization');
2738 }
2739 }
2740
2741
2750 public function isSkippableCurlHeader(&$data)
2751 {
2752 $skipHeaders = array( 'HTTP/1.1 100',
2753 'HTTP/1.0 301',
2754 'HTTP/1.1 301',
2755 'HTTP/1.0 302',
2756 'HTTP/1.1 302',
2757 'HTTP/1.0 401',
2758 'HTTP/1.1 401',
2759 'HTTP/1.0 200 Connection established');
2760 foreach ($skipHeaders as $hd) {
2761 $prefix = substr($data, 0, strlen($hd));
2762 if ($prefix == $hd) {
2763 return true;
2764 }
2765 }
2766
2767 return false;
2768 }
2769
2780 public function decodeChunked($buffer, $lb)
2781 {
2782 // length := 0
2783 $length = 0;
2784 $new = '';
2785
2786 // read chunk-size, chunk-extension (if any) and CRLF
2787 // get the position of the linebreak
2788 $chunkend = strpos($buffer, $lb);
2789 if ($chunkend == false) {
2790 $this->debug('no linebreak found in decodeChunked');
2791 return $new;
2792 }
2793 $temp = substr($buffer, 0, $chunkend);
2794 $chunk_size = hexdec(trim($temp));
2795 $chunkstart = $chunkend + strlen($lb);
2796 // while (chunk-size > 0) {
2797 while ($chunk_size > 0) {
2798 $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
2799 $chunkend = strpos($buffer, $lb, $chunkstart + $chunk_size);
2800
2801 // Just in case we got a broken connection
2802 if ($chunkend == false) {
2803 $chunk = substr($buffer, $chunkstart);
2804 // append chunk-data to entity-body
2805 $new .= $chunk;
2806 $length += strlen($chunk);
2807 break;
2808 }
2809
2810 // read chunk-data and CRLF
2811 $chunk = substr($buffer, $chunkstart, $chunkend - $chunkstart);
2812 // append chunk-data to entity-body
2813 $new .= $chunk;
2814 // length := length + chunk-size
2815 $length += strlen($chunk);
2816 // read chunk-size and CRLF
2817 $chunkstart = $chunkend + strlen($lb);
2818
2819 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2820 if ($chunkend == false) {
2821 break; //Just in case we got a broken connection
2822 }
2823 $temp = substr($buffer, $chunkstart, $chunkend - $chunkstart);
2824 $chunk_size = hexdec(trim($temp));
2825 $chunkstart = $chunkend;
2826 }
2827 return $new;
2828 }
2829
2838 public function buildPayload($data, $cookie_str = '')
2839 {
2840 // Note: for cURL connections, $this->outgoing_payload is ignored,
2841 // as is the Content-Length header, but these are still created as
2842 // debugging guides.
2843
2844 // add content-length header
2845 $this->setHeader('Content-Length', strlen($data));
2846
2847 // start building outgoing payload:
2848 if ($this->proxy) {
2849 $uri = $this->url;
2850 } else {
2851 $uri = $this->uri;
2852 }
2853 $req = "$this->request_method $uri HTTP/$this->protocol_version";
2854 $this->debug("HTTP request: $req");
2855 $this->outgoing_payload = "$req\r\n";
2856
2857 // loop thru headers, serializing
2858 foreach ($this->outgoing_headers as $k => $v) {
2859 $hdr = $k . ': ' . $v;
2860 $this->debug("HTTP header: $hdr");
2861 $this->outgoing_payload .= "$hdr\r\n";
2862 }
2863
2864 // add any cookies
2865 if ($cookie_str != '') {
2866 $hdr = 'Cookie: ' . $cookie_str;
2867 $this->debug("HTTP header: $hdr");
2868 $this->outgoing_payload .= "$hdr\r\n";
2869 }
2870
2871 // header/body separator
2872 $this->outgoing_payload .= "\r\n";
2873
2874 // add data
2875 $this->outgoing_payload .= $data;
2876 }
2877
2886 public function sendRequest($data, $cookies = null)
2887 {
2888 // build cookie string
2889 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
2890
2891 // build payload
2892 $this->buildPayload($data, $cookie_str);
2893
2894 if ($this->io_method() == 'socket') {
2895 // send payload
2896 if (!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2897 $this->setError('couldn\'t write message data to socket');
2898 $this->debug('couldn\'t write message data to socket');
2899 return false;
2900 }
2901 $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
2902 return true;
2903 } elseif ($this->io_method() == 'curl') {
2904 // set payload
2905 // cURL does say this should only be the verb, and in fact it
2906 // turns out that the URI and HTTP version are appended to this, which
2907 // some servers refuse to work with (so we no longer use this method!)
2908 //$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
2909 $curl_headers = array();
2910 foreach ($this->outgoing_headers as $k => $v) {
2911 if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
2912 $this->debug("Skip cURL header $k: $v");
2913 } else {
2914 $curl_headers[] = "$k: $v";
2915 }
2916 }
2917 if ($cookie_str != '') {
2918 $curl_headers[] = 'Cookie: ' . $cookie_str;
2919 }
2920 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2921 $this->debug('set cURL HTTP headers');
2922 if ($this->request_method == "POST") {
2923 $this->setCurlOption(CURLOPT_POST, 1);
2924 $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
2925 $this->debug('set cURL POST data');
2926 } else {
2927 }
2928 // insert custom user-set cURL options
2929 foreach ($this->ch_options as $key => $val) {
2930 $this->setCurlOption($key, $val);
2931 }
2932
2933 $this->debug('set cURL payload');
2934 return true;
2935 }
2936 }
2937
2944 public function getResponse()
2945 {
2946 $this->incoming_payload = '';
2947
2948 if ($this->io_method() == 'socket') {
2949 // loop until headers have been retrieved
2950 $data = '';
2951 while (!isset($lb)) {
2952 // We might EOF during header read.
2953 if (feof($this->fp)) {
2954 $this->incoming_payload = $data;
2955 $this->debug('found no headers before EOF after length ' . strlen($data));
2956 $this->debug("received before EOF:\n" . $data);
2957 $this->setError('server failed to send headers');
2958 return false;
2959 }
2960
2961 $tmp = fgets($this->fp, 256);
2962 $tmplen = strlen($tmp);
2963 $this->debug("read line of $tmplen bytes: " . trim($tmp));
2964
2965 if ($tmplen == 0) {
2966 $this->incoming_payload = $data;
2967 $this->debug('socket read of headers timed out after length ' . strlen($data));
2968 $this->debug("read before timeout: " . $data);
2969 $this->setError('socket read of headers timed out');
2970 return false;
2971 }
2972
2973 $data .= $tmp;
2974 $pos = strpos($data, "\r\n\r\n");
2975 if ($pos > 1) {
2976 $lb = "\r\n";
2977 } else {
2978 $pos = strpos($data, "\n\n");
2979 if ($pos > 1) {
2980 $lb = "\n";
2981 }
2982 }
2983 // remove 100 headers
2984 if (isset($lb) && preg_match('/^HTTP\/1.1 100/', $data)) {
2985 unset($lb);
2986 $data = '';
2987 }//
2988 }
2989 // store header data
2990 $this->incoming_payload .= $data;
2991 $this->debug('found end of headers after length ' . strlen($data));
2992 // process headers
2993 $header_data = trim(substr($data, 0, $pos));
2994 $header_array = explode($lb, $header_data);
2995 $this->incoming_headers = array();
2996 $this->incoming_cookies = array();
2997 foreach ($header_array as $header_line) {
2998 $arr = explode(':', $header_line, 2);
2999 if (count($arr) > 1) {
3000 $header_name = strtolower(trim($arr[0]));
3001 $this->incoming_headers[$header_name] = trim($arr[1]);
3002 if ($header_name == 'set-cookie') {
3003 // TODO: allow multiple cookies from parseCookie
3004 $cookie = $this->parseCookie(trim($arr[1]));
3005 if ($cookie) {
3006 $this->incoming_cookies[] = $cookie;
3007 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3008 } else {
3009 $this->debug('did not find cookie in ' . trim($arr[1]));
3010 }
3011 }
3012 } elseif (isset($header_name)) {
3013 // append continuation line to previous header
3014 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3015 }
3016 }
3017
3018 // loop until msg has been received
3019 if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
3020 $content_length = 2147483647; // ignore any content-length header
3021 $chunked = true;
3022 $this->debug("want to read chunked content");
3023 } elseif (isset($this->incoming_headers['content-length'])) {
3024 $content_length = $this->incoming_headers['content-length'];
3025 $chunked = false;
3026 $this->debug("want to read content of length $content_length");
3027 } else {
3028 $content_length = 2147483647;
3029 $chunked = false;
3030 $this->debug("want to read content to EOF");
3031 }
3032 $data = '';
3033 do {
3034 if ($chunked) {
3035 $tmp = fgets($this->fp, 256);
3036 $tmplen = strlen($tmp);
3037 $this->debug("read chunk line of $tmplen bytes");
3038 if ($tmplen == 0) {
3039 $this->incoming_payload = $data;
3040 $this->debug('socket read of chunk length timed out after length ' . strlen($data));
3041 $this->debug("read before timeout:\n" . $data);
3042 $this->setError('socket read of chunk length timed out');
3043 return false;
3044 }
3045 $content_length = hexdec(trim($tmp));
3046 $this->debug("chunk length $content_length");
3047 }
3048 $strlen = 0;
3049 while (($strlen < $content_length) && (!feof($this->fp))) {
3050 $readlen = min(8192, $content_length - $strlen);
3051 $tmp = fread($this->fp, $readlen);
3052 $tmplen = strlen($tmp);
3053 $this->debug("read buffer of $tmplen bytes");
3054 if (($tmplen == 0) && (!feof($this->fp))) {
3055 $this->incoming_payload = $data;
3056 $this->debug('socket read of body timed out after length ' . strlen($data));
3057 $this->debug("read before timeout:\n" . $data);
3058 $this->setError('socket read of body timed out');
3059 return false;
3060 }
3061 $strlen += $tmplen;
3062 $data .= $tmp;
3063 }
3064 if ($chunked && ($content_length > 0)) {
3065 $tmp = fgets($this->fp, 256);
3066 $tmplen = strlen($tmp);
3067 $this->debug("read chunk terminator of $tmplen bytes");
3068 if ($tmplen == 0) {
3069 $this->incoming_payload = $data;
3070 $this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
3071 $this->debug("read before timeout:\n" . $data);
3072 $this->setError('socket read of chunk terminator timed out');
3073 return false;
3074 }
3075 }
3076 } while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3077 if (feof($this->fp)) {
3078 $this->debug('read to EOF');
3079 }
3080 $this->debug('read body of length ' . strlen($data));
3081 $this->incoming_payload .= $data;
3082 $this->debug('received a total of ' . strlen($this->incoming_payload) . ' bytes of data from server');
3083
3084 // close filepointer
3085 if (
3086 (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') ||
3087 (! $this->persistentConnection) || feof($this->fp)) {
3088 fclose($this->fp);
3089 $this->fp = false;
3090 $this->debug('closed socket');
3091 }
3092
3093 // connection was closed unexpectedly
3094 if ($this->incoming_payload == '') {
3095 $this->setError('no response from server');
3096 return false;
3097 }
3098
3099 // decode transfer-encoding
3100 // if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
3101 // if(!$data = $this->decodeChunked($data, $lb)){
3102 // $this->setError('Decoding of chunked data failed');
3103 // return false;
3104 // }
3105 //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
3106 // set decoded payload
3107 // $this->incoming_payload = $header_data.$lb.$lb.$data;
3108 // }
3109 } elseif ($this->io_method() == 'curl') {
3110 // send and receive
3111 $this->debug('send and receive with cURL');
3112 $this->incoming_payload = curl_exec($this->ch);
3114
3115 $cErr = curl_error($this->ch);
3116 if ($cErr != '') {
3117 $err = 'cURL ERROR: ' . curl_errno($this->ch) . ': ' . $cErr . '<br>';
3118 // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
3119 foreach (curl_getinfo($this->ch) as $k => $v) {
3120 $err .= "$k: $v<br>";
3121 }
3122 $this->debug($err);
3123 $this->setError($err);
3124 $this->ch = null;
3125 return false;
3126 } else {
3127 //echo '<pre>';
3128 //var_dump(curl_getinfo($this->ch));
3129 //echo '</pre>';
3130 }
3131 // close curl
3132 $this->debug('No cURL error, closing cURL');
3133 $this->ch = null;
3134
3135 // try removing skippable headers
3136 $savedata = $data;
3137 while ($this->isSkippableCurlHeader($data)) {
3138 $this->debug("Found HTTP header to skip");
3139 if ($pos = strpos($data, "\r\n\r\n")) {
3140 $data = ltrim(substr($data, $pos));
3141 } elseif ($pos = strpos($data, "\n\n")) {
3142 $data = ltrim(substr($data, $pos));
3143 }
3144 }
3145
3146 if ($data == '') {
3147 // have nothing left; just remove 100 header(s)
3148 $data = $savedata;
3149 while (preg_match('/^HTTP\/1.1 100/', $data)) {
3150 if ($pos = strpos($data, "\r\n\r\n")) {
3151 $data = ltrim(substr($data, $pos));
3152 } elseif ($pos = strpos($data, "\n\n")) {
3153 $data = ltrim(substr($data, $pos));
3154 }
3155 }
3156 }
3157
3158 // separate content from HTTP headers
3159 if ($pos = strpos($data, "\r\n\r\n")) {
3160 $lb = "\r\n";
3161 } elseif ($pos = strpos($data, "\n\n")) {
3162 $lb = "\n";
3163 } else {
3164 $this->debug('no proper separation of headers and document');
3165 $this->setError('no proper separation of headers and document');
3166 return false;
3167 }
3168 $header_data = trim(substr($data, 0, $pos));
3169 $header_array = explode($lb, $header_data);
3170 $data = ltrim(substr($data, $pos));
3171 $this->debug('found proper separation of headers and document');
3172 $this->debug('cleaned data, stringlen: ' . strlen($data));
3173 // clean headers
3174 foreach ($header_array as $header_line) {
3175 $arr = explode(':', $header_line, 2);
3176 if (count($arr) > 1) {
3177 $header_name = strtolower(trim($arr[0]));
3178 $this->incoming_headers[$header_name] = trim($arr[1]);
3179 if ($header_name == 'set-cookie') {
3180 // TODO: allow multiple cookies from parseCookie
3181 $cookie = $this->parseCookie(trim($arr[1]));
3182 if ($cookie) {
3183 $this->incoming_cookies[] = $cookie;
3184 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3185 } else {
3186 $this->debug('did not find cookie in ' . trim($arr[1]));
3187 }
3188 }
3189 } elseif (isset($header_name)) {
3190 // append continuation line to previous header
3191 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3192 }
3193 }
3194 }
3195
3196 $this->response_status_line = $header_array[0];
3197 $arr = explode(' ', $this->response_status_line, 3);
3198 $http_version = $arr[0];
3199 $http_status = intval($arr[1]);
3200 $http_reason = count($arr) > 2 ? $arr[2] : '';
3201
3202 // see if we need to resend the request with http digest authentication
3203 if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
3204 $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
3205 $this->setURL($this->incoming_headers['location']);
3206 $this->tryagain = true;
3207 return false;
3208 }
3209
3210 // see if we need to resend the request with http digest authentication
3211 if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
3212 $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
3213 if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
3214 $this->debug('Server wants digest authentication');
3215 // remove "Digest " from our elements
3216 $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
3217
3218 // parse elements into array
3219 $digestElements = explode(',', $digestString);
3220 foreach ($digestElements as $val) {
3221 $tempElement = explode('=', trim($val), 2);
3222 $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
3223 }
3224
3225 // should have (at least) qop, realm, nonce
3226 if (isset($digestRequest['nonce'])) {
3227 $this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
3228 $this->tryagain = true;
3229 return false;
3230 }
3231 }
3232 $this->debug('HTTP authentication failed');
3233 $this->setError('HTTP authentication failed');
3234 return false;
3235 }
3236
3237 if (
3238 ($http_status >= 300 && $http_status <= 307) ||
3239 ($http_status >= 400 && $http_status <= 417) ||
3240 ($http_status >= 501 && $http_status <= 505)
3241 ) {
3242 $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3243 return false;
3244 }
3245
3246 // decode content-encoding
3247 if (isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != '') {
3248 if (strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip') {
3249 // if decoding works, use it. else assume data wasn't gzencoded
3250 if (function_exists('gzinflate')) {
3251 //$timer->setMarker('starting decoding of gzip/deflated content');
3252 // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
3253 // this means there are no Zlib headers, although there should be
3254 $this->debug('The gzinflate function exists');
3255 $datalen = strlen($data);
3256 if ($this->incoming_headers['content-encoding'] == 'deflate') {
3257 if ($degzdata = @gzinflate($data)) {
3258 $data = $degzdata;
3259 $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
3260 if (strlen($data) < $datalen) {
3261 // test for the case that the payload has been compressed twice
3262 $this->debug('The inflated payload is smaller than the gzipped one; try again');
3263 if ($degzdata = @gzinflate($data)) {
3264 $data = $degzdata;
3265 $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
3266 }
3267 }
3268 } else {
3269 $this->debug('Error using gzinflate to inflate the payload');
3270 $this->setError('Error using gzinflate to inflate the payload');
3271 }
3272 } elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
3273 if ($degzdata = @gzinflate(substr($data, 10))) { // do our best
3274 $data = $degzdata;
3275 $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
3276 if (strlen($data) < $datalen) {
3277 // test for the case that the payload has been compressed twice
3278 $this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
3279 if ($degzdata = @gzinflate(substr($data, 10))) {
3280 $data = $degzdata;
3281 $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
3282 }
3283 }
3284 } else {
3285 $this->debug('Error using gzinflate to un-gzip the payload');
3286 $this->setError('Error using gzinflate to un-gzip the payload');
3287 }
3288 }
3289 //$timer->setMarker('finished decoding of gzip/deflated content');
3290 //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
3291 // set decoded payload
3292 $this->incoming_payload = $header_data . $lb . $lb . $data;
3293 } else {
3294 $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3295 $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3296 }
3297 } else {
3298 $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3299 $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3300 }
3301 } else {
3302 $this->debug('No Content-Encoding header');
3303 }
3304
3305 if (strlen($data) == 0) {
3306 $this->debug('no data after headers!');
3307 $this->setError('no data present after HTTP headers');
3308 return false;
3309 }
3310
3311 return $data;
3312 }
3313
3321 public function setContentType($type, $charset = false)
3322 {
3323 $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
3324 }
3325
3332 public function usePersistentConnection()
3333 {
3334 if (isset($this->outgoing_headers['Accept-Encoding'])) {
3335 return false;
3336 }
3337 $this->protocol_version = '1.1';
3338 $this->persistentConnection = true;
3339 $this->setHeader('Connection', 'Keep-Alive');
3340 return true;
3341 }
3342
3350 /*
3351 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
3352 */
3353 public function parseCookie($cookie_str)
3354 {
3355 $cookie_str = str_replace('; ', ';', $cookie_str) . ';';
3356 // begin-patch php8
3357 //$data = split(';', $cookie_str);
3358 $data = explode(';', $cookie_str);
3359 $value_str = $data[0];
3360
3361 $cookie_param = 'domain=';
3362 $start = strpos($cookie_str, $cookie_param);
3363 if ($start > 0) {
3364 $domain = substr($cookie_str, $start + strlen($cookie_param));
3365 $domain = substr($domain, 0, strpos($domain, ';'));
3366 } else {
3367 $domain = '';
3368 }
3369
3370 $cookie_param = 'expires=';
3371 $start = strpos($cookie_str, $cookie_param);
3372 if ($start > 0) {
3373 $expires = substr($cookie_str, $start + strlen($cookie_param));
3374 $expires = substr($expires, 0, strpos($expires, ';'));
3375 } else {
3376 $expires = '';
3377 }
3378
3379 $cookie_param = 'path=';
3380 $start = strpos($cookie_str, $cookie_param);
3381 if ($start > 0) {
3382 $path = substr($cookie_str, $start + strlen($cookie_param));
3383 $path = substr($path, 0, strpos($path, ';'));
3384 } else {
3385 $path = '/';
3386 }
3387
3388 $cookie_param = ';secure;';
3389 if (strpos($cookie_str, $cookie_param) !== false) {
3390 $secure = true;
3391 } else {
3392 $secure = false;
3393 }
3394
3395 $sep_pos = strpos($value_str, '=');
3396
3397 if ($sep_pos) {
3398 $name = substr($value_str, 0, $sep_pos);
3399 $value = substr($value_str, $sep_pos + 1);
3400 $cookie = array( 'name' => $name,
3401 'value' => $value,
3402 'domain' => $domain,
3403 'path' => $path,
3404 'expires' => $expires,
3405 'secure' => $secure
3406 );
3407 return $cookie;
3408 }
3409 return false;
3410 }
3411
3420 public function getCookiesForRequest($cookies, $secure = false)
3421 {
3422 $cookie_str = '';
3423 if ((! is_null($cookies)) && (is_array($cookies))) {
3424 foreach ($cookies as $cookie) {
3425 if (! is_array($cookie)) {
3426 continue;
3427 }
3428 $this->debug("check cookie for validity: " . $cookie['name'] . '=' . $cookie['value']);
3429 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
3430 if (strtotime($cookie['expires']) <= time()) {
3431 $this->debug('cookie has expired');
3432 continue;
3433 }
3434 }
3435 if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
3436 $domain = preg_quote($cookie['domain']);
3437 if (! preg_match("'.*$domain$'i", $this->host)) {
3438 $this->debug('cookie has different domain');
3439 continue;
3440 }
3441 }
3442 if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
3443 $path = preg_quote($cookie['path']);
3444 if (! preg_match("'^$path.*'i", $this->path)) {
3445 $this->debug('cookie is for a different path');
3446 continue;
3447 }
3448 }
3449 if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
3450 $this->debug('cookie is secure, transport is not');
3451 continue;
3452 }
3453 $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
3454 $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
3455 }
3456 }
3457 return $cookie_str;
3458 }
3459}
3460
3461?><?php
3462
3463
3464
3475class nusoap_server extends nusoap_base
3476{
3477 public $opData;
3483 public $headers = array();
3489 public $request = '';
3495 public $requestHeaders = '';
3501 public $requestHeader = null;
3507 public $document = '';
3513 public $requestSOAP = '';
3519 public $methodURI = '';
3525 public $methodname = '';
3531 public $methodparams = array();
3537 public $SOAPAction = '';
3543 public $xml_encoding = '';
3549 public $decode_utf8 = true;
3550 public $class;
3551
3557 public $outgoing_headers = array();
3563 public $response = '';
3569 public $responseHeaders = '';
3575 public $responseSOAP = '';
3581 public $methodreturn = false;
3587 public $methodreturnisliteralxml = false;
3593 public $fault = false;
3599 public $result = 'successful';
3600
3607 public $operations = array();
3613 public $wsdl = false;
3619 public $externalWSDLURL = false;
3625 public $debug_flag = false;
3626
3627
3635 public function __construct($wsdl = false)
3636 {
3638 // turn on debugging?
3639 global $debug;
3640 global $HTTP_SERVER_VARS;
3641
3642 if (isset($_SERVER)) {
3643 $this->debug("_SERVER is defined:");
3644 $this->appendDebug($this->varDump($_SERVER));
3645 } elseif (isset($HTTP_SERVER_VARS)) {
3646 $this->debug("HTTP_SERVER_VARS is defined:");
3647 $this->appendDebug($this->varDump($HTTP_SERVER_VARS));
3648 } else {
3649 $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3650 }
3651
3652 if (isset($debug)) {
3653 $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
3654 $this->debug_flag = $debug;
3655 } elseif (isset($_SERVER['QUERY_STRING'])) {
3656 $qs = explode('&', $_SERVER['QUERY_STRING']);
3657 foreach ($qs as $v) {
3658 if (substr($v, 0, 6) == 'debug=') {
3659 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
3660 $this->debug_flag = substr($v, 6);
3661 }
3662 }
3663 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3664 $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
3665 foreach ($qs as $v) {
3666 if (substr($v, 0, 6) == 'debug=') {
3667 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
3668 $this->debug_flag = substr($v, 6);
3669 }
3670 }
3671 }
3672
3673 // wsdl
3674 if ($wsdl) {
3675 $this->debug("In nusoap_server, WSDL is specified");
3676 if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
3677 $this->wsdl = $wsdl;
3678 $this->externalWSDLURL = $this->wsdl->wsdl;
3679 $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
3680 } else {
3681 $this->debug('Create wsdl from ' . $wsdl);
3682 $this->wsdl = new wsdl($wsdl);
3683 $this->externalWSDLURL = $wsdl;
3684 }
3685 $this->appendDebug($this->wsdl->getDebug());
3686 $this->wsdl->clearDebug();
3687 if ($err = $this->wsdl->getError()) {
3688 die('WSDL ERROR: ' . $err);
3689 }
3690 }
3691 }
3692
3699 public function service($data)
3700 {
3701 global $HTTP_SERVER_VARS;
3702
3703 if (isset($_SERVER['QUERY_STRING'])) {
3704 $qs = $_SERVER['QUERY_STRING'];
3705 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3706 $qs = $HTTP_SERVER_VARS['QUERY_STRING'];
3707 } else {
3708 $qs = '';
3709 }
3710 $this->debug("In service, query string=$qs");
3711
3712 if (preg_match('/wsdl/', $qs)) {
3713 $this->debug("In service, this is a request for WSDL");
3714 if ($this->externalWSDLURL) {
3715 if (strpos($this->externalWSDLURL, "://") !== false) { // assume URL
3716 header('Location: ' . $this->externalWSDLURL);
3717 } else { // assume file
3718 header("Content-Type: text/xml\r\n");
3719 $fp = fopen($this->externalWSDLURL, 'r');
3720 fpassthru($fp);
3721 }
3722 } elseif ($this->wsdl) {
3723 header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
3724 print $this->wsdl->serialize($this->debug_flag);
3725 if ($this->debug_flag) {
3726 $this->debug('wsdl:');
3727 $this->appendDebug($this->varDump($this->wsdl));
3728 print $this->getDebugAsXMLComment();
3729 }
3730 } else {
3731 header("Content-Type: text/html; charset=ISO-8859-1\r\n");
3732 print "This service does not provide WSDL";
3733 }
3734 } elseif ($data == '' && $this->wsdl) {
3735 $this->debug("In service, there is no data, so return Web description");
3736 print $this->wsdl->webDescription();
3737 } else {
3738 $this->debug("In service, invoke the request");
3739 $this->parse_request($data);
3740 if (! $this->fault) {
3741 $this->invoke_method();
3742 }
3743 if (! $this->fault) {
3744 $this->serialize_return();
3745 }
3746 $this->send_response();
3747 }
3748 }
3749
3762 public function parse_http_headers()
3763 {
3764 global $HTTP_SERVER_VARS;
3765
3766 $this->request = '';
3767 $this->SOAPAction = '';
3768 if (function_exists('getallheaders')) {
3769 $this->debug("In parse_http_headers, use getallheaders");
3770 $headers = getallheaders();
3771 foreach ($headers as $k => $v) {
3772 $k = strtolower($k);
3773 $this->headers[$k] = $v;
3774 $this->request .= "$k: $v\r\n";
3775 $this->debug("$k: $v");
3776 }
3777 // get SOAPAction header
3778 if (isset($this->headers['soapaction'])) {
3779 $this->SOAPAction = str_replace('"', '', $this->headers['soapaction']);
3780 }
3781 // get the character encoding of the incoming request
3782 if (isset($this->headers['content-type']) && strpos($this->headers['content-type'], '=')) {
3783 $enc = str_replace('"', '', substr(strstr($this->headers["content-type"], '='), 1));
3784 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3785 $this->xml_encoding = strtoupper($enc);
3786 } else {
3787 $this->xml_encoding = 'US-ASCII';
3788 }
3789 } else {
3790 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3791 $this->xml_encoding = 'ISO-8859-1';
3792 }
3793 } elseif (isset($_SERVER) && is_array($_SERVER)) {
3794 $this->debug("In parse_http_headers, use _SERVER");
3795 foreach ($_SERVER as $k => $v) {
3796 if (substr($k, 0, 5) == 'HTTP_') {
3797 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
3798 } else {
3799 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
3800 }
3801 if ($k == 'soapaction') {
3802 // get SOAPAction header
3803 $k = 'SOAPAction';
3804 $v = str_replace('"', '', $v);
3805 $v = str_replace('\\', '', $v);
3806 $this->SOAPAction = $v;
3807 } elseif ($k == 'content-type') {
3808 // get the character encoding of the incoming request
3809 if (strpos($v, '=')) {
3810 $enc = substr(strstr($v, '='), 1);
3811 $enc = str_replace('"', '', $enc);
3812 $enc = str_replace('\\', '', $enc);
3813 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3814 $this->xml_encoding = strtoupper($enc);
3815 } else {
3816 $this->xml_encoding = 'US-ASCII';
3817 }
3818 } else {
3819 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3820 $this->xml_encoding = 'ISO-8859-1';
3821 }
3822 }
3823 $this->headers[$k] = $v;
3824 $this->request .= "$k: $v\r\n";
3825 $this->debug("$k: $v");
3826 }
3827 } elseif (is_array($HTTP_SERVER_VARS)) {
3828 $this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
3829 foreach ($HTTP_SERVER_VARS as $k => $v) {
3830 if (substr($k, 0, 5) == 'HTTP_') {
3831 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
3832 $k = strtolower(substr($k, 5));
3833 } else {
3834 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
3835 $k = strtolower($k);
3836 }
3837 if ($k == 'soapaction') {
3838 // get SOAPAction header
3839 $k = 'SOAPAction';
3840 $v = str_replace('"', '', $v);
3841 $v = str_replace('\\', '', $v);
3842 $this->SOAPAction = $v;
3843 } elseif ($k == 'content-type') {
3844 // get the character encoding of the incoming request
3845 if (strpos($v, '=')) {
3846 $enc = substr(strstr($v, '='), 1);
3847 $enc = str_replace('"', '', $enc);
3848 $enc = str_replace('\\', '', $enc);
3849 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
3850 $this->xml_encoding = strtoupper($enc);
3851 } else {
3852 $this->xml_encoding = 'US-ASCII';
3853 }
3854 } else {
3855 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3856 $this->xml_encoding = 'ISO-8859-1';
3857 }
3858 }
3859 $this->headers[$k] = $v;
3860 $this->request .= "$k: $v\r\n";
3861 $this->debug("$k: $v");
3862 }
3863 } else {
3864 $this->debug("In parse_http_headers, HTTP headers not accessible");
3865 $this->setError("HTTP headers not accessible");
3866 }
3867 }
3868
3891 public function parse_request($data = '')
3892 {
3893 $this->debug('entering parse_request()');
3894 $this->parse_http_headers();
3895 $this->debug('got character encoding: ' . $this->xml_encoding);
3896 // uncompress if necessary
3897 if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
3898 $this->debug('got content encoding: ' . $this->headers['content-encoding']);
3899 if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
3900 // if decoding works, use it. else assume data wasn't gzencoded
3901 if (function_exists('gzuncompress')) {
3902 if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
3903 $data = $degzdata;
3904 } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
3905 $data = $degzdata;
3906 } else {
3907 $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
3908 return;
3909 }
3910 } else {
3911 $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
3912 return;
3913 }
3914 }
3915 }
3916 $this->request .= "\r\n" . $data;
3917 $data = $this->parseRequest($this->headers, $data);
3918 $this->requestSOAP = $data;
3919 $this->debug('leaving parse_request');
3920 }
3921
3939 public function invoke_method()
3940 {
3941 $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
3942
3943 if ($this->wsdl) {
3944 if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
3945 $this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
3946 $this->appendDebug('opData=' . $this->varDump($this->opData));
3947 } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
3948 // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
3949 $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
3950 $this->appendDebug('opData=' . $this->varDump($this->opData));
3951 $this->methodname = $this->opData['name'];
3952 } else {
3953 $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
3954 $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
3955 return;
3956 }
3957 } else {
3958 $this->debug('in invoke_method, no WSDL to validate method');
3959 }
3960
3961 // if a . is present in $this->methodname, we see if there is a class in scope,
3962 // which could be referred to. We will also distinguish between two deliminators,
3963 // to allow methods to be called a the class or an instance
3964 $class = '';
3965 $method = '';
3966 if (strpos($this->methodname, '..') > 0) {
3967 $delim = '..';
3968 } elseif (strpos($this->methodname, '.') > 0) {
3969 $delim = '.';
3970 } else {
3971 $delim = '';
3972 }
3973
3974 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3975 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3976 // get the class and method name
3977 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3978 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3979 $this->debug("in invoke_method, class=$class method=$method delim=$delim");
3980 }
3981 // set class handler
3982 // added to support single operations
3983 if ($class == '' && $this->class != '') {
3985 $delim = "..";
3986 $method = $this->methodname;
3987 }
3988
3989 // does method exist?
3990 if ($class == '') {
3991 if (!function_exists($this->methodname)) {
3992 $this->debug("in invoke_method, function '$this->methodname' not found!");
3993 $this->result = 'fault: method not found';
3994 $this->fault('SOAP-ENV:Client', "method '$this->methodname' not defined in service");
3995 return;
3996 }
3997 } else {
3998 $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
3999 if (!in_array($method_to_compare, get_class_methods($class))) {
4000 $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
4001 $this->result = 'fault: method not found';
4002 $this->fault('SOAP-ENV:Client', "method '$this->methodname' not defined in service");
4003 return;
4004 }
4005 }
4006
4007 // evaluate message, getting back parameters
4008 // verify that request parameters match the method's signature
4009 if (! $this->verify_method($this->methodname, $this->methodparams)) {
4010 // debug
4011 $this->debug('ERROR: request not verified against method signature');
4012 $this->result = 'fault: request failed validation against method signature';
4013 // return fault
4014 $this->fault('SOAP-ENV:Client', "Operation '$this->methodname' not defined in service.");
4015 return;
4016 }
4017
4018 // if there are parameters to pass
4019 $this->debug('in invoke_method, params:');
4020 $this->appendDebug($this->varDump($this->methodparams));
4021 $this->debug("in invoke_method, calling '$this->methodname'");
4022 if (!function_exists('call_user_func_array')) {
4023 if ($class == '') {
4024 $this->debug('in invoke_method, calling function using eval()');
4025 $funcCall = "\$this->methodreturn = $this->methodname(";
4026 } else {
4027 if ($delim == '..') {
4028 $this->debug('in invoke_method, calling class method using eval()');
4029 $funcCall = "\$this->methodreturn = " . $class . "::" . $method . "(";
4030 } else {
4031 $this->debug('in invoke_method, calling instance method using eval()');
4032 // generate unique instance name
4033 $instname = "\$inst_" . time();
4034 $funcCall = $instname . " = new " . $class . "(); ";
4035 $funcCall .= "\$this->methodreturn = " . $instname . "->" . $method . "(";
4036 }
4037 }
4038 if ($this->methodparams) {
4039 foreach ($this->methodparams as $param) {
4040 if (is_array($param) || is_object($param)) {
4041 $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
4042 return;
4043 }
4044 $funcCall .= "\"$param\",";
4045 }
4046 $funcCall = substr($funcCall, 0, -1);
4047 }
4048 $funcCall .= ');';
4049 $this->debug('in invoke_method, function call: ' . $funcCall);
4050 @eval($funcCall);
4051 } else {
4052 if ($class == '') {
4053 $this->debug('in invoke_method, calling function using call_user_func_array()');
4054 $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array()
4055 } elseif ($delim == '..') {
4056 $this->debug('in invoke_method, calling class method using call_user_func_array()');
4057 $call_arg = array($class, $method);
4058 } else {
4059 $this->debug('in invoke_method, calling instance method using call_user_func_array()');
4060 $instance = new $class();
4061 $call_arg = array(&$instance, $method);
4062 }
4063 if (is_array($this->methodparams)) {
4064 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4065 } else {
4066 $this->methodreturn = call_user_func_array($call_arg, array());
4067 }
4068 }
4069 $this->debug('in invoke_method, methodreturn:');
4070 $this->appendDebug($this->varDump($this->methodreturn));
4071 $this->debug("in invoke_method, called method $this->methodname, received data of type " . gettype($this->methodreturn));
4072 }
4073
4085 public function serialize_return()
4086 {
4087 $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
4088 // if fault
4089 if (isset($this->methodreturn) && ((get_class((object) $this->methodreturn) == 'soap_fault') || (get_class((object) $this->methodreturn) == 'nusoap_fault'))) {
4090 $this->debug('got a fault object from method');
4091 $this->fault = $this->methodreturn;
4092 return;
4093 } elseif ($this->methodreturnisliteralxml) {
4094 $return_val = $this->methodreturn;
4095 // returned value(s)
4096 } else {
4097 $this->debug('got a(n) ' . gettype($this->methodreturn) . ' from method');
4098 $this->debug('serializing return value');
4099 if ($this->wsdl) {
4100 if (sizeof($this->opData['output']['parts']) > 1) {
4101 $this->debug('more than one output part, so use the method return unchanged');
4102 $opParams = $this->methodreturn;
4103 } elseif (sizeof($this->opData['output']['parts']) == 1) {
4104 $this->debug('exactly one output part, so wrap the method return in a simple array');
4105 // TODO: verify that it is not already wrapped!
4106 //foreach ($this->opData['output']['parts'] as $name => $type) {
4107 // $this->debug('wrap in element named ' . $name);
4108 //}
4109 $opParams = array($this->methodreturn);
4110 }
4111 $return_val = $this->wsdl->serializeRPCParameters($this->methodname, 'output', $opParams);
4112 $this->appendDebug($this->wsdl->getDebug());
4113 $this->wsdl->clearDebug();
4114 if ($errstr = $this->wsdl->getError()) {
4115 $this->debug('got wsdl error: ' . $errstr);
4116 $this->fault('SOAP-ENV:Server', 'unable to serialize result');
4117 return;
4118 }
4119 } else {
4120 if (isset($this->methodreturn)) {
4121 $return_val = $this->serialize_val($this->methodreturn, 'return');
4122 } else {
4123 $return_val = '';
4124 $this->debug('in absence of WSDL, assume void return for backward compatibility');
4125 }
4126 }
4127 }
4128 $this->debug('return value:');
4129 $this->appendDebug($this->varDump($return_val));
4130
4131 $this->debug('serializing response');
4132 if ($this->wsdl) {
4133 $this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
4134 if ($this->opData['style'] == 'rpc') {
4135 $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
4136 if ($this->opData['output']['use'] == 'literal') {
4137 // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
4138 $payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
4139 } else {
4140 $payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
4141 }
4142 } else {
4143 $this->debug('style is not rpc for serialization: assume document');
4144 $payload = $return_val;
4145 }
4146 } else {
4147 $this->debug('do not have WSDL for serialization: assume rpc/encoded');
4148 $payload = '<ns1:' . $this->methodname . 'Response xmlns:ns1="' . $this->methodURI . '">' . $return_val . '</ns1:' . $this->methodname . "Response>";
4149 }
4150 $this->result = 'successful';
4151 if ($this->wsdl) {
4152 //if($this->debug_flag){
4153 $this->appendDebug($this->wsdl->getDebug());
4154 // }
4155 if (isset($opData['output']['encodingStyle'])) {
4156 $encodingStyle = $opData['output']['encodingStyle'];
4157 } else {
4158 $encodingStyle = '';
4159 }
4160 // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
4161 $this->responseSOAP = $this->serializeEnvelope($payload, $this->responseHeaders, $this->wsdl->usedNamespaces, $this->opData['style'], $this->opData['output']['use'], $encodingStyle);
4162 } else {
4163 $this->responseSOAP = $this->serializeEnvelope($payload, $this->responseHeaders);
4164 }
4165 $this->debug("Leaving serialize_return");
4166 }
4167
4178 public function send_response()
4179 {
4180 $this->debug('Enter send_response');
4181 if ($this->fault) {
4182 $payload = $this->fault->serialize();
4183 $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
4184 $this->outgoing_headers[] = "Status: 500 Internal Server Error";
4185 } else {
4187 // Some combinations of PHP+Web server allow the Status
4188 // to come through as a header. Since OK is the default
4189 // just do nothing.
4190 // $this->outgoing_headers[] = "HTTP/1.0 200 OK";
4191 // $this->outgoing_headers[] = "Status: 200 OK";
4192 }
4193 // add debug data if in debug mode
4194 if (isset($this->debug_flag) && $this->debug_flag) {
4195 $payload .= $this->getDebugAsXMLComment();
4196 }
4197 $this->outgoing_headers[] = "Server: $this->title Server v$this->version";
4198 preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
4199 $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (" . $rev[1] . ")";
4200 // Let the Web server decide about this
4201 //$this->outgoing_headers[] = "Connection: Close\r\n";
4202 $payload = $this->getHTTPBody($payload);
4203 $type = $this->getHTTPContentType();
4204 $charset = $this->getHTTPContentTypeCharset();
4205 $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
4206 //begin code to compress payload - by John
4207 // NOTE: there is no way to know whether the Web server will also compress
4208 // this data.
4209 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {
4210 if (strstr($this->headers['accept-encoding'], 'gzip')) {
4211 if (function_exists('gzencode')) {
4212 if (isset($this->debug_flag) && $this->debug_flag) {
4213 $payload .= "<!-- Content being gzipped -->";
4214 }
4215 $this->outgoing_headers[] = "Content-Encoding: gzip";
4216 $payload = gzencode($payload);
4217 } else {
4218 if (isset($this->debug_flag) && $this->debug_flag) {
4219 $payload .= "<!-- Content will not be gzipped: no gzencode -->";
4220 }
4221 }
4222 } elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
4223 // Note: MSIE requires gzdeflate output (no Zlib header and checksum),
4224 // instead of gzcompress output,
4225 // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
4226 if (function_exists('gzdeflate')) {
4227 if (isset($this->debug_flag) && $this->debug_flag) {
4228 $payload .= "<!-- Content being deflated -->";
4229 }
4230 $this->outgoing_headers[] = "Content-Encoding: deflate";
4231 $payload = gzdeflate($payload);
4232 } else {
4233 if (isset($this->debug_flag) && $this->debug_flag) {
4234 $payload .= "<!-- Content will not be deflated: no gzcompress -->";
4235 }
4236 }
4237 }
4238 }
4239 //end code
4240 $this->outgoing_headers[] = "Content-Length: " . strlen($payload);
4241 reset($this->outgoing_headers);
4242 foreach ($this->outgoing_headers as $hdr) {
4243 header($hdr, false);
4244 }
4245 print $payload;
4246 $this->response = join("\r\n", $this->outgoing_headers) . "\r\n\r\n" . $payload;
4247 }
4248
4258 public function verify_method($operation, $request)
4259 {
4260 if (isset($this->wsdl) && is_object($this->wsdl)) {
4261 if ($this->wsdl->getOperationData($operation)) {
4262 return true;
4263 }
4264 } elseif (isset($this->operations[$operation])) {
4265 return true;
4266 }
4267 return false;
4268 }
4269
4278 public function parseRequest($headers, $data)
4279 {
4280 $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
4281 if (!strstr($headers['content-type'], 'text/xml')) {
4282 $this->setError('Request not of type text/xml');
4283 return false;
4284 }
4285 if (strpos($headers['content-type'], '=')) {
4286 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
4287 $this->debug('Got response encoding: ' . $enc);
4288 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
4289 $this->xml_encoding = strtoupper($enc);
4290 } else {
4291 $this->xml_encoding = 'US-ASCII';
4292 }
4293 } else {
4294 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
4295 $this->xml_encoding = 'ISO-8859-1';
4296 }
4297 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
4298 // parse response, get soap parser obj
4299 $parser = new nusoap_parser($data, $this->xml_encoding, '', $this->decode_utf8);
4300 // parser debug
4301 $this->debug("parser debug: \n" . $parser->getDebug());
4302 // if fault occurred during message parsing
4303 if ($err = $parser->getError()) {
4304 $this->result = 'fault: error in msg parsing: ' . $err;
4305 $this->fault('SOAP-ENV:Client', "error in msg parsing:\n" . $err);
4306 // else successfully parsed request into soapval object
4307 } else {
4308 // get/set methodname
4309 $this->methodURI = $parser->root_struct_namespace;
4310 $this->methodname = $parser->root_struct_name;
4311 $this->debug('methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
4312 $this->debug('calling parser->get_soapbody()');
4313 $this->methodparams = $parser->get_soapbody();
4314 // get SOAP headers
4315 $this->requestHeaders = $parser->getHeaders();
4316 // get SOAP Header
4317 $this->requestHeader = $parser->get_soapheader();
4318 // add document for doclit support
4319 $this->document = $parser->document;
4320 }
4321 }
4322
4330 public function getHTTPBody($soapmsg)
4331 {
4332 return $soapmsg;
4333 }
4334
4343 public function getHTTPContentType()
4344 {
4345 return 'text/xml';
4346 }
4347
4357 public function getHTTPContentTypeCharset()
4358 {
4360 }
4361
4371 public function add_to_map($methodname, $in, $out)
4372 {
4373 $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
4374 }
4375
4390 public function register($name, $in = array(), $out = array(), $namespace = false, $soapaction = false, $style = false, $use = false, $documentation = '', $encodingStyle = '')
4391 {
4392 global $HTTP_SERVER_VARS;
4393
4394 if ($this->externalWSDLURL) {
4395 die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4396 }
4397 if (! $name) {
4398 die('You must specify a name when you register an operation');
4399 }
4400 if (!is_array($in)) {
4401 die('You must provide an array for operation inputs');
4402 }
4403 if (!is_array($out)) {
4404 die('You must provide an array for operation outputs');
4405 }
4406 if (false == $namespace) {
4407 }
4408 if (false == $soapaction) {
4409 if (isset($_SERVER)) {
4410 $SERVER_NAME = $_SERVER['SERVER_NAME'];
4411 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4412 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4413 } elseif (isset($HTTP_SERVER_VARS)) {
4414 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4415 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4416 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4417 } else {
4418 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4419 }
4420 if ($HTTPS == '1' || $HTTPS == 'on') {
4421 $SCHEME = 'https';
4422 } else {
4423 $SCHEME = 'http';
4424 }
4425 $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4426 }
4427 if (false == $style) {
4428 $style = "rpc";
4429 }
4430 if (false == $use) {
4431 $use = "encoded";
4432 }
4433 if ($use == 'encoded' && $encodingStyle = '') {
4434 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
4435 }
4436
4437 $this->operations[$name] = array(
4438 'name' => $name,
4439 'in' => $in,
4440 'out' => $out,
4441 'namespace' => $namespace,
4442 'soapaction' => $soapaction,
4443 'style' => $style);
4444 if ($this->wsdl) {
4445 $this->wsdl->addOperation($name, $in, $out, $namespace, $soapaction, $style, $use, $documentation, $encodingStyle);
4446 }
4447 return true;
4448 }
4449
4460 public function fault($faultcode, $faultstring, $faultactor = '', $faultdetail = '')
4461 {
4462 if ($faultdetail == '' && $this->debug_flag) {
4463 $faultdetail = $this->getDebug();
4464 }
4465 $this->fault = new nusoap_fault($faultcode, $faultactor, $faultstring, $faultdetail);
4466 $this->fault->soap_defencoding = $this->soap_defencoding;
4467 }
4468
4480 public function configureWSDL($serviceName, $namespace = false, $endpoint = false, $style = 'rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
4481 {
4482 global $HTTP_SERVER_VARS;
4483
4484 if (isset($_SERVER)) {
4485 $SERVER_NAME = $_SERVER['SERVER_NAME'];
4486 $SERVER_PORT = $_SERVER['SERVER_PORT'];
4487 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4488 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4489 } elseif (isset($HTTP_SERVER_VARS)) {
4490 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4491 $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
4492 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4493 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4494 } else {
4495 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4496 }
4497 // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
4498 $colon = strpos($SERVER_NAME, ":");
4499 if ($colon) {
4500 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4501 }
4502 if ($SERVER_PORT == 80) {
4503 $SERVER_PORT = '';
4504 } else {
4505 $SERVER_PORT = ':' . $SERVER_PORT;
4506 }
4507 if (false == $namespace) {
4508 $namespace = "http://$SERVER_NAME/soap/$serviceName";
4509 }
4510
4511 if (false == $endpoint) {
4512 if ($HTTPS == '1' || $HTTPS == 'on') {
4513 $SCHEME = 'https';
4514 } else {
4515 $SCHEME = 'http';
4516 }
4517 $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4518 }
4519
4520 if (false == $schemaTargetNamespace) {
4521 $schemaTargetNamespace = $namespace;
4522 }
4523
4524 $this->wsdl = new wsdl();
4525 $this->wsdl->serviceName = $serviceName;
4526 $this->wsdl->endpoint = $endpoint;
4527 $this->wsdl->namespaces['tns'] = $namespace;
4528 $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
4529 $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
4530 if ($schemaTargetNamespace != $namespace) {
4531 $this->wsdl->namespaces['types'] = $schemaTargetNamespace;
4532 }
4533 $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
4534 if ($style == 'document') {
4535 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
4536 }
4537 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4538 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
4539 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
4540 $this->wsdl->bindings[$serviceName . 'Binding'] = array(
4541 'name' => $serviceName . 'Binding',
4542 'style' => $style,
4543 'transport' => $transport,
4544 'portType' => $serviceName . 'PortType');
4545 $this->wsdl->ports[$serviceName . 'Port'] = array(
4546 'binding' => $serviceName . 'Binding',
4547 'location' => $endpoint,
4548 'bindingType' => 'http://schemas.xmlsoap.org/wsdl/soap/');
4549 }
4550
4551 public function addInternalPort(string $serviceName, string $url): void
4552 {
4553 $this->wsdl->ports['Internal' . $serviceName . 'Port'] = [
4554 'binding' => $serviceName . 'Binding',
4555 'location' => (string) (new \ILIAS\Data\URI($url))->withQuery(),
4556 'bindingType' => 'http://schemas.xmlsoap.org/wsdl/soap/'
4557 ];
4558 }
4559}
4560
4564class soap_server extends nusoap_server
4565{
4566}
4567
4568?><?php
4569
4570
4571
4581class wsdl extends nusoap_base
4582{
4583 // URL or filename of the root of this WSDL
4584 public $serviceName;
4585 public $opStatus;
4586 public $currentPortOperation;
4587 public $wsdl;
4588 // define internal arrays of bindings, ports, operations, messages, etc.
4589 public $schemas = array();
4590 public $currentSchema;
4591 public $message = array();
4592 public $complexTypes = array();
4593 public $messages = array();
4594 public $currentMessage;
4595 public $currentOperation;
4596 public $portTypes = array();
4597 public $currentPortType;
4598 public $bindings = array();
4599 public $currentBinding;
4600 public $ports = array();
4601 public $currentPort;
4602 public $opData = array();
4603 public $status = '';
4604 public $documentation = false;
4605 public $endpoint = '';
4606 // array of wsdl docs to import
4607 public $import = array();
4608 // parser vars
4609 public $parser;
4610 public $position = 0;
4611 public $depth = 0;
4612 public $depth_array = array();
4613 // for getting wsdl
4614 public $proxyhost = '';
4615 public $proxyport = '';
4616 public $proxyusername = '';
4617 public $proxypassword = '';
4618 public $timeout = 0;
4619 public $response_timeout = 30;
4620 public $curl_options = array(); // User-specified cURL options
4621 public $use_curl = false; // whether to always try to use cURL
4622 // for HTTP authentication
4623 public $username = ''; // Username for HTTP authentication
4624 public $password = ''; // Password for HTTP authentication
4625 public $authtype = ''; // Type of HTTP authentication
4626 public $certRequest = array(); // Certificate for HTTP SSL authentication
4627
4642 public function __construct($wsdl = '', $proxyhost = false, $proxyport = false, $proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $curl_options = null, $use_curl = false)
4643 {
4645 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4646 $this->proxyhost = $proxyhost;
4647 $this->proxyport = $proxyport;
4648 $this->proxyusername = $proxyusername;
4649 $this->proxypassword = $proxypassword;
4650 $this->timeout = $timeout;
4651 $this->response_timeout = $response_timeout;
4652 if (is_array($curl_options)) {
4653 $this->curl_options = $curl_options;
4654 }
4655 $this->use_curl = $use_curl;
4656 $this->fetchWSDL($wsdl);
4657 }
4658
4664 public function fetchWSDL($wsdl)
4665 {
4666 $this->debug("parse and process WSDL path=$wsdl");
4667 $this->wsdl = $wsdl;
4668 // parse wsdl file
4669 if ($this->wsdl != "") {
4670 $this->parseWSDL($this->wsdl);
4671 }
4672 // imports
4673 // TODO: handle imports more properly, grabbing them in-line and nesting them
4674 $imported_urls = array();
4675 $imported = 1;
4676 while ($imported > 0) {
4677 $imported = 0;
4678 // Schema imports
4679 foreach ($this->schemas as $ns => $list) {
4680 foreach ($list as $xs) {
4681 $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4682 foreach ($xs->imports as $ns2 => $list2) {
4683 for ($ii = 0; $ii < count($list2); $ii++) {
4684 if (! $list2[$ii]['loaded']) {
4685 $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
4686 $url = $list2[$ii]['location'];
4687 if ($url != '') {
4688 $urlparts = parse_url($url);
4689 if (!isset($urlparts['host'])) {
4690 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
4691 substr($wsdlparts['path'], 0, strrpos($wsdlparts['path'], '/') + 1) . $urlparts['path'];
4692 }
4693 if (! in_array($url, $imported_urls)) {
4694 $this->parseWSDL($url);
4695 $imported++;
4696 $imported_urls[] = $url;
4697 }
4698 } else {
4699 $this->debug("Unexpected scenario: empty URL for unloaded import");
4700 }
4701 }
4702 }
4703 }
4704 }
4705 }
4706 // WSDL imports
4707 $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4708 foreach ($this->import as $ns => $list) {
4709 for ($ii = 0; $ii < count($list); $ii++) {
4710 if (! $list[$ii]['loaded']) {
4711 $this->import[$ns][$ii]['loaded'] = true;
4712 $url = $list[$ii]['location'];
4713 if ($url != '') {
4714 $urlparts = parse_url($url);
4715 if (!isset($urlparts['host'])) {
4716 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
4717 substr($wsdlparts['path'], 0, strrpos($wsdlparts['path'], '/') + 1) . $urlparts['path'];
4718 }
4719 if (! in_array($url, $imported_urls)) {
4720 $this->parseWSDL($url);
4721 $imported++;
4722 $imported_urls[] = $url;
4723 }
4724 } else {
4725 $this->debug("Unexpected scenario: empty URL for unloaded import");
4726 }
4727 }
4728 }
4729 }
4730 }
4731 // add new data to operation data
4732 foreach ($this->bindings as $binding => $bindingData) {
4733 if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
4734 foreach ($bindingData['operations'] as $operation => $data) {
4735 $this->debug('post-parse data gathering for ' . $operation);
4736 $this->bindings[$binding]['operations'][$operation]['input'] =
4737 isset($this->bindings[$binding]['operations'][$operation]['input']) ?
4738 array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
4739 $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
4740 $this->bindings[$binding]['operations'][$operation]['output'] =
4741 isset($this->bindings[$binding]['operations'][$operation]['output']) ?
4742 array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
4743 $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
4744 if (isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])) {
4745 $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
4746 }
4747 if (isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])) {
4748 $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
4749 }
4750 // Set operation style if necessary, but do not override one already provided
4751 if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
4752 $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
4753 }
4754 $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
4755 $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
4756 $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
4757 }
4758 }
4759 }
4760 }
4761
4768 public function parseWSDL($wsdl = '')
4769 {
4770 $this->debug("parse WSDL at path=$wsdl");
4771
4772 if ($wsdl == '') {
4773 $this->debug('no wsdl passed to parseWSDL()!!');
4774 $this->setError('no wsdl passed to parseWSDL()!!');
4775 return false;
4776 }
4777
4778 // parse $wsdl for url format
4779 $wsdl_props = parse_url($wsdl);
4780
4781 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
4782 $this->debug('getting WSDL http(s) URL ' . $wsdl);
4783 // get wsdl
4784 $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
4785 $tr->request_method = 'GET';
4786 $tr->useSOAPAction = false;
4787 if ($this->proxyhost && $this->proxyport) {
4788 $tr->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
4789 }
4790 if ($this->authtype != '') {
4791 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4792 }
4793 $tr->setEncoding('gzip, deflate');
4794 $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
4795 //$this->debug("WSDL request\n" . $tr->outgoing_payload);
4796 //$this->debug("WSDL response\n" . $tr->incoming_payload);
4797 $this->appendDebug($tr->getDebug());
4798 // catch errors
4799 if ($err = $tr->getError()) {
4800 $errstr = 'HTTP ERROR: ' . $err;
4801 $this->debug($errstr);
4802 $this->setError($errstr);
4803 unset($tr);
4804 return false;
4805 }
4806 unset($tr);
4807 $this->debug("got WSDL URL");
4808 } else {
4809 // $wsdl is not http(s), so treat it as a file URL or plain file path
4810 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
4811 $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
4812 } else {
4813 $path = $wsdl;
4814 }
4815 $this->debug('getting WSDL file ' . $path);
4816 if ($fp = @fopen($path, 'r')) {
4817 $wsdl_string = '';
4818 while ($data = fread($fp, 32768)) {
4819 $wsdl_string .= $data;
4820 }
4821 fclose($fp);
4822 } else {
4823 $errstr = "Bad path to WSDL file $path";
4824 $this->debug($errstr);
4825 $this->setError($errstr);
4826 return false;
4827 }
4828 }
4829 $this->debug('Parse WSDL');
4830 // end new code added
4831 // Create an XML parser.
4832 $this->parser = xml_parser_create();
4833 // Set the options for parsing the XML data.
4834 // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
4835 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4836 // Set the object for the parser.
4837 // Set the element handlers for the parser.
4838 xml_set_element_handler($this->parser, $this->start_element(...), $this->end_element(...));
4839 xml_set_character_data_handler($this->parser, $this->character_data(...));
4840 // Parse the XML file.
4841 if (!xml_parse($this->parser, $wsdl_string, true)) {
4842 // Display an error message.
4843 $errstr = sprintf(
4844 'XML error parsing WSDL from %s on line %d: %s',
4845 $wsdl,
4846 xml_get_current_line_number($this->parser),
4847 xml_error_string(xml_get_error_code($this->parser))
4848 );
4849 $this->debug($errstr);
4850 $this->debug("XML payload:\n" . $wsdl_string);
4851 $this->setError($errstr);
4852 return false;
4853 }
4854 $this->debug('Parsing WSDL done');
4855 // catch wsdl parse errors
4856 if ($this->getError()) {
4857 return false;
4858 }
4859 return true;
4860 }
4861
4870 public function start_element($parser, $name, $attrs)
4871 {
4872 if ($this->status == 'schema') {
4873 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4874 $this->appendDebug($this->currentSchema->getDebug());
4875 $this->currentSchema->clearDebug();
4876 } elseif (preg_match('/schema$/', $name)) {
4877 $this->debug('Parsing WSDL schema');
4878 // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
4879 $this->status = 'schema';
4880 $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
4881 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4882 $this->appendDebug($this->currentSchema->getDebug());
4883 $this->currentSchema->clearDebug();
4884 } else {
4885 // position in the total number of elements, starting from 0
4886 $pos = $this->position++;
4887 $depth = $this->depth++;
4888 // set self as current value for this depth
4889 $this->depth_array[$depth] = $pos;
4890 $this->message[$pos] = array('cdata' => '');
4891 // process attributes
4892 if (count($attrs) > 0) {
4893 // register namespace declarations
4894 foreach ($attrs as $k => $v) {
4895 if (preg_match('/^xmlns/', $k)) {
4896 if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
4897 $this->namespaces[$ns_prefix] = $v;
4898 } else {
4899 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
4900 }
4901 if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
4902 $this->XMLSchemaVersion = $v;
4903 $this->namespaces['xsi'] = $v . '-instance';
4904 }
4905 }
4906 }
4907 // expand each attribute prefix to its namespace
4908 foreach ($attrs as $k => $v) {
4909 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
4910 if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
4911 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
4912 }
4913 $eAttrs[$k] = $v;
4914 }
4915 $attrs = $eAttrs;
4916 } else {
4917 $attrs = array();
4918 }
4919 // get element prefix, namespace and name
4920 if (preg_match('/:/', $name)) {
4921 // get ns prefix
4922 $prefix = substr($name, 0, strpos($name, ':'));
4923 // get ns
4924 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : '';
4925 // get unqualified name
4926 $name = substr(strstr($name, ':'), 1);
4927 }
4928 // process attributes, expanding any prefixes to namespaces
4929 // find status, register data
4930 switch ($this->status) {
4931 case 'message':
4932 if ($name == 'part') {
4933 if (isset($attrs['type'])) {
4934 $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
4935 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
4936 }
4937 if (isset($attrs['element'])) {
4938 $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
4939 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
4940 }
4941 }
4942 break;
4943 case 'portType':
4944 switch ($name) {
4945 case 'operation':
4946 $this->currentPortOperation = $attrs['name'];
4947 $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
4948 if (isset($attrs['parameterOrder'])) {
4949 $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
4950 }
4951 break;
4952 case 'documentation':
4953 $this->documentation = true;
4954 break;
4955 // merge input/output data
4956 default:
4957 $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
4958 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
4959 break;
4960 }
4961 break;
4962 case 'binding':
4963 switch ($name) {
4964 case 'binding':
4965 // get ns prefix
4966 if (isset($attrs['style'])) {
4967 $this->bindings[$this->currentBinding]['prefix'] = $prefix;
4968 }
4969 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4970 break;
4971 case 'header':
4972 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
4973 break;
4974 case 'operation':
4975 if (isset($attrs['soapAction'])) {
4976 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
4977 }
4978 if (isset($attrs['style'])) {
4979 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
4980 }
4981 if (isset($attrs['name'])) {
4982 $this->currentOperation = $attrs['name'];
4983 $this->debug("current binding operation: $this->currentOperation");
4984 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
4985 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
4986 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
4987 }
4988 break;
4989 case 'input':
4990 $this->opStatus = 'input';
4991 break;
4992 case 'output':
4993 $this->opStatus = 'output';
4994 break;
4995 case 'body':
4996 if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
4997 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
4998 } else {
4999 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
5000 }
5001 break;
5002 }
5003 break;
5004 case 'service':
5005 switch ($name) {
5006 case 'port':
5007 $this->currentPort = $attrs['name'];
5008 $this->debug('current port: ' . $this->currentPort);
5009 $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
5010
5011 break;
5012 case 'address':
5013 $this->ports[$this->currentPort]['location'] = $attrs['location'];
5014 $this->ports[$this->currentPort]['bindingType'] = $namespace;
5015 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
5016 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
5017 break;
5018 }
5019 break;
5020 }
5021 // set status
5022 switch ($name) {
5023 case 'import':
5024 if (isset($attrs['location'])) {
5025 $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
5026 $this->debug('parsing import ' . $attrs['namespace'] . ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]) . ')');
5027 } else {
5028 $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
5029 if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
5030 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $attrs['namespace'];
5031 }
5032 $this->debug('parsing import ' . $attrs['namespace'] . ' - [no location] (' . count($this->import[$attrs['namespace']]) . ')');
5033 }
5034 break;
5035 //wait for schema
5036 //case 'types':
5037 // $this->status = 'schema';
5038 // break;
5039 case 'message':
5040 $this->status = 'message';
5041 $this->messages[$attrs['name']] = array();
5042 $this->currentMessage = $attrs['name'];
5043 break;
5044 case 'portType':
5045 $this->status = 'portType';
5046 $this->portTypes[$attrs['name']] = array();
5047 $this->currentPortType = $attrs['name'];
5048 break;
5049 case "binding":
5050 if (isset($attrs['name'])) {
5051 // get binding name
5052 if (strpos($attrs['name'], ':')) {
5053 $this->currentBinding = $this->getLocalPart($attrs['name']);
5054 } else {
5055 $this->currentBinding = $attrs['name'];
5056 }
5057 $this->status = 'binding';
5058 $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
5059 $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
5060 }
5061 break;
5062 case 'service':
5063 $this->serviceName = $attrs['name'];
5064 $this->status = 'service';
5065 $this->debug('current service: ' . $this->serviceName);
5066 break;
5067 case 'definitions':
5068 foreach ($attrs as $name => $value) {
5069 $this->wsdl_info[$name] = $value;
5070 }
5071 break;
5072 }
5073 }
5074 }
5075
5083 public function end_element($parser, $name)
5084 {
5085 // unset schema status
5086 if (/*preg_match('/types$/', $name) ||*/ preg_match('/schema$/', $name)) {
5087 $this->status = "";
5088 $this->appendDebug($this->currentSchema->getDebug());
5089 $this->currentSchema->clearDebug();
5090 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5091 $this->debug('Parsing WSDL schema done');
5092 }
5093 if ($this->status == 'schema') {
5094 $this->currentSchema->schemaEndElement($parser, $name);
5095 } else {
5096 // bring depth down a notch
5097 $this->depth--;
5098 }
5099 // end documentation
5100 if ($this->documentation) {
5101 //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
5102 //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
5103 $this->documentation = false;
5104 }
5105 }
5106
5114 public function character_data($parser, $data)
5115 {
5116 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5117 if (isset($this->message[$pos]['cdata'])) {
5118 $this->message[$pos]['cdata'] .= $data;
5119 }
5120 if ($this->documentation) {
5121 $this->documentation .= $data;
5122 }
5123 }
5124
5134 public function setCredentials($username, $password, $authtype = 'basic', $certRequest = array())
5135 {
5136 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
5137 $this->appendDebug($this->varDump($certRequest));
5138 $this->username = $username;
5139 $this->password = $password;
5140 $this->authtype = $authtype;
5141 $this->certRequest = $certRequest;
5142 }
5143
5144 public function getBindingData($binding)
5145 {
5146 if (is_array($this->bindings[$binding])) {
5147 return $this->bindings[$binding];
5148 }
5149 }
5150
5158 public function getOperations($bindingType = 'soap')
5159 {
5160 $ops = array();
5161 if ($bindingType == 'soap') {
5162 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5163 } elseif ($bindingType == 'soap12') {
5164 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5165 }
5166 // loop thru ports
5167 foreach ($this->ports as $port => $portData) {
5168 // binding type of port matches parameter
5169 if ($portData['bindingType'] == $bindingType) {
5170 //$this->debug("getOperations for port $port");
5171 //$this->debug("port data: " . $this->varDump($portData));
5172 //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
5173 // merge bindings
5174 if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
5175 $ops = array_merge($ops, $this->bindings[ $portData['binding'] ]['operations']);
5176 }
5177 }
5178 }
5179 return $ops;
5180 }
5181
5190 public function getOperationData($operation, $bindingType = 'soap')
5191 {
5192 if ($bindingType == 'soap') {
5193 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5194 } elseif ($bindingType == 'soap12') {
5195 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5196 }
5197 // loop thru ports
5198 foreach ($this->ports as $port => $portData) {
5199 // binding type of port matches parameter
5200 if ($portData['bindingType'] == $bindingType) {
5201 // get binding
5202 //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5203 foreach (array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
5204 // note that we could/should also check the namespace here
5205 if ($operation == $bOperation) {
5206 $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
5207 return $opData;
5208 }
5209 }
5210 }
5211 }
5212 }
5213
5222 public function getOperationDataForSoapAction($soapAction, $bindingType = 'soap')
5223 {
5224 if ($bindingType == 'soap') {
5225 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5226 } elseif ($bindingType == 'soap12') {
5227 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5228 }
5229 // loop thru ports
5230 foreach ($this->ports as $port => $portData) {
5231 // binding type of port matches parameter
5232 if ($portData['bindingType'] == $bindingType) {
5233 // loop through operations for the binding
5234 foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5235 if ($opData['soapAction'] == $soapAction) {
5236 return $opData;
5237 }
5238 }
5239 }
5240 }
5241 }
5242
5261 public function getTypeDef($type, $ns)
5262 {
5263 $this->debug("in getTypeDef: type=$type, ns=$ns");
5264 if ((! $ns) && isset($this->namespaces['tns'])) {
5265 $ns = $this->namespaces['tns'];
5266 $this->debug("in getTypeDef: type namespace forced to $ns");
5267 }
5268 if (!isset($this->schemas[$ns])) {
5269 foreach ($this->schemas as $ns0 => $schema0) {
5270 if (strcasecmp($ns, $ns0) == 0) {
5271 $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
5272 $ns = $ns0;
5273 break;
5274 }
5275 }
5276 }
5277 if (isset($this->schemas[$ns])) {
5278 $this->debug("in getTypeDef: have schema for namespace $ns");
5279 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5280 $xs = &$this->schemas[$ns][$i];
5281 $t = $xs->getTypeDef($type);
5282 //$this->appendDebug($xs->getDebug());
5283 //$xs->clearDebug();
5284 if ($t) {
5285 if (!isset($t['phpType'])) {
5286 // get info for type to tack onto the element
5287 $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
5288 $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
5289 $etype = $this->getTypeDef($uqType, $ns);
5290 if ($etype) {
5291 $this->debug("found type for [element] $type:");
5292 $this->debug($this->varDump($etype));
5293 if (isset($etype['phpType'])) {
5294 $t['phpType'] = $etype['phpType'];
5295 }
5296 if (isset($etype['elements'])) {
5297 $t['elements'] = $etype['elements'];
5298 }
5299 if (isset($etype['attrs'])) {
5300 $t['attrs'] = $etype['attrs'];
5301 }
5302 }
5303 }
5304 return $t;
5305 }
5306 }
5307 } else {
5308 $this->debug("in getTypeDef: do not have schema for namespace $ns");
5309 }
5310 return false;
5311 }
5312
5318 public function webDescription()
5319 {
5320 global $HTTP_SERVER_VARS;
5321
5322 if (isset($_SERVER)) {
5323 $PHP_SELF = $_SERVER['PHP_SELF'];
5324 } elseif (isset($HTTP_SERVER_VARS)) {
5325 $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
5326 } else {
5327 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
5328 }
5329 // begin-patch: https://mantis.ilias.de/view.php?id=28866
5330 $PHP_SELF = htmlspecialchars($PHP_SELF, ENT_QUOTES | ENT_HTML5, 'UTF-8');
5331 // end-patch
5332
5333 $b = '
5334 <html><head><title>NuSOAP: ' . $this->serviceName . '</title>
5335 <style type="text/css">
5336 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
5337 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
5338 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
5339 ul { margin-top: 10px; margin-left: 20px; }
5340 li { list-style-type: none; margin-top: 10px; color: #000000; }
5341 .content{
5342 margin-left: 0px; padding-bottom: 2em; }
5343 .nav {
5344 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
5345 margin-top: 10px; margin-left: 0px; color: #000000;
5346 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
5347 .title {
5348 font-family: arial; font-size: 26px; color: #ffffff;
5349 background-color: #999999; width: 105%; margin-left: 0px;
5350 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
5351 .hidden {
5352 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
5353 font-family: arial; overflow: hidden; width: 600;
5354 padding: 20px; font-size: 10px; background-color: #999999;
5355 layer-background-color:#FFFFFF; }
5356 a,a:active { color: charcoal; font-weight: bold; }
5357 a:visited { color: #666666; font-weight: bold; }
5358 a:hover { color: cc3300; font-weight: bold; }
5359 </style>
5360 <script language="JavaScript" type="text/javascript">
5361 <!--
5362 // POP-UP CAPTIONS...
5363 function lib_bwcheck(){ //Browsercheck (needed)
5364 this.ver=navigator.appVersion
5365 this.agent=navigator.userAgent
5366 this.dom=document.getElementById?1:0
5367 this.opera5=this.agent.indexOf("Opera 5")>-1
5368 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
5369 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
5370 this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
5371 this.ie=this.ie4||this.ie5||this.ie6
5372 this.mac=this.agent.indexOf("Mac")>-1
5373 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
5374 this.ns4=(document.layers && !this.dom)?1:0;
5375 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
5376 return this
5377 }
5378 var bw = new lib_bwcheck()
5379 //Makes crossbrowser object.
5380 function makeObj(obj){
5381 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
5382 if(!this.evnt) return false
5383 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
5384 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
5385 this.writeIt=b_writeIt;
5386 return this
5387 }
5388 // A unit of measure that will be added when setting the position of a layer.
5389 //var px = bw.ns4||window.opera?"":"px";
5390 function b_writeIt(text){
5391 if (bw.ns4){this.wref.write(text);this.wref.close()}
5392 else this.wref.innerHTML = text
5393 }
5394 //Shows the messages
5395 var oDesc;
5396 function popup(divid){
5397 if(oDesc = new makeObj(divid)){
5398 oDesc.css.visibility = "visible"
5399 }
5400 }
5401 function popout(){ // Hides message
5402 if(oDesc) oDesc.css.visibility = "hidden"
5403 }
5404 //-->
5405 </script>
5406 </head>
5407 <body>
5408 <div class=content>
5409 <br><br>
5410 <div class=title>' . $this->serviceName . '</div>
5411 <div class=nav>
5412 <p>View the <a href="' . $PHP_SELF . '?wsdl">WSDL</a> for the service.
5413 Click on an operation name to view it&apos;s details.</p>
5414 <ul>';
5415 foreach ($this->getOperations() as $op => $data) {
5416 // begin-patch: https://mantis.ilias.de/view.php?id=28866
5417 if (isset($data['endpoint'])) {
5418 $data['endpoint'] = htmlspecialchars($data['endpoint'], ENT_QUOTES | ENT_HTML5, 'UTF-8');
5419 }
5420 // end-patch
5421 $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5422 // create hidden div
5423 $b .= "<div id='$op' class='hidden'>
5424 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5425 foreach ($data as $donnie => $marie) { // loop through opdata
5426 if ($donnie == 'input' || $donnie == 'output') { // show input/output data
5427 $b .= "<font color='white'>" . ucfirst($donnie) . ':</font><br>';
5428 foreach ($marie as $captain => $tenille) { // loop through data
5429 if ($captain == 'parts') { // loop thru parts
5430 $b .= "&nbsp;&nbsp;$captain:<br>";
5431 //if(is_array($tenille)){
5432 foreach ($tenille as $joanie => $chachi) {
5433 $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
5434 }
5435 //}
5436 } else {
5437 $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
5438 }
5439 }
5440 } else {
5441 $b .= "<font color='white'>" . ucfirst($donnie) . ":</font> $marie<br>";
5442 }
5443 }
5444 $b .= '</div>';
5445 }
5446 $b .= '
5447 <ul>
5448 </div>
5449 </div></body></html>';
5450 return $b;
5451 }
5452
5460 public function serialize($debug = 0)
5461 {
5462 $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
5463 $xml .= "\n<definitions";
5464 foreach ($this->namespaces as $k => $v) {
5465 $xml .= " xmlns:$k=\"$v\"";
5466 }
5467 // 10.9.02 - add poulter fix for wsdl and tns declarations
5468 if (isset($this->namespaces['wsdl'])) {
5469 $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
5470 }
5471 if (isset($this->namespaces['tns'])) {
5472 $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
5473 }
5474 $xml .= '>';
5475 // imports
5476 if (sizeof($this->import) > 0) {
5477 foreach ($this->import as $ns => $list) {
5478 foreach ($list as $ii) {
5479 if ($ii['location'] != '') {
5480 $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
5481 } else {
5482 $xml .= '<import namespace="' . $ns . '" />';
5483 }
5484 }
5485 }
5486 }
5487 // types
5488 if (count($this->schemas) >= 1) {
5489 $xml .= "\n<types>\n";
5490 foreach ($this->schemas as $ns => $list) {
5491 foreach ($list as $xs) {
5492 $xml .= $xs->serializeSchema();
5493 }
5494 }
5495 $xml .= '</types>';
5496 }
5497 // messages
5498 if (count($this->messages) >= 1) {
5499 foreach ($this->messages as $msgName => $msgParts) {
5500 $xml .= "\n<message name=\"" . $msgName . '">';
5501 if (is_array($msgParts)) {
5502 foreach ($msgParts as $partName => $partType) {
5503 // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
5504 if (strpos($partType, ':')) {
5505 $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
5506 } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
5507 // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
5508 $typePrefix = 'xsd';
5509 } else {
5510 foreach ($this->typemap as $ns => $types) {
5511 if (isset($types[$partType])) {
5512 $typePrefix = $this->getPrefixFromNamespace($ns);
5513 }
5514 }
5515 if (!isset($typePrefix)) {
5516 die("$partType has no namespace!");
5517 }
5518 }
5519 $ns = $this->getNamespaceFromPrefix($typePrefix);
5520 $localPart = $this->getLocalPart($partType);
5521 $typeDef = $this->getTypeDef($localPart, $ns);
5522 if (($typeDef['typeClass'] ?? '') == 'element') {
5523 $elementortype = 'element';
5524 if (substr($localPart, -1) == '^') {
5525 $localPart = substr($localPart, 0, -1);
5526 }
5527 } else {
5528 $elementortype = 'type';
5529 }
5530 $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
5531 }
5532 }
5533 $xml .= '</message>';
5534 }
5535 }
5536 // bindings & porttypes
5537 if (count($this->bindings) >= 1) {
5538 $binding_xml = '';
5539 $portType_xml = '';
5540 foreach ($this->bindings as $bindingName => $attrs) {
5541 $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
5542 $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
5543 $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
5544 foreach ($attrs['operations'] as $opName => $opParts) {
5545 $binding_xml .= "\n" . ' <operation name="' . $opName . '">';
5546 $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="' . $opParts['style'] . '"/>';
5547 if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
5548 $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
5549 } else {
5550 $enc_style = '';
5551 }
5552 $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
5553 if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
5554 $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
5555 } else {
5556 $enc_style = '';
5557 }
5558 $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
5559 $binding_xml .= "\n" . ' </operation>';
5560 $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"';
5561 if (isset($opParts['parameterOrder'])) {
5562 $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
5563 }
5564 $portType_xml .= '>';
5565 if (isset($opParts['documentation']) && $opParts['documentation'] != '') {
5566 $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
5567 }
5568 $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>';
5569 $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>';
5570 $portType_xml .= "\n" . ' </operation>';
5571 }
5572 $portType_xml .= "\n" . '</portType>';
5573 $binding_xml .= "\n" . '</binding>';
5574 }
5575 $xml .= $portType_xml . $binding_xml;
5576 }
5577 // services
5578 $xml .= "\n<service name=\"" . $this->serviceName . '">';
5579 $has_client = isset($_GET['client_id']);
5580 if (count($this->ports) >= 1) {
5581 foreach ($this->ports as $pName => $attrs) {
5582 $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
5583 $locations = $attrs['location'];
5584 $locations = is_array($locations) ? $locations : [$locations];
5585 foreach ($locations as $location) {
5586 $address = $location . ($debug || $has_client ? "?" : "")
5587 . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&amp;" : "")
5588 . ($has_client ? 'client_id=' . $_GET['client_id'] : '');
5589 $xml .= "\n" . ' <soap:address location="' . $address . '"/>';
5590 }
5591 $xml .= "\n" . ' </port>';
5592 }
5593 }
5594
5595 $xml .= "\n" . '</service>';
5596 return $xml . "\n</definitions>";
5597 }
5598
5608 public function parametersMatchWrapped($type, &$parameters)
5609 {
5610 $this->debug("in parametersMatchWrapped type=$type, parameters=");
5611 $this->appendDebug($this->varDump($parameters));
5612
5613 // split type into namespace:unqualified-type
5614 if (strpos($type, ':')) {
5615 $uqType = substr($type, strrpos($type, ':') + 1);
5616 $ns = substr($type, 0, strrpos($type, ':'));
5617 $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5618 if ($this->getNamespaceFromPrefix($ns)) {
5619 $ns = $this->getNamespaceFromPrefix($ns);
5620 $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5621 }
5622 } else {
5623 // TODO: should the type be compared to types in XSD, and the namespace
5624 // set to XSD if the type matches?
5625 $this->debug("in parametersMatchWrapped: No namespace for type $type");
5626 $ns = '';
5627 $uqType = $type;
5628 }
5629
5630 // get the type information
5631 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5632 $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5633 return false;
5634 }
5635 $this->debug("in parametersMatchWrapped: found typeDef=");
5636 $this->appendDebug($this->varDump($typeDef));
5637 if (substr($uqType, -1) == '^') {
5638 $uqType = substr($uqType, 0, -1);
5639 }
5640 $phpType = $typeDef['phpType'];
5641 $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
5642 $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5643
5644 // we expect a complexType or element of complexType
5645 if ($phpType != 'struct') {
5646 $this->debug("in parametersMatchWrapped: not a struct");
5647 return false;
5648 }
5649
5650 // see whether the parameter names match the elements
5651 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
5652 $elements = 0;
5653 $matches = 0;
5654 $change = false;
5655 if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
5656 $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5657 $change = true;
5658 }
5659 foreach ($typeDef['elements'] as $name => $attrs) {
5660 if ($change) {
5661 $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
5662 $parameters[$name] = $parameters[$elements];
5663 unset($parameters[$elements]);
5664 $matches++;
5665 } elseif (isset($parameters[$name])) {
5666 $this->debug("in parametersMatchWrapped: have parameter named $name");
5667 $matches++;
5668 } else {
5669 $this->debug("in parametersMatchWrapped: do not have parameter named $name");
5670 }
5671 $elements++;
5672 }
5673
5674 $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5675 if ($matches == 0) {
5676 return false;
5677 }
5678 return true;
5679 }
5680
5681 // since there are no elements for the type, if the user passed no
5682 // parameters, the parameters match wrapped.
5683 $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
5684 return count($parameters) == 0;
5685 }
5686
5702 public function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap')
5703 {
5704 $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5705 $this->appendDebug('parameters=' . $this->varDump($parameters));
5706
5707 if ($direction != 'input' && $direction != 'output') {
5708 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5709 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5710 return false;
5711 }
5712 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5713 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5714 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5715 return false;
5716 }
5717 $this->debug('in serializeRPCParameters: opData:');
5718 $this->appendDebug($this->varDump($opData));
5719
5720 // Get encoding style for output and set to current
5721 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5722 if (($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5723 $encodingStyle = $opData['output']['encodingStyle'];
5724 $enc_style = $encodingStyle;
5725 }
5726
5727 // set input params
5728 $xml = '';
5729 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5730 $parts = &$opData[$direction]['parts'];
5731 $part_count = sizeof($parts);
5732 $style = $opData['style'];
5733 $use = $opData[$direction]['use'];
5734 $this->debug("have $part_count part(s) to serialize using $style/$use");
5735 if (is_array($parameters)) {
5736 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5737 $parameter_count = count($parameters);
5738 $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5739 // check for Microsoft-style wrapped parameters
5740 if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
5741 $this->debug('check whether the caller has wrapped the parameters');
5742 if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
5743 $this->debug('check whether caller\'s parameters match the wrapped ones');
5744 if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
5745 $this->debug('wrap the parameters for the caller');
5746 $parameters = array('parameters' => $parameters);
5747 $parameter_count = 1;
5748 }
5749 }
5750 }
5751 foreach ($parts as $name => $type) {
5752 $this->debug("serializing part $name of type $type");
5753 // Track encoding style
5754 if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5755 $encodingStyle = $opData[$direction]['encodingStyle'];
5756 $enc_style = $encodingStyle;
5757 } else {
5758 $enc_style = false;
5759 }
5760 // NOTE: add error handling here
5761 // if serializeType returns false, then catch global error and fault
5762 if ($parametersArrayType == 'arraySimple') {
5763 $p = array_shift($parameters);
5764 $this->debug('calling serializeType w/indexed param');
5765 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5766 } elseif (isset($parameters[$name])) {
5767 $this->debug('calling serializeType w/named param');
5768 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5769 } else {
5770 // TODO: only send nillable
5771 $this->debug('calling serializeType w/null param');
5772 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5773 }
5774 }
5775 } else {
5776 $this->debug('no parameters passed.');
5777 }
5778 }
5779 $this->debug("serializeRPCParameters returning: $xml");
5780 return $xml;
5781 }
5782
5797 public function serializeParameters($operation, $direction, $parameters)
5798 {
5799 $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5800 $this->appendDebug('parameters=' . $this->varDump($parameters));
5801
5802 if ($direction != 'input' && $direction != 'output') {
5803 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5804 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5805 return false;
5806 }
5807 if (!$opData = $this->getOperationData($operation)) {
5808 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
5809 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
5810 return false;
5811 }
5812 $this->debug('opData:');
5813 $this->appendDebug($this->varDump($opData));
5814
5815 // Get encoding style for output and set to current
5816 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5817 if (($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5818 $encodingStyle = $opData['output']['encodingStyle'];
5819 $enc_style = $encodingStyle;
5820 }
5821
5822 // set input params
5823 $xml = '';
5824 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5825 $use = $opData[$direction]['use'];
5826 $this->debug("use=$use");
5827 $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
5828 if (is_array($parameters)) {
5829 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5830 $this->debug('have ' . $parametersArrayType . ' parameters');
5831 foreach ($opData[$direction]['parts'] as $name => $type) {
5832 $this->debug('serializing part "' . $name . '" of type "' . $type . '"');
5833 // Track encoding style
5834 if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5835 $encodingStyle = $opData[$direction]['encodingStyle'];
5836 $enc_style = $encodingStyle;
5837 } else {
5838 $enc_style = false;
5839 }
5840 // NOTE: add error handling here
5841 // if serializeType returns false, then catch global error and fault
5842 if ($parametersArrayType == 'arraySimple') {
5843 $p = array_shift($parameters);
5844 $this->debug('calling serializeType w/indexed param');
5845 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5846 } elseif (isset($parameters[$name])) {
5847 $this->debug('calling serializeType w/named param');
5848 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5849 } else {
5850 // TODO: only send nillable
5851 $this->debug('calling serializeType w/null param');
5852 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5853 }
5854 }
5855 } else {
5856 $this->debug('no parameters passed.');
5857 }
5858 }
5859 $this->debug("serializeParameters returning: $xml");
5860 return $xml;
5861 }
5862
5875 public function serializeType($name, $type, $value, $use = 'encoded', $encodingStyle = false, $unqualified = false)
5876 {
5877 $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
5878 $this->appendDebug("value=" . $this->varDump($value));
5879 if ($use == 'encoded' && $encodingStyle) {
5880 $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
5881 }
5882
5883 // if a soapval has been supplied, let its type override the WSDL
5884 if (is_object($value) && get_class($value) == 'soapval') {
5885 if ($value->type_ns) {
5886 $type = $value->type_ns . ':' . $value->type;
5887 $forceType = true;
5888 $this->debug("in serializeType: soapval overrides type to $type");
5889 } elseif ($value->type) {
5890 $type = $value->type;
5891 $forceType = true;
5892 $this->debug("in serializeType: soapval overrides type to $type");
5893 } else {
5894 $forceType = false;
5895 $this->debug("in serializeType: soapval does not override type");
5896 }
5897 $attrs = $value->attributes;
5898 $value = $value->value;
5899 $this->debug("in serializeType: soapval overrides value to $value");
5900 if ($attrs) {
5901 if (!is_array($value)) {
5902 $value['!'] = $value;
5903 }
5904 foreach ($attrs as $n => $v) {
5905 $value['!' . $n] = $v;
5906 }
5907 $this->debug("in serializeType: soapval provides attributes");
5908 }
5909 } else {
5910 $forceType = false;
5911 }
5912
5913 $xml = '';
5914 if (strpos($type, ':')) {
5915 $uqType = substr($type, strrpos($type, ':') + 1);
5916 $ns = substr($type, 0, strrpos($type, ':'));
5917 $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
5918 if ($this->getNamespaceFromPrefix($ns)) {
5919 $ns = $this->getNamespaceFromPrefix($ns);
5920 $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
5921 }
5922
5923 if ($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/') {
5924 $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5925 if ($unqualified && $use == 'literal') {
5926 $elementNS = " xmlns=\"\"";
5927 } else {
5928 $elementNS = '';
5929 }
5930 if (is_null($value)) {
5931 if ($use == 'literal') {
5932 // TODO: depends on minOccurs
5933 $xml = "<$name$elementNS/>";
5934 } else {
5935 // TODO: depends on nillable, which should be checked before calling this method
5936 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5937 }
5938 $this->debug("in serializeType: returning: $xml");
5939 return $xml;
5940 }
5941 if ($uqType == 'Array') {
5942 // JBoss/Axis does this sometimes
5943 return $this->serialize_val($value, $name, false, false, false, false, $use);
5944 }
5945 if ($uqType == 'boolean') {
5946 if ((is_string($value) && $value == 'false') || (! $value)) {
5947 $value = 'false';
5948 } else {
5949 $value = 'true';
5950 }
5951 }
5952 if ($uqType == 'string' && gettype($value) == 'string') {
5953 $value = $this->expandEntities($value);
5954 }
5955 if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
5956 $value = sprintf("%.0lf", $value);
5957 }
5958 // it's a scalar
5959 // TODO: what about null/nil values?
5960 // check type isn't a custom type extending xmlschema namespace
5961 if (!$this->getTypeDef($uqType, $ns)) {
5962 if ($use == 'literal') {
5963 if ($forceType) {
5964 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
5965 } else {
5966 $xml = "<$name$elementNS>$value</$name>";
5967 }
5968 } else {
5969 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
5970 }
5971 $this->debug("in serializeType: returning: $xml");
5972 return $xml;
5973 }
5974 $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5975 } elseif ($ns == 'http://xml.apache.org/xml-soap') {
5976 $this->debug('in serializeType: appears to be Apache SOAP type');
5977 if ($uqType == 'Map') {
5978 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5979 if (! $tt_prefix) {
5980 $this->debug('in serializeType: Add namespace for Apache SOAP type');
5981 $tt_prefix = 'ns' . rand(1000, 9999);
5982 $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
5983 // force this to be added to usedNamespaces
5984 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5985 }
5986 $contents = '';
5987 foreach ($value as $k => $v) {
5988 $this->debug("serializing map element: key $k, value $v");
5989 $contents .= '<item>';
5990 $contents .= $this->serialize_val($k, 'key', false, false, false, false, $use);
5991 $contents .= $this->serialize_val($v, 'value', false, false, false, false, $use);
5992 $contents .= '</item>';
5993 }
5994 if ($use == 'literal') {
5995 if ($forceType) {
5996 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
5997 } else {
5998 $xml = "<$name>$contents</$name>";
5999 }
6000 } else {
6001 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
6002 }
6003 $this->debug("in serializeType: returning: $xml");
6004 return $xml;
6005 }
6006 $this->debug('in serializeType: Apache SOAP type, but only support Map');
6007 }
6008 } else {
6009 // TODO: should the type be compared to types in XSD, and the namespace
6010 // set to XSD if the type matches?
6011 $this->debug("in serializeType: No namespace for type $type");
6012 $ns = '';
6013 $uqType = $type;
6014 }
6015 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
6016 $this->setError("$type ($uqType) is not a supported type.");
6017 $this->debug("in serializeType: $type ($uqType) is not a supported type.");
6018 return false;
6019 } else {
6020 $this->debug("in serializeType: found typeDef");
6021 $this->appendDebug('typeDef=' . $this->varDump($typeDef));
6022 if (substr($uqType, -1) == '^') {
6023 $uqType = substr($uqType, 0, -1);
6024 }
6025 }
6026 $phpType = $typeDef['phpType'];
6027 $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : ''));
6028 // if php type == struct, map value to the <all> element names
6029 if ($phpType == 'struct') {
6030 if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
6031 $elementName = $uqType;
6032 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6033 $elementNS = " xmlns=\"$ns\"";
6034 } else {
6035 $elementNS = " xmlns=\"\"";
6036 }
6037 } else {
6038 $elementName = $name;
6039 if ($unqualified) {
6040 $elementNS = " xmlns=\"\"";
6041 } else {
6042 $elementNS = '';
6043 }
6044 }
6045 if (is_null($value)) {
6046 if ($use == 'literal') {
6047 // TODO: depends on minOccurs
6048 $xml = "<$elementName$elementNS/>";
6049 } else {
6050 $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
6051 }
6052 $this->debug("in serializeType: returning: $xml");
6053 return $xml;
6054 }
6055 if (is_object($value)) {
6056 $value = get_object_vars($value);
6057 }
6058 if (is_array($value)) {
6059 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6060 if ($use == 'literal') {
6061 if ($forceType) {
6062 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
6063 } else {
6064 $xml = "<$elementName$elementNS$elementAttrs>";
6065 }
6066 } else {
6067 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
6068 }
6069
6070 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6071 $xml .= "</$elementName>";
6072 } else {
6073 $this->debug("in serializeType: phpType is struct, but value is not an array");
6074 $this->setError("phpType is struct, but value is not an array: see debug output for details");
6075 $xml = '';
6076 }
6077 } elseif ($phpType == 'array') {
6078 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6079 $elementNS = " xmlns=\"$ns\"";
6080 } else {
6081 if ($unqualified) {
6082 $elementNS = " xmlns=\"\"";
6083 } else {
6084 $elementNS = '';
6085 }
6086 }
6087 if (is_null($value)) {
6088 if ($use == 'literal') {
6089 // TODO: depends on minOccurs
6090 $xml = "<$name$elementNS/>";
6091 } else {
6092 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6093 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6094 ":Array\" " .
6095 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6096 ':arrayType="' .
6097 $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
6098 ':' .
6099 $this->getLocalPart($typeDef['arrayType']) . "[0]\"/>";
6100 }
6101 $this->debug("in serializeType: returning: $xml");
6102 return $xml;
6103 }
6104 if (isset($typeDef['multidimensional'])) {
6105 $nv = array();
6106 foreach ($value as $v) {
6107 $cols = ',' . sizeof($v);
6108 $nv = array_merge($nv, $v);
6109 }
6110 $value = $nv;
6111 } else {
6112 $cols = '';
6113 }
6114 if (is_array($value) && sizeof($value) >= 1) {
6115 $rows = sizeof($value);
6116 $contents = '';
6117 foreach ($value as $k => $v) {
6118 $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
6119 //if (strpos($typeDef['arrayType'], ':') ) {
6120 if (!in_array($typeDef['arrayType'], $this->typemap['http://www.w3.org/2001/XMLSchema'])) {
6121 $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
6122 } else {
6123 $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
6124 }
6125 }
6126 } else {
6127 $rows = 0;
6128 $contents = null;
6129 }
6130 // TODO: for now, an empty value will be serialized as a zero element
6131 // array. Revisit this when coding the handling of null/nil values.
6132 if ($use == 'literal') {
6133 $xml = "<$name$elementNS>"
6134 . $contents
6135 . "</$name>";
6136 } else {
6137 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . ':Array" ' .
6138 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
6139 . ':arrayType="'
6140 . $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
6141 . ":" . $this->getLocalPart($typeDef['arrayType']) . "[$rows$cols]\">"
6142 . $contents
6143 . "</$name>";
6144 }
6145 } elseif ($phpType == 'scalar') {
6146 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6147 $elementNS = " xmlns=\"$ns\"";
6148 } else {
6149 if ($unqualified) {
6150 $elementNS = " xmlns=\"\"";
6151 } else {
6152 $elementNS = '';
6153 }
6154 }
6155 if ($use == 'literal') {
6156 if ($forceType) {
6157 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
6158 } else {
6159 $xml = "<$name$elementNS>$value</$name>";
6160 }
6161 } else {
6162 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
6163 }
6164 }
6165 $this->debug("in serializeType: returning: $xml");
6166 return $xml;
6167 }
6168
6179 public function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
6180 {
6181 $xml = '';
6182 if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
6183 $this->debug("serialize attributes for XML Schema type $ns:$uqType");
6184 if (is_array($value)) {
6185 $xvalue = $value;
6186 } elseif (is_object($value)) {
6187 $xvalue = get_object_vars($value);
6188 } else {
6189 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6190 $xvalue = array();
6191 }
6192 foreach ($typeDef['attrs'] as $aName => $attrs) {
6193 if (isset($xvalue['!' . $aName])) {
6194 $xname = '!' . $aName;
6195 $this->debug("value provided for attribute $aName with key $xname");
6196 } elseif (isset($xvalue[$aName])) {
6197 $xname = $aName;
6198 $this->debug("value provided for attribute $aName with key $xname");
6199 } elseif (isset($attrs['default'])) {
6200 $xname = '!' . $aName;
6201 $xvalue[$xname] = $attrs['default'];
6202 $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
6203 } else {
6204 $xname = '';
6205 $this->debug("no value provided for attribute $aName");
6206 }
6207 if ($xname) {
6208 $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
6209 }
6210 }
6211 } else {
6212 $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
6213 }
6214 if (isset($typeDef['extensionBase'])) {
6215 $ns = $this->getPrefix($typeDef['extensionBase']);
6216 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6217 if ($this->getNamespaceFromPrefix($ns)) {
6218 $ns = $this->getNamespaceFromPrefix($ns);
6219 }
6220 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6221 $this->debug("serialize attributes for extension base $ns:$uqType");
6222 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6223 } else {
6224 $this->debug("extension base $ns:$uqType is not a supported type");
6225 }
6226 }
6227 return $xml;
6228 }
6229
6242 public function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use = 'encoded', $encodingStyle = false)
6243 {
6244 $xml = '';
6245 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
6246 $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6247 if (is_array($value)) {
6248 $xvalue = $value;
6249 } elseif (is_object($value)) {
6250 $xvalue = get_object_vars($value);
6251 } else {
6252 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6253 $xvalue = array();
6254 }
6255 // toggle whether all elements are present - ideally should validate against schema
6256 if (count($typeDef['elements']) != count($xvalue)) {
6257 $optionals = true;
6258 }
6259 foreach ($typeDef['elements'] as $eName => $attrs) {
6260 if (!isset($xvalue[$eName])) {
6261 if (isset($attrs['default'])) {
6262 $xvalue[$eName] = $attrs['default'];
6263 $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
6264 }
6265 }
6266 // if user took advantage of a minOccurs=0, then only serialize named parameters
6267 if (isset($optionals)
6268 && (!isset($xvalue[$eName]))
6269 && ((!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
6270 ) {
6271 if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
6272 $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
6273 }
6274 // do nothing
6275 $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6276 } else {
6277 // get value
6278 if (isset($xvalue[$eName])) {
6279 $v = $xvalue[$eName];
6280 } else {
6281 $v = null;
6282 }
6283 if (isset($attrs['form'])) {
6284 $unqualified = ($attrs['form'] == 'unqualified');
6285 } else {
6286 $unqualified = false;
6287 }
6288 if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
6289 $vv = $v;
6290 foreach ($vv as $k => $v) {
6291 if (isset($attrs['type']) || isset($attrs['ref'])) {
6292 // serialize schema-defined type
6293 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6294 } else {
6295 // serialize generic type (can this ever really happen?)
6296 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6297 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6298 }
6299 }
6300 } else {
6301 if (isset($attrs['type']) || isset($attrs['ref'])) {
6302 // serialize schema-defined type
6303 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6304 } else {
6305 // serialize generic type (can this ever really happen?)
6306 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6307 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6308 }
6309 }
6310 }
6311 }
6312 } else {
6313 $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
6314 }
6315 if (isset($typeDef['extensionBase'])) {
6316 $ns = $this->getPrefix($typeDef['extensionBase']);
6317 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6318 if ($this->getNamespaceFromPrefix($ns)) {
6319 $ns = $this->getNamespaceFromPrefix($ns);
6320 }
6321 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6322 $this->debug("serialize elements for extension base $ns:$uqType");
6323 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6324 } else {
6325 $this->debug("extension base $ns:$uqType is not a supported type");
6326 }
6327 }
6328 return $xml;
6329 }
6330
6345 public function addComplexType($name, $typeClass = 'complexType', $phpType = 'array', $compositor = '', $restrictionBase = '', $elements = array(), $attrs = array(), $arrayType = '')
6346 {
6347 if (count($elements) > 0) {
6348 $eElements = array();
6349 foreach ($elements as $n => $e) {
6350 // expand each element
6351 $ee = array();
6352 foreach ($e as $k => $v) {
6353 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
6354 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
6355 $ee[$k] = $v;
6356 }
6357 $eElements[$n] = $ee;
6358 }
6359 $elements = $eElements;
6360 }
6361
6362 if (count($attrs) > 0) {
6363 foreach ($attrs as $n => $a) {
6364 // expand each attribute
6365 foreach ($a as $k => $v) {
6366 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
6367 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
6368 $aa[$k] = $v;
6369 }
6370 $eAttrs[$n] = $aa;
6371 }
6372 $attrs = $eAttrs;
6373 }
6374
6375 $restrictionBase = strpos($restrictionBase, ':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6376 $arrayType = strpos($arrayType, ':') ? $this->expandQname($arrayType) : $arrayType;
6377
6378 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6379 $this->schemas[$typens][0]->addComplexType($name, $typeClass, $phpType, $compositor, $restrictionBase, $elements, $attrs, $arrayType);
6380 }
6381
6393 public function addSimpleType($name, $restrictionBase = '', $typeClass = 'simpleType', $phpType = 'scalar', $enumeration = array())
6394 {
6395 $restrictionBase = strpos($restrictionBase, ':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6396
6397 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6398 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6399 }
6400
6408 public function addElement($attrs)
6409 {
6410 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6411 $this->schemas[$typens][0]->addElement($attrs);
6412 }
6413
6428 public function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = '')
6429 {
6430 if ($use == 'encoded' && $encodingStyle == '') {
6431 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
6432 }
6433
6434 if ($style == 'document') {
6435 $elements = array();
6436 foreach ($in as $n => $t) {
6437 $elements[$n] = array('name' => $n, 'type' => $t);
6438 }
6439 $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
6440 $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
6441 $in = array('parameters' => 'tns:' . $name . '^');
6442
6443 $elements = array();
6444 foreach ($out as $n => $t) {
6445 $elements[$n] = array('name' => $n, 'type' => $t);
6446 }
6447 $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
6448 $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
6449 $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
6450 }
6451
6452 // get binding
6453 $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
6454 array(
6455 'name' => $name,
6456 'binding' => $this->serviceName . 'Binding',
6457 'endpoint' => $this->endpoint,
6458 'soapAction' => $soapaction,
6459 'style' => $style,
6460 'input' => array(
6461 'use' => $use,
6462 'namespace' => $namespace,
6463 'encodingStyle' => $encodingStyle,
6464 'message' => $name . 'Request',
6465 'parts' => $in),
6466 'output' => array(
6467 'use' => $use,
6468 'namespace' => $namespace,
6469 'encodingStyle' => $encodingStyle,
6470 'message' => $name . 'Response',
6471 'parts' => $out),
6472 'namespace' => $namespace,
6473 'transport' => 'http://schemas.xmlsoap.org/soap/http',
6474 'documentation' => $documentation);
6475 // add portTypes
6476 // add messages
6477 if ($in) {
6478 foreach ($in as $pName => $pType) {
6479 if (strpos($pType, ':')) {
6480 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)) . ":" . $this->getLocalPart($pType);
6481 }
6482 $this->messages[$name . 'Request'][$pName] = $pType;
6483 }
6484 } else {
6485 $this->messages[$name . 'Request'] = '0';
6486 }
6487 if ($out) {
6488 foreach ($out as $pName => $pType) {
6489 if (strpos($pType, ':')) {
6490 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)) . ":" . $this->getLocalPart($pType);
6491 }
6492 $this->messages[$name . 'Response'][$pName] = $pType;
6493 }
6494 } else {
6495 $this->messages[$name . 'Response'] = '0';
6496 }
6497 return true;
6498 }
6499}
6500?><?php
6501
6502
6503
6513class nusoap_parser extends nusoap_base
6514{
6515 public $methodNamespace;
6516 public $parser;
6517 public $xml = '';
6518 public $xml_encoding = '';
6519 public $method = '';
6520 public $root_struct = '';
6521 public $root_struct_name = '';
6522 public $root_struct_namespace = '';
6523 public $root_header = '';
6524 public $document = ''; // incoming SOAP body (text)
6525 // determines where in the message we are (envelope,header,body,method)
6526 public $status = '';
6527 public $position = 0;
6528 public $depth = 0;
6529 public $default_namespace = '';
6530 public $namespaces = array();
6531 public $message = array();
6532 public $parent = '';
6533 public $fault = false;
6534 public $fault_code = '';
6535 public $fault_str = '';
6536 public $fault_detail = '';
6537 public $depth_array = array();
6538 public $debug_flag = true;
6539 public $soapresponse = null; // parsed SOAP Body
6540 public $soapheader = null; // parsed SOAP Header
6541 public $responseHeaders = ''; // incoming SOAP headers (text)
6542 public $body_position = 0;
6543 // for multiref parsing:
6544 // array of id => pos
6545 public $ids = array();
6546 // array of id => hrefs => pos
6547 public $multirefs = array();
6548 // toggle for auto-decoding element content
6549 public $decode_utf8 = true;
6550
6560 public function __construct($xml, $encoding = 'UTF-8', $method = '', $decode_utf8 = true)
6561 {
6563 $this->xml = $xml;
6564 $this->xml_encoding = $encoding;
6565 $this->method = $method;
6566 $this->decode_utf8 = $decode_utf8;
6567
6568 // Check whether content has been read.
6569 if (!empty($xml)) {
6570 // Check XML encoding
6571 $pos_xml = strpos($xml, '<?xml');
6572 if ($pos_xml !== false) {
6573 $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
6574 if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
6575 $xml_encoding = $res[1];
6576 if (strtoupper($xml_encoding) != $encoding) {
6577 $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
6578 $this->debug($err);
6579 if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
6580 $this->setError($err);
6581 return;
6582 }
6583 // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
6584 } else {
6585 $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
6586 }
6587 } else {
6588 $this->debug('No encoding specified in XML declaration');
6589 }
6590 } else {
6591 $this->debug('No XML declaration');
6592 }
6593 $this->debug('Entering nusoap_parser(), length=' . strlen($xml) . ', encoding=' . $encoding);
6594 // Create an XML parser - why not xml_parser_create_ns?
6595 $this->parser = xml_parser_create($this->xml_encoding);
6596 // Set the options for parsing the XML data.
6597 //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
6598 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6599 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6600 // Set the object for the parser.
6601 // Set the element handlers for the parser.
6602 xml_set_element_handler($this->parser, $this->start_element(...), $this->end_element(...));
6603 xml_set_character_data_handler($this->parser, $this->character_data(...));
6604
6605 // Parse the XML file.
6606 if (!xml_parse($this->parser, $xml, true)) {
6607 // Display an error message.
6608 $err = sprintf(
6609 'XML error parsing SOAP payload on line %d: %s',
6610 xml_get_current_line_number($this->parser),
6611 xml_error_string(xml_get_error_code($this->parser))
6612 );
6613 $this->debug($err);
6614 $this->debug("XML payload:\n" . $xml);
6615 $this->setError($err);
6616 } else {
6617 $this->debug('parsed successfully, found root struct: ' . $this->root_struct . ' of name ' . $this->root_struct_name);
6618 // get final value
6619 $this->soapresponse = $this->message[$this->root_struct]['result'];
6620 // get header value
6621 if ($this->root_header != '' && isset($this->message[$this->root_header]['result'])) {
6622 $this->soapheader = $this->message[$this->root_header]['result'];
6623 }
6624 // resolve hrefs/ids
6625 if (sizeof($this->multirefs) > 0) {
6626 foreach ($this->multirefs as $id => $hrefs) {
6627 $this->debug('resolving multirefs for id: ' . $id);
6628 $idVal = $this->buildVal($this->ids[$id]);
6629 if (is_array($idVal) && isset($idVal['!id'])) {
6630 unset($idVal['!id']);
6631 }
6632 foreach ($hrefs as $refPos => $ref) {
6633 $this->debug('resolving href at pos ' . $refPos);
6634 $this->multirefs[$id][$refPos] = $idVal;
6635 }
6636 }
6637 }
6638 }
6639 } else {
6640 $this->debug('xml was empty, didn\'t parse!');
6641 $this->setError('xml was empty, didn\'t parse!');
6642 }
6643 }
6644
6653 public function start_element($parser, $name, $attrs)
6654 {
6655 // position in a total number of elements, starting from 0
6656 // update class level pos
6657 $pos = $this->position++;
6658 // and set mine
6659 $this->message[$pos] = array('pos' => $pos,'children' => '','cdata' => '');
6660 // depth = how many levels removed from root?
6661 // set mine as current global depth and increment global depth value
6662 $this->message[$pos]['depth'] = $this->depth++;
6663
6664 // else add self as child to whoever the current parent is
6665 if ($pos != 0) {
6666 $this->message[$this->parent]['children'] .= '|' . $pos;
6667 }
6668 // set my parent
6669 $this->message[$pos]['parent'] = $this->parent;
6670 // set self as current parent
6671 $this->parent = $pos;
6672 // set self as current value for this depth
6673 $this->depth_array[$this->depth] = $pos;
6674 // get element prefix
6675 if (strpos($name, ':')) {
6676 // get ns prefix
6677 $prefix = substr($name, 0, strpos($name, ':'));
6678 // get unqualified name
6679 $name = substr(strstr($name, ':'), 1);
6680 }
6681 // set status
6682 if ($name == 'Envelope') {
6683 $this->status = 'envelope';
6684 } elseif ($name == 'Header' && $this->status = 'envelope') {
6685 $this->root_header = $pos;
6686 $this->status = 'header';
6687 } elseif ($name == 'Body' && $this->status = 'envelope') {
6688 $this->status = 'body';
6689 $this->body_position = $pos;
6690 // set method
6691 } elseif ($this->status == 'body' && $pos == ($this->body_position + 1)) {
6692 $this->status = 'method';
6693 $this->root_struct_name = $name;
6694 $this->root_struct = $pos;
6695 $this->message[$pos]['type'] = 'struct';
6696 $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
6697 }
6698 // set my status
6699 $this->message[$pos]['status'] = $this->status;
6700 // set name
6701 $this->message[$pos]['name'] = htmlspecialchars($name);
6702 // set attrs
6703 $this->message[$pos]['attrs'] = $attrs;
6704
6705 // loop through atts, logging ns and type declarations
6706 $attstr = '';
6707 foreach ($attrs as $key => $value) {
6708 $key_prefix = $this->getPrefix($key);
6709 $key_localpart = $this->getLocalPart($key);
6710 // if ns declarations, add to class level array of valid namespaces
6711 if ($key_prefix == 'xmlns') {
6712 if (preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/', $value)) {
6713 $this->XMLSchemaVersion = $value;
6714 $this->namespaces['xsd'] = $this->XMLSchemaVersion;
6715 $this->namespaces['xsi'] = $this->XMLSchemaVersion . '-instance';
6716 }
6717 $this->namespaces[$key_localpart] = $value;
6718 // set method namespace
6719 if ($name == $this->root_struct_name) {
6720 $this->methodNamespace = $value;
6721 }
6722 // if it's a type declaration, set type
6723 } elseif ($key_localpart == 'type') {
6724 if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
6725 // do nothing: already processed arrayType
6726 } else {
6727 $value_prefix = $this->getPrefix($value);
6728 $value_localpart = $this->getLocalPart($value);
6729 $this->message[$pos]['type'] = $value_localpart;
6730 $this->message[$pos]['typePrefix'] = $value_prefix;
6731 if (isset($this->namespaces[$value_prefix])) {
6732 $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
6733 } elseif (isset($attrs['xmlns:' . $value_prefix])) {
6734 $this->message[$pos]['type_namespace'] = $attrs['xmlns:' . $value_prefix];
6735 }
6736 // should do something here with the namespace of specified type?
6737 }
6738 } elseif ($key_localpart == 'arrayType') {
6739 $this->message[$pos]['type'] = 'array';
6740 /* do arrayType ereg here
6741 [1] arrayTypeValue ::= atype asize
6742 [2] atype ::= QName rank*
6743 [3] rank ::= '[' (',')* ']'
6744 [4] asize ::= '[' length~ ']'
6745 [5] length ::= nextDimension* Digit+
6746 [6] nextDimension ::= Digit+ ','
6747 */
6748 $expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6749 if (preg_match($expr, $value, $regs)) {
6750 $this->message[$pos]['typePrefix'] = $regs[1];
6751 $this->message[$pos]['arrayTypePrefix'] = $regs[1];
6752 if (isset($this->namespaces[$regs[1]])) {
6753 $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6754 } elseif (isset($attrs['xmlns:' . $regs[1]])) {
6755 $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:' . $regs[1]];
6756 }
6757 $this->message[$pos]['arrayType'] = $regs[2];
6758 $this->message[$pos]['arraySize'] = $regs[3];
6759 $this->message[$pos]['arrayCols'] = $regs[4];
6760 }
6761 // specifies nil value (or not)
6762 } elseif ($key_localpart == 'nil') {
6763 $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
6764 // some other attribute
6765 } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
6766 $this->message[$pos]['xattrs']['!' . $key] = $value;
6767 }
6768
6769 if ($key == 'xmlns') {
6770 $this->default_namespace = $value;
6771 }
6772 // log id
6773 if ($key == 'id') {
6774 $this->ids[$value] = $pos;
6775 }
6776 // root
6777 if ($key_localpart == 'root' && $value == 1) {
6778 $this->status = 'method';
6779 $this->root_struct_name = $name;
6780 $this->root_struct = $pos;
6781 $this->debug("found root struct $this->root_struct_name, pos $pos");
6782 }
6783 // for doclit
6784 $attstr .= " $key=\"$value\"";
6785 }
6786 // get namespace - must be done after namespace atts are processed
6787 if (isset($prefix)) {
6788 $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
6789 $this->default_namespace = $this->namespaces[$prefix];
6790 } else {
6791 $this->message[$pos]['namespace'] = $this->default_namespace;
6792 }
6793 if ($this->status == 'header') {
6794 if ($this->root_header != $pos) {
6795 $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6796 }
6797 } elseif ($this->root_struct_name != '') {
6798 $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6799 }
6800 }
6801
6809 public function end_element($parser, $name)
6810 {
6811 // position of current element is equal to the last value left in depth_array for my depth
6812 $pos = $this->depth_array[$this->depth--];
6813
6814 // get element prefix
6815 if (strpos($name, ':')) {
6816 // get ns prefix
6817 $prefix = substr($name, 0, strpos($name, ':'));
6818 // get unqualified name
6819 $name = substr(strstr($name, ':'), 1);
6820 }
6821
6822 // build to native type
6823 if (isset($this->body_position) && $pos > $this->body_position) {
6824 // deal w/ multirefs
6825 if (isset($this->message[$pos]['attrs']['href'])) {
6826 // get id
6827 $id = substr($this->message[$pos]['attrs']['href'], 1);
6828 // add placeholder to href array
6829 $this->multirefs[$id][$pos] = 'placeholder';
6830 // add set a reference to it as the result value
6831 $this->message[$pos]['result'] = & $this->multirefs[$id][$pos];
6832 // build complexType values
6833 } elseif ($this->message[$pos]['children'] != '') {
6834 // if result has already been generated (struct/array)
6835 if (!isset($this->message[$pos]['result'])) {
6836 $this->message[$pos]['result'] = $this->buildVal($pos);
6837 }
6838 // build complexType values of attributes and possibly simpleContent
6839 } elseif (isset($this->message[$pos]['xattrs'])) {
6840 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6841 $this->message[$pos]['xattrs']['!'] = null;
6842 } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6843 if (isset($this->message[$pos]['type'])) {
6844 $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'] : '');
6845 } else {
6846 $parent = $this->message[$pos]['parent'];
6847 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6848 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6849 } else {
6850 $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
6851 }
6852 }
6853 }
6854 $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
6855 // set value of simpleType (or nil complexType)
6856 } else {
6857 //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
6858 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6859 $this->message[$pos]['xattrs']['!'] = null;
6860 } elseif (isset($this->message[$pos]['type'])) {
6861 $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'] : '');
6862 } else {
6863 $parent = $this->message[$pos]['parent'];
6864 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6865 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6866 } else {
6867 $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
6868 }
6869 }
6870
6871 /* add value to parent's result, if parent is struct/array
6872 $parent = $this->message[$pos]['parent'];
6873 if($this->message[$parent]['type'] != 'map'){
6874 if(strtolower($this->message[$parent]['type']) == 'array'){
6875 $this->message[$parent]['result'][] = $this->message[$pos]['result'];
6876 } else {
6877 $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
6878 }
6879 }
6880 */
6881 }
6882 }
6883
6884 // for doclit
6885 if ($this->status == 'header') {
6886 if ($this->root_header != $pos) {
6887 $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6888 }
6889 } elseif ($pos >= $this->root_struct) {
6890 $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6891 }
6892 // switch status
6893 if ($pos == $this->root_struct) {
6894 $this->status = 'body';
6895 $this->root_struct_namespace = $this->message[$pos]['namespace'];
6896 } elseif ($name == 'Body') {
6897 $this->status = 'envelope';
6898 } elseif ($name == 'Header') {
6899 $this->status = 'envelope';
6900 } elseif ($name == 'Envelope') {
6901 //
6902 }
6903 // set parent back to my parent
6904 $this->parent = $this->message[$pos]['parent'];
6905 }
6906
6914 public function character_data($parser, $data)
6915 {
6916 $pos = $this->depth_array[$this->depth];
6917 if ($this->xml_encoding == 'UTF-8') {
6918 // TODO: add an option to disable this for folks who want
6919 // raw UTF-8 that, e.g., might not map to iso-8859-1
6920 // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
6921 if ($this->decode_utf8) {
6922 $data = utf8_decode($data);
6923 }
6924 }
6925 $this->message[$pos]['cdata'] .= $data;
6926 // for doclit
6927 if ($this->status == 'header') {
6928 $this->responseHeaders .= $data;
6929 } else {
6930 $this->document .= $data;
6931 }
6932 }
6933
6941 public function get_response()
6942 {
6943 return $this->soapresponse;
6944 }
6945
6952 public function get_soapbody()
6953 {
6954 return $this->soapresponse;
6955 }
6956
6963 public function get_soapheader()
6964 {
6965 return $this->soapheader;
6966 }
6967
6974 public function getHeaders()
6975 {
6977 }
6978
6988 public function decodeSimple($value, $type, $typens)
6989 {
6990 // TODO: use the namespace!
6991 if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
6992 return (string) $value;
6993 }
6994 if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
6995 return (int) $value;
6996 }
6997 if ($type == 'float' || $type == 'double' || $type == 'decimal') {
6998 return (float) $value;
6999 }
7000 if ($type == 'boolean') {
7001 if (strtolower($value) == 'false' || strtolower($value) == 'f') {
7002 return false;
7003 }
7004 return (bool) $value;
7005 }
7006 if ($type == 'base64' || $type == 'base64Binary') {
7007 $this->debug('Decode base64 value');
7008 return base64_decode($value);
7009 }
7010 // obscure numeric types
7011 if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
7012 || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
7013 || $type == 'unsignedInt'
7014 || $type == 'unsignedShort' || $type == 'unsignedByte') {
7015 return (int) $value;
7016 }
7017 // bogus: parser treats array with no elements as a simple type
7018 if ($type == 'array') {
7019 return array();
7020 }
7021 // everything else
7022 return (string) $value;
7023 }
7024
7033 public function buildVal($pos)
7034 {
7035 if (!isset($this->message[$pos]['type'])) {
7036 $this->message[$pos]['type'] = '';
7037 }
7038 $this->debug('in buildVal() for ' . $this->message[$pos]['name'] . "(pos $pos) of type " . $this->message[$pos]['type']);
7039 // if there are children...
7040 if ($this->message[$pos]['children'] != '') {
7041 $this->debug('in buildVal, there are children');
7042 $children = explode('|', $this->message[$pos]['children']);
7043 array_shift($children); // knock off empty
7044 // md array
7045 if (isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != '') {
7046 $r = 0; // rowcount
7047 $c = 0; // colcount
7048 foreach ($children as $child_pos) {
7049 $this->debug("in buildVal, got an MD array element: $r, $c");
7050 $params[$r][] = $this->message[$child_pos]['result'];
7051 $c++;
7052 if ($c == $this->message[$pos]['arrayCols']) {
7053 $c = 0;
7054 $r++;
7055 }
7056 }
7057 // array
7058 } elseif ($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array') {
7059 $this->debug('in buildVal, adding array ' . $this->message[$pos]['name']);
7060 foreach ($children as $child_pos) {
7061 $params[] = &$this->message[$child_pos]['result'];
7062 }
7063 // apache Map type: java hashtable
7064 } elseif ($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
7065 $this->debug('in buildVal, Java Map ' . $this->message[$pos]['name']);
7066 foreach ($children as $child_pos) {
7067 $kv = explode("|", $this->message[$child_pos]['children']);
7068 $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
7069 }
7070 // generic compound type
7071 //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
7072 } else {
7073 // Apache Vector type: treat as an array
7074 $this->debug('in buildVal, adding Java Vector or generic compound type ' . $this->message[$pos]['name']);
7075 if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
7076 $notstruct = 1;
7077 } else {
7078 $notstruct = 0;
7079 }
7080 //
7081 foreach ($children as $child_pos) {
7082 if ($notstruct) {
7083 $params[] = &$this->message[$child_pos]['result'];
7084 } else {
7085 if (isset($params[$this->message[$child_pos]['name']])) {
7086 // de-serialize repeated element name into an array
7087 if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
7088 $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
7089 }
7090 $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
7091 } else {
7092 $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
7093 }
7094 }
7095 }
7096 }
7097 if (isset($this->message[$pos]['xattrs'])) {
7098 $this->debug('in buildVal, handling attributes');
7099 foreach ($this->message[$pos]['xattrs'] as $n => $v) {
7100 $params[$n] = $v;
7101 }
7102 }
7103 // handle simpleContent
7104 if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
7105 $this->debug('in buildVal, handling simpleContent');
7106 if (isset($this->message[$pos]['type'])) {
7107 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7108 } else {
7109 $parent = $this->message[$pos]['parent'];
7110 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7111 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7112 } else {
7113 $params['!'] = $this->message[$pos]['cdata'];
7114 }
7115 }
7116 }
7117 $ret = is_array($params) ? $params : array();
7118 $this->debug('in buildVal, return:');
7119 $this->appendDebug($this->varDump($ret));
7120 return $ret;
7121 } else {
7122 $this->debug('in buildVal, no children, building scalar');
7123 $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
7124 if (isset($this->message[$pos]['type'])) {
7125 $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7126 $this->debug("in buildVal, return: $ret");
7127 return $ret;
7128 }
7129 $parent = $this->message[$pos]['parent'];
7130 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7131 $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7132 $this->debug("in buildVal, return: $ret");
7133 return $ret;
7134 }
7135 $ret = $this->message[$pos]['cdata'];
7136 $this->debug("in buildVal, return: $ret");
7137 return $ret;
7138 }
7139 }
7140}
7141
7145class soap_parser extends nusoap_parser
7146{
7147}
7148
7149?><?php
7150
7151
7152
7173class nusoap_client extends nusoap_base
7174{
7175 public $return;
7176 public $wsdl;
7177 public $wsdlFile;
7178 public $opData;
7179 public $operation;
7180 public $username = ''; // Username for HTTP authentication
7181 public $password = ''; // Password for HTTP authentication
7182 public $authtype = ''; // Type of HTTP authentication
7183 public $certRequest = array(); // Certificate for HTTP SSL authentication
7184 public $requestHeaders = false; // SOAP headers in request (text)
7185 public $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
7186 public $responseHeader = null; // SOAP Header from response (parsed)
7187 public $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
7188 public $endpoint;
7189 public $forceEndpoint = ''; // overrides WSDL endpoint
7190 public $proxyhost = '';
7191 public $proxyport = '';
7192 public $proxyusername = '';
7193 public $proxypassword = '';
7194 public $xml_encoding = ''; // character set encoding of incoming (response) messages
7195 public $http_encoding = false;
7196 public $timeout = 0; // HTTP connection timeout
7197 public $response_timeout = 30; // HTTP response timeout
7198 public $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
7199 public $persistentConnection = false;
7200 public $defaultRpcParams = false; // This is no longer used
7201 public $request = ''; // HTTP request
7202 public $response = ''; // HTTP response
7203 public $responseData = ''; // SOAP payload of response
7204 public $cookies = array(); // Cookies from response or for request
7205 public $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
7206 public $operations = array(); // WSDL operations, empty for WSDL initialization error
7207 public $curl_options = array(); // User-specified cURL options
7208 public $bindingType = ''; // WSDL operation binding type
7209 public $use_curl = false; // whether to always try to use cURL
7210
7211 /*
7212 * fault related variables
7213 */
7218 public $fault;
7223 public $faultcode;
7228 public $faultstring;
7233 public $faultdetail;
7234
7249 public function __construct($endpoint, $wsdl = false, $proxyhost = false, $proxyport = false, $proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30)
7250 {
7252 $this->endpoint = $endpoint;
7253 $this->proxyhost = $proxyhost;
7254 $this->proxyport = $proxyport;
7255 $this->proxyusername = $proxyusername;
7256 $this->proxypassword = $proxypassword;
7257 $this->timeout = $timeout;
7258 $this->response_timeout = $response_timeout;
7259
7260 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7261 $this->appendDebug('endpoint=' . $this->varDump($endpoint));
7262
7263 // make values
7264 if ($wsdl) {
7265 if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
7266 $this->wsdl = $endpoint;
7267 $this->endpoint = $this->wsdl->wsdl;
7268 $this->wsdlFile = $this->endpoint;
7269 $this->debug('existing wsdl instance created from ' . $this->endpoint);
7270 $this->checkWSDL();
7271 } else {
7272 $this->wsdlFile = $this->endpoint;
7273 $this->wsdl = null;
7274 $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
7275 }
7276 $this->endpointType = 'wsdl';
7277 } else {
7278 $this->debug("instantiate SOAP with endpoint at $endpoint");
7279 $this->endpointType = 'soap';
7280 }
7281 }
7282
7308 public function call($operation, $params = array(), $namespace = 'http://tempuri.org', $soapAction = '', $headers = false, $rpcParams = null, $style = 'rpc', $use = 'encoded')
7309 {
7310 $this->operation = $operation;
7311 $this->fault = false;
7312 $this->setError('');
7313 $this->request = '';
7314 $this->response = '';
7315 $this->responseData = '';
7316 $this->faultstring = '';
7317 $this->faultcode = '';
7318 $this->opData = array();
7319
7320 $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7321 $this->appendDebug('params=' . $this->varDump($params));
7322 $this->appendDebug('headers=' . $this->varDump($headers));
7323 if ($headers) {
7324 $this->requestHeaders = $headers;
7325 }
7326 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7327 $this->loadWSDL();
7328 if ($this->getError()) {
7329 return false;
7330 }
7331 }
7332 // serialize parameters
7333 if ($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)) {
7334 // use WSDL for operation
7335 $this->opData = $opData;
7336 $this->debug("found operation");
7337 $this->appendDebug('opData=' . $this->varDump($opData));
7338 if (isset($opData['soapAction'])) {
7339 $soapAction = $opData['soapAction'];
7340 }
7341 if (! $this->forceEndpoint) {
7342 $this->endpoint = $opData['endpoint'];
7343 } else {
7344 $this->endpoint = $this->forceEndpoint;
7345 }
7346 $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
7347 $style = $opData['style'];
7348 $use = $opData['input']['use'];
7349 // add ns to ns array
7350 if ($namespace != '' && !isset($this->wsdl->namespaces[$namespace])) {
7351 $nsPrefix = 'ns' . rand(1000, 9999);
7352 $this->wsdl->namespaces[$nsPrefix] = $namespace;
7353 }
7354 $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
7355 // serialize payload
7356 if (is_string($params)) {
7357 $this->debug("serializing param string for WSDL operation $operation");
7358 $payload = $params;
7359 } elseif (is_array($params)) {
7360 $this->debug("serializing param array for WSDL operation $operation");
7361 $payload = $this->wsdl->serializeRPCParameters($operation, 'input', $params, $this->bindingType);
7362 } else {
7363 $this->debug('params must be array or string');
7364 $this->setError('params must be array or string');
7365 return false;
7366 }
7367 $usedNamespaces = $this->wsdl->usedNamespaces;
7368 if (isset($opData['input']['encodingStyle'])) {
7369 $encodingStyle = $opData['input']['encodingStyle'];
7370 } else {
7371 $encodingStyle = '';
7372 }
7373 $this->appendDebug($this->wsdl->getDebug());
7374 $this->wsdl->clearDebug();
7375 if ($errstr = $this->wsdl->getError()) {
7376 $this->debug('got wsdl error: ' . $errstr);
7377 $this->setError('wsdl error: ' . $errstr);
7378 return false;
7379 }
7380 } elseif ($this->endpointType == 'wsdl') {
7381 // operation not in WSDL
7382 $this->appendDebug($this->wsdl->getDebug());
7383 $this->wsdl->clearDebug();
7384 $this->setError('operation ' . $operation . ' not present.');
7385 $this->debug("operation '$operation' not present.");
7386 return false;
7387 } else {
7388 // no WSDL
7389 //$this->namespaces['ns1'] = $namespace;
7390 $nsPrefix = 'ns' . rand(1000, 9999);
7391 // serialize
7392 $payload = '';
7393 if (is_string($params)) {
7394 $this->debug("serializing param string for operation $operation");
7395 $payload = $params;
7396 } elseif (is_array($params)) {
7397 $this->debug("serializing param array for operation $operation");
7398 foreach ($params as $k => $v) {
7399 $payload .= $this->serialize_val($v, $k, false, false, false, false, $use);
7400 }
7401 } else {
7402 $this->debug('params must be array or string');
7403 $this->setError('params must be array or string');
7404 return false;
7405 }
7406 $usedNamespaces = array();
7407 if ($use == 'encoded') {
7408 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
7409 } else {
7410 $encodingStyle = '';
7411 }
7412 }
7413 // wrap RPC calls with method element
7414 if ($style == 'rpc') {
7415 if ($use == 'literal') {
7416 $this->debug("wrapping RPC request with literal method element");
7417 if ($namespace) {
7418 // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
7419 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7420 $payload .
7421 "</$nsPrefix:$operation>";
7422 } else {
7423 $payload = "<$operation>" . $payload . "</$operation>";
7424 }
7425 } else {
7426 $this->debug("wrapping RPC request with encoded method element");
7427 if ($namespace) {
7428 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7429 $payload .
7430 "</$nsPrefix:$operation>";
7431 } else {
7432 $payload = "<$operation>" .
7433 $payload .
7434 "</$operation>";
7435 }
7436 }
7437 }
7438 // serialize envelope
7439 $soapmsg = $this->serializeEnvelope($payload, $this->requestHeaders, $usedNamespaces, $style, $use, $encodingStyle);
7440 $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7441 $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7442 // send
7443 $return = $this->send($this->getHTTPBody($soapmsg), $soapAction, $this->timeout, $this->response_timeout);
7444 if ($errstr = $this->getError()) {
7445 $this->debug('Error: ' . $errstr);
7446 return false;
7447 } else {
7448 $this->return = $return;
7449 $this->debug('sent message successfully and got a(n) ' . gettype($return));
7450 $this->appendDebug('return=' . $this->varDump($return));
7451
7452 // fault?
7453 if (is_array($return) && isset($return['faultcode'])) {
7454 $this->debug('got fault');
7455 $this->setError($return['faultcode'] . ': ' . $return['faultstring']);
7456 $this->fault = true;
7457 foreach ($return as $k => $v) {
7458 $this->$k = $v;
7459 $this->debug("$k = $v<br>");
7460 }
7461 return $return;
7462 } elseif ($style == 'document') {
7463 // NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
7464 // we are only going to return the first part here...sorry about that
7465 return $return;
7466 } else {
7467 // array of return values
7468 if (is_array($return)) {
7469 // multiple 'out' parameters, which we return wrapped up
7470 // in the array
7471 if (sizeof($return) > 1) {
7472 return $return;
7473 }
7474 // single 'out' parameter (normally the return value)
7475 $return = array_shift($return);
7476 $this->debug('return shifted value: ');
7477 $this->appendDebug($this->varDump($return));
7478 return $return;
7479 // nothing returned (ie, echoVoid)
7480 } else {
7481 return "";
7482 }
7483 }
7484 }
7485 }
7486
7492 public function checkWSDL()
7493 {
7494 $this->appendDebug($this->wsdl->getDebug());
7495 $this->wsdl->clearDebug();
7496 $this->debug('checkWSDL');
7497 // catch errors
7498 if ($errstr = $this->wsdl->getError()) {
7499 $this->debug('got wsdl error: ' . $errstr);
7500 $this->setError('wsdl error: ' . $errstr);
7501 } elseif ($this->operations = $this->wsdl->getOperations('soap')) {
7502 $this->bindingType = 'soap';
7503 $this->debug('got ' . count($this->operations) . ' operations from wsdl ' . $this->wsdlFile . ' for binding type ' . $this->bindingType);
7504 } elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
7505 $this->bindingType = 'soap12';
7506 $this->debug('got ' . count($this->operations) . ' operations from wsdl ' . $this->wsdlFile . ' for binding type ' . $this->bindingType);
7507 $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
7508 } else {
7509 $this->debug('getOperations returned false');
7510 $this->setError('no operations defined in the WSDL document!');
7511 }
7512 }
7513
7519 public function loadWSDL()
7520 {
7521 $this->debug('instantiating wsdl class with doc: ' . $this->wsdlFile);
7522 $this->wsdl = new wsdl('', $this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword, $this->timeout, $this->response_timeout, $this->curl_options, $this->use_curl);
7523 $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7524 $this->wsdl->fetchWSDL($this->wsdlFile);
7525 $this->checkWSDL();
7526 }
7527
7535 public function getOperationData($operation)
7536 {
7537 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7538 $this->loadWSDL();
7539 if ($this->getError()) {
7540 return false;
7541 }
7542 }
7543 if (isset($this->operations[$operation])) {
7544 return $this->operations[$operation];
7545 }
7546 $this->debug("No data for operation: $operation");
7547 }
7548
7563 public function send($msg, $soapaction = '', $timeout = 0, $response_timeout = 30)
7564 {
7565 $this->checkCookies();
7566 // detect transport
7567 switch (true) {
7568 // http(s)
7569 case preg_match('/^http/', $this->endpoint):
7570 $this->debug('transporting via HTTP');
7571 if ($this->persistentConnection == true && is_object($this->persistentConnection)) {
7573 } else {
7574 $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
7575 if ($this->persistentConnection) {
7576 $http->usePersistentConnection();
7577 }
7578 }
7579 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7580 $http->setSOAPAction($soapaction);
7581 if ($this->proxyhost && $this->proxyport) {
7582 $http->setProxy($this->proxyhost, $this->proxyport, $this->proxyusername, $this->proxypassword);
7583 }
7584 if ($this->authtype != '') {
7585 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7586 }
7587 if ($this->http_encoding != '') {
7588 $http->setEncoding($this->http_encoding);
7589 }
7590 $this->debug('sending message, length=' . strlen($msg));
7591 if (preg_match('/^http:/', $this->endpoint)) {
7592 //if(strpos($this->endpoint,'http:')){
7593 $this->responseData = $http->send($msg, $timeout, $response_timeout, $this->cookies);
7594 } elseif (preg_match('/^https/', $this->endpoint)) {
7595 //} elseif(strpos($this->endpoint,'https:')){
7596 //if(phpversion() == '4.3.0-dev'){
7597 //$response = $http->send($msg,$timeout,$response_timeout);
7598 //$this->request = $http->outgoing_payload;
7599 //$this->response = $http->incoming_payload;
7600 //} else
7601 $this->responseData = $http->sendHTTPS($msg, $timeout, $response_timeout, $this->cookies);
7602 } else {
7603 $this->setError('no http/s in endpoint url');
7604 }
7605 $this->request = $http->outgoing_payload;
7606 $this->response = $http->incoming_payload;
7607 $this->appendDebug($http->getDebug());
7608 $this->UpdateCookies($http->incoming_cookies);
7609
7610 // save transport object if using persistent connections
7611 if ($this->persistentConnection) {
7612 $http->clearDebug();
7613 if (!is_object($this->persistentConnection)) {
7614 $this->persistentConnection = $http;
7615 }
7616 }
7617
7618 if ($err = $http->getError()) {
7619 $this->setError('HTTP Error: ' . $err);
7620 return false;
7621 } elseif ($this->getError()) {
7622 return false;
7623 } else {
7624 $this->debug('got response, length=' . strlen($this->responseData) . ' type=' . $http->incoming_headers['content-type']);
7625 return $this->parseResponse($http->incoming_headers, $this->responseData);
7626 }
7627 break;
7628 default:
7629 $this->setError('no transport found, or selected transport is not yet supported!');
7630 return false;
7631 break;
7632 }
7633 }
7634
7643 public function parseResponse($headers, $data)
7644 {
7645 $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
7646 $this->appendDebug($this->varDump($headers));
7647 if (!strstr($headers['content-type'], 'text/xml')) {
7648 $this->setError('Response not of type text/xml: ' . $headers['content-type']);
7649 return false;
7650 }
7651 if (strpos($headers['content-type'], '=')) {
7652 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
7653 $this->debug('Got response encoding: ' . $enc);
7654 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i', $enc)) {
7655 $this->xml_encoding = strtoupper($enc);
7656 } else {
7657 $this->xml_encoding = 'US-ASCII';
7658 }
7659 } else {
7660 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
7661 $this->xml_encoding = 'ISO-8859-1';
7662 }
7663 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
7664 $parser = new nusoap_parser($data, $this->xml_encoding, $this->operation, $this->decode_utf8);
7665 // add parser debug data to our debug
7666 $this->appendDebug($parser->getDebug());
7667 // if parse errors
7668 if ($errstr = $parser->getError()) {
7669 $this->setError($errstr);
7670 // destroy the parser object
7671 unset($parser);
7672 return false;
7673 } else {
7674 // get SOAP headers
7675 $this->responseHeaders = $parser->getHeaders();
7676 // get SOAP headers
7677 $this->responseHeader = $parser->get_soapheader();
7678 // get decoded message
7679 $return = $parser->get_soapbody();
7680 // add document for doclit support
7681 $this->document = $parser->document;
7682 // destroy the parser object
7683 unset($parser);
7684 // return decode message
7685 return $return;
7686 }
7687 }
7688
7696 public function setCurlOption($option, $value)
7697 {
7698 $this->debug("setCurlOption option=$option, value=");
7699 $this->appendDebug($this->varDump($value));
7700 $this->curl_options[$option] = $value;
7701 }
7702
7709 public function setEndpoint($endpoint)
7710 {
7711 $this->debug("setEndpoint(\"$endpoint\")");
7712 $this->forceEndpoint = $endpoint;
7713 }
7714
7721 public function setHeaders($headers)
7722 {
7723 $this->debug("setHeaders headers=");
7724 $this->appendDebug($this->varDump($headers));
7725 $this->requestHeaders = $headers;
7726 }
7727
7734 public function getHeaders()
7735 {
7737 }
7738
7745 public function getHeader()
7746 {
7747 return $this->responseHeader;
7748 }
7749
7759 public function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '')
7760 {
7761 $this->proxyhost = $proxyhost;
7762 $this->proxyport = $proxyport;
7763 $this->proxyusername = $proxyusername;
7764 $this->proxypassword = $proxypassword;
7765 }
7766
7776 public function setCredentials($username, $password, $authtype = 'basic', $certRequest = array())
7777 {
7778 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
7779 $this->appendDebug($this->varDump($certRequest));
7780 $this->username = $username;
7781 $this->password = $password;
7782 $this->authtype = $authtype;
7783 $this->certRequest = $certRequest;
7784 }
7785
7792 public function setHTTPEncoding($enc = 'gzip, deflate')
7793 {
7794 $this->debug("setHTTPEncoding(\"$enc\")");
7795 $this->http_encoding = $enc;
7796 }
7797
7804 public function setUseCURL($use)
7805 {
7806 $this->debug("setUseCURL($use)");
7807 $this->use_curl = $use;
7808 }
7809
7815 public function useHTTPPersistentConnection()
7816 {
7817 $this->debug("useHTTPPersistentConnection");
7818 $this->persistentConnection = true;
7819 }
7820
7832 public function getDefaultRpcParams()
7833 {
7835 }
7836
7848 public function setDefaultRpcParams($rpcParams)
7849 {
7850 $this->defaultRpcParams = $rpcParams;
7851 }
7852
7860 public function getProxy()
7861 {
7862 $r = rand();
7863 $evalStr = $this->_getProxyClassCode($r);
7864 //$this->debug("proxy class: $evalStr");
7865 if ($this->getError()) {
7866 $this->debug("Error from _getProxyClassCode, so return NULL");
7867 return null;
7868 }
7869 // eval the class
7870 eval($evalStr);
7871 // instantiate proxy object
7872 eval("\$proxy = new nusoap_proxy_$r('');");
7873 // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
7874 $proxy->endpointType = 'wsdl';
7875 $proxy->wsdlFile = $this->wsdlFile;
7876 $proxy->wsdl = $this->wsdl;
7877 $proxy->operations = $this->operations;
7878 $proxy->defaultRpcParams = $this->defaultRpcParams;
7879 // transfer other state
7880 $proxy->soap_defencoding = $this->soap_defencoding;
7881 $proxy->username = $this->username;
7882 $proxy->password = $this->password;
7883 $proxy->authtype = $this->authtype;
7884 $proxy->certRequest = $this->certRequest;
7885 $proxy->requestHeaders = $this->requestHeaders;
7886 $proxy->endpoint = $this->endpoint;
7887 $proxy->forceEndpoint = $this->forceEndpoint;
7888 $proxy->proxyhost = $this->proxyhost;
7889 $proxy->proxyport = $this->proxyport;
7890 $proxy->proxyusername = $this->proxyusername;
7891 $proxy->proxypassword = $this->proxypassword;
7892 $proxy->http_encoding = $this->http_encoding;
7893 $proxy->timeout = $this->timeout;
7894 $proxy->response_timeout = $this->response_timeout;
7895 $proxy->persistentConnection = &$this->persistentConnection;
7896 $proxy->decode_utf8 = $this->decode_utf8;
7897 $proxy->curl_options = $this->curl_options;
7898 $proxy->bindingType = $this->bindingType;
7899 $proxy->use_curl = $this->use_curl;
7900 return $proxy;
7901 }
7902
7909 public function _getProxyClassCode($r)
7910 {
7911 $this->debug("in getProxy endpointType=$this->endpointType");
7912 $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
7913 if ($this->endpointType != 'wsdl') {
7914 $evalStr = 'A proxy can only be created for a WSDL client';
7915 $this->setError($evalStr);
7916 $evalStr = "echo \"$evalStr\";";
7917 return $evalStr;
7918 }
7919 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7920 $this->loadWSDL();
7921 if ($this->getError()) {
7922 return "echo \"" . $this->getError() . "\";";
7923 }
7924 }
7925 $evalStr = '';
7926 foreach ($this->operations as $operation => $opData) {
7927 if ($operation != '') {
7928 // create param string and param comment string
7929 if (sizeof($opData['input']['parts']) > 0) {
7930 $paramStr = '';
7931 $paramArrayStr = '';
7932 $paramCommentStr = '';
7933 foreach ($opData['input']['parts'] as $name => $type) {
7934 $paramStr .= "\$$name, ";
7935 $paramArrayStr .= "'$name' => \$$name, ";
7936 $paramCommentStr .= "$type \$$name, ";
7937 }
7938 $paramStr = substr($paramStr, 0, strlen($paramStr) - 2);
7939 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr) - 2);
7940 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr) - 2);
7941 } else {
7942 $paramStr = '';
7943 $paramArrayStr = '';
7944 $paramCommentStr = 'void';
7945 }
7946 $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
7947 $evalStr .= "// $paramCommentStr
7948 function " . str_replace('.', '__', $operation) . "($paramStr) {
7949 \$params = array($paramArrayStr);
7950 return \$this->call('$operation', \$params, '" . $opData['namespace'] . "', '" . (isset($opData['soapAction']) ? $opData['soapAction'] : '') . "');
7951 }
7952 ";
7953 unset($paramStr);
7954 unset($paramCommentStr);
7955 }
7956 }
7957 $evalStr = 'class nusoap_proxy_' . $r . ' extends nusoap_client {
7958 ' . $evalStr . '
7959}';
7960 return $evalStr;
7961 }
7962
7969 public function getProxyClassCode()
7970 {
7971 $r = rand();
7972 return $this->_getProxyClassCode($r);
7973 }
7974
7982 public function getHTTPBody($soapmsg)
7983 {
7984 return $soapmsg;
7985 }
7986
7995 public function getHTTPContentType()
7996 {
7997 return 'text/xml';
7998 }
7999
8009 public function getHTTPContentTypeCharset()
8010 {
8012 }
8013
8014 /*
8015 * whether or not parser should decode utf8 element content
8016 *
8017 * @return always returns true
8018 * @access public
8019 */
8020 public function decodeUTF8($bool)
8021 {
8022 $this->decode_utf8 = $bool;
8023 return true;
8024 }
8025
8034 public function setCookie($name, $value)
8035 {
8036 if (strlen($name) == 0) {
8037 return false;
8038 }
8039 $this->cookies[] = array('name' => $name, 'value' => $value);
8040 return true;
8041 }
8042
8049 public function getCookies()
8050 {
8051 return $this->cookies;
8052 }
8053
8060 public function checkCookies()
8061 {
8062 if (sizeof($this->cookies) == 0) {
8063 return true;
8064 }
8065 $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
8066 $curr_cookies = $this->cookies;
8067 $this->cookies = array();
8068 foreach ($curr_cookies as $cookie) {
8069 if (! is_array($cookie)) {
8070 $this->debug('Remove cookie that is not an array');
8071 continue;
8072 }
8073 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
8074 if (strtotime($cookie['expires']) > time()) {
8075 $this->cookies[] = $cookie;
8076 } else {
8077 $this->debug('Remove expired cookie ' . $cookie['name']);
8078 }
8079 } else {
8080 $this->cookies[] = $cookie;
8081 }
8082 }
8083 $this->debug('checkCookie: ' . sizeof($this->cookies) . ' cookies left in array');
8084 return true;
8085 }
8086
8094 public function UpdateCookies($cookies)
8095 {
8096 if (sizeof($this->cookies) == 0) {
8097 // no existing cookies: take whatever is new
8098 if (sizeof($cookies) > 0) {
8099 $this->debug('Setting new cookie(s)');
8100 $this->cookies = $cookies;
8101 }
8102 return true;
8103 }
8104 if (sizeof($cookies) == 0) {
8105 // no new cookies: keep what we've got
8106 return true;
8107 }
8108 // merge
8109 foreach ($cookies as $newCookie) {
8110 if (!is_array($newCookie)) {
8111 continue;
8112 }
8113 if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
8114 continue;
8115 }
8116 $newName = $newCookie['name'];
8117
8118 $found = false;
8119 for ($i = 0; $i < count($this->cookies); $i++) {
8120 $cookie = $this->cookies[$i];
8121 if (!is_array($cookie)) {
8122 continue;
8123 }
8124 if (!isset($cookie['name'])) {
8125 continue;
8126 }
8127 if ($newName != $cookie['name']) {
8128 continue;
8129 }
8130 $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
8131 $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
8132 if ($newDomain != $domain) {
8133 continue;
8134 }
8135 $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
8136 $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
8137 if ($newPath != $path) {
8138 continue;
8139 }
8140 $this->cookies[$i] = $newCookie;
8141 $found = true;
8142 $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
8143 break;
8144 }
8145 if (! $found) {
8146 $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
8147 $this->cookies[] = $newCookie;
8148 }
8149 }
8150 return true;
8151 }
8152}
8153
8154if (!extension_loaded('soap')) {
8158 class soapclient extends nusoap_client
8159 {
8160 }
8161}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$out
Definition: buildRTE.php:24
$location
Definition: buildRTE.php:22
Backward compatibility.
Definition: nusoap.php:2014
nusoap_base
Definition: nusoap.php:55
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
Definition: nusoap.php:797
& getDebug()
gets the current debug data for this instance
Definition: nusoap.php:290
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
Definition: nusoap.php:304
setError($str)
sets error string
Definition: nusoap.php:353
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace
Definition: nusoap.php:813
debug($string)
adds debug data to the instance debug string with formatting
Definition: nusoap.php:250
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
Definition: nusoap.php:830
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded', $soapval=false)
serializes PHP values in accordance w/ section 5.
Definition: nusoap.php:391
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded', $encodingStyle='http://schemas.xmlsoap.org/soap/encoding/')
serializes a message
Definition: nusoap.php:658
clearDebug()
clears the current debug data for this instance
Definition: nusoap.php:277
expandEntities($val)
expands entities, e.g.
Definition: nusoap.php:321
$soap_defencoding
Definition: nusoap.php:122
expandQname($qname)
expands (changes prefix to namespace) a qualified name
Definition: nusoap.php:753
$XMLSchemaVersion
Definition: nusoap.php:113
varDump($data)
Returns a string with the output of var_dump.
Definition: nusoap.php:867
getError()
returns error string if present
Definition: nusoap.php:339
appendDebug($string)
adds debug data to the instance debug string without formatting
Definition: nusoap.php:263
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed
Definition: nusoap.php:779
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
Definition: nusoap.php:365
__construct()
constructor
Definition: nusoap.php:195
[nu]soapclient higher level class for easy usage.
Definition: nusoap.php:7174
setCurlOption($option, $value)
sets user-specified cURL options
Definition: nusoap.php:7696
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:7776
setHTTPProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='')
set proxy info here
Definition: nusoap.php:7759
getProxy()
dynamically creates an instance of a proxy class, allowing user to directly call methods from wsdl
Definition: nusoap.php:7860
send($msg, $soapaction='', $timeout=0, $response_timeout=30)
send the SOAP message
Definition: nusoap.php:7563
setUseCURL($use)
Set whether to try to use cURL connections if possible.
Definition: nusoap.php:7804
call($operation, $params=array(), $namespace='http://tempuri.org', $soapAction='', $headers=false, $rpcParams=null, $style='rpc', $use='encoded')
calls method, returns PHP native type
Definition: nusoap.php:7308
getProxyClassCode()
dynamically creates proxy class code
Definition: nusoap.php:7969
checkCookies()
checks all Cookies and delete those which are expired
Definition: nusoap.php:8060
getHTTPContentType()
gets the HTTP content type for the current request.
Definition: nusoap.php:7995
setHTTPEncoding($enc='gzip, deflate')
use HTTP encoding
Definition: nusoap.php:7792
getHeader()
get the SOAP response Header (parsed)
Definition: nusoap.php:7745
decodeUTF8($bool)
Definition: nusoap.php:8020
useHTTPPersistentConnection()
use HTTP persistent connections if possible
Definition: nusoap.php:7815
setCookie($name, $value)
adds a new Cookie into $this->cookies array
Definition: nusoap.php:8034
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current request.
Definition: nusoap.php:8009
getOperationData($operation)
get available data pertaining to an operation
Definition: nusoap.php:7535
getDefaultRpcParams()
gets the default RPC parameter setting.
Definition: nusoap.php:7832
checkWSDL()
check WSDL passed as an instance or pulled from an endpoint
Definition: nusoap.php:7492
setHeaders($headers)
set the SOAP headers
Definition: nusoap.php:7721
loadWSDL()
instantiate wsdl object and parse wsdl file
Definition: nusoap.php:7519
getHTTPBody($soapmsg)
gets the HTTP body for the current request.
Definition: nusoap.php:7982
setDefaultRpcParams($rpcParams)
sets the default RPC parameter setting.
Definition: nusoap.php:7848
setEndpoint($endpoint)
sets the SOAP endpoint, which can override WSDL
Definition: nusoap.php:7709
UpdateCookies($cookies)
updates the current cookies with a new set
Definition: nusoap.php:8094
getHeaders()
get the SOAP response headers (namespace resolution incomplete)
Definition: nusoap.php:7734
_getProxyClassCode($r)
dynamically creates proxy class code
Definition: nusoap.php:7909
getCookies()
gets all Cookies
Definition: nusoap.php:8049
parseResponse($headers, $data)
processes SOAP message returned from server
Definition: nusoap.php:7643
Contains information for a SOAP fault.
Definition: nusoap.php:994
serialize()
serialize a fault
Definition: nusoap.php:1043
nusoap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:6514
$root_struct_namespace
Definition: nusoap.php:6522
character_data($parser, $data)
element content handler
Definition: nusoap.php:6914
get_soapbody()
get the parsed SOAP Body (NULL if there was none)
Definition: nusoap.php:6952
end_element($parser, $name)
end-element handler
Definition: nusoap.php:6809
getHeaders()
get the unparsed SOAP Header
Definition: nusoap.php:6974
get_response()
get the parsed message (SOAP Body)
Definition: nusoap.php:6941
decodeSimple($value, $type, $typens)
decodes simple types into PHP variables
Definition: nusoap.php:6988
get_soapheader()
get the parsed SOAP Header (NULL if there was none)
Definition: nusoap.php:6963
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:6653
buildVal($pos)
builds response structures for compound values (arrays/structs) and scalars
Definition: nusoap.php:7033
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
Definition: nusoap.php:3476
verify_method($operation, $request)
takes the value that was created by parsing the request and compares to the method's signature,...
Definition: nusoap.php:4258
$methodreturnisliteralxml
Definition: nusoap.php:3587
getHTTPBody($soapmsg)
gets the HTTP body for the current response.
Definition: nusoap.php:4330
invoke_method()
invokes a PHP function for the requested SOAP method
Definition: nusoap.php:3939
add_to_map($methodname, $in, $out)
add a method to the dispatch map (this has been replaced by the register method)
Definition: nusoap.php:4371
getHTTPContentType()
gets the HTTP content type for the current response.
Definition: nusoap.php:4343
addInternalPort(string $serviceName, string $url)
Definition: nusoap.php:4551
parse_request($data='')
parses a request
Definition: nusoap.php:3891
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current response.
Definition: nusoap.php:4357
serialize_return()
serializes the return value from a PHP function into a full SOAP Envelope
Definition: nusoap.php:4085
send_response()
sends an HTTP response
Definition: nusoap.php:4178
fault($faultcode, $faultstring, $faultactor='', $faultdetail='')
Specify a fault to be returned to the client.
Definition: nusoap.php:4460
parse_http_headers()
parses HTTP request headers.
Definition: nusoap.php:3762
service($data)
processes request and returns response
Definition: nusoap.php:3699
parseRequest($headers, $data)
processes SOAP message received from client
Definition: nusoap.php:4278
configureWSDL($serviceName, $namespace=false, $endpoint=false, $style='rpc', $transport='http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace=false)
Sets up wsdl object.
Definition: nusoap.php:4480
parses an XML Schema, allows access to it's data, other utility methods.
Definition: nusoap.php:1086
schemaCharacterData($parser, $data)
element content handler
Definition: nusoap.php:1580
getTypeDef($type)
returns an associative array of information about a given type returns false if no type exists by the...
Definition: nusoap.php:1760
addComplexType($name, $typeClass='complexType', $phpType='array', $compositor='', $restrictionBase='', $elements=array(), $attrs=array(), $arrayType='')
adds a complex type to the schema
Definition: nusoap.php:1947
typeToForm($name, $type)
returns HTML form elements that allow a user to enter values for creating an instance of the given ty...
Definition: nusoap.php:1874
addElement($attrs)
adds an element to the schema
Definition: nusoap.php:1997
getPHPType($type, $ns)
get the PHP type of a user defined type in the schema PHP type is kind of a misnomer since it actuall...
Definition: nusoap.php:1726
xdebug($string)
adds debug data to the clas level debug string
Definition: nusoap.php:1709
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array())
adds a simple type to the schema
Definition: nusoap.php:1976
serializeSchema()
serialize the schema
Definition: nusoap.php:1591
parseString($xml, $type)
parse an XML string
Definition: nusoap.php:1184
schemaEndElement($parser, $name)
end-element handler
Definition: nusoap.php:1542
schemaStartElement($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:1244
serializeTypeDef($type)
returns a sample serialization of a given type, or false if no type by the given name
Definition: nusoap.php:1837
parseFile($xml, $type)
parse an XML file
Definition: nusoap.php:1157
CreateTypeName($ename)
gets a type name for an unnamed type
Definition: nusoap.php:1227
Backward compatibility.
Definition: nusoap.php:1069
Backward compatibility.
Definition: nusoap.php:7146
Backward compatibility.
Definition: nusoap.php:4565
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
Definition: nusoap.php:2139
sendRequest($data, $cookies=null)
sends the SOAP request via HTTP[S]
Definition: nusoap.php:2886
setCurlOption($option, $value)
sets a cURL option
Definition: nusoap.php:2207
getCookiesForRequest($cookies, $secure=false)
sort out cookies for the current request
Definition: nusoap.php:3420
send($data, $timeout=0, $response_timeout=30, $cookies=null)
sends the SOAP request and gets the SOAP response via HTTP[S]
Definition: nusoap.php:2554
parseCookie($cookie_str)
parse an incoming Cookie into it's parts
Definition: nusoap.php:3353
setURL($url)
sets the URL to which to connect
Definition: nusoap.php:2247
getResponse()
gets the SOAP response via HTTP[S]
Definition: nusoap.php:2944
setContentType($type, $charset=false)
sets the content-type for the SOAP message to be sent
Definition: nusoap.php:3321
unsetHeader($name)
unsets an HTTP header
Definition: nusoap.php:2233
isSkippableCurlHeader(&$data)
Test if the given string starts with a header that is to be skipped.
Definition: nusoap.php:2750
setSOAPAction($soapaction)
set the soapaction value
Definition: nusoap.php:2685
setEncoding($enc='gzip, deflate')
use http encoding
Definition: nusoap.php:2696
usePersistentConnection()
specifies that an HTTP persistent connection should be used
Definition: nusoap.php:3332
setCredentials($username, $password, $authtype='basic', $digestRequest=array(), $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:2610
buildPayload($data, $cookie_str='')
Writes the payload, including HTTP headers, to $this->outgoing_payload.
Definition: nusoap.php:2838
connect($connection_timeout=0, $response_timeout=30)
establish an HTTP connection
Definition: nusoap.php:2311
setHeader($name, $value)
sets an HTTP header
Definition: nusoap.php:2221
io_method()
gets the I/O method to use
Definition: nusoap.php:2292
decodeChunked($buffer, $lb)
decode a string that is encoded w/ "chunked' transfer encoding as defined in RFC2068 19....
Definition: nusoap.php:2780
setProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='', $proxyauthtype='basic')
set proxy info here
Definition: nusoap.php:2721
sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies=null)
sends the SOAP request and gets the SOAP response via HTTPS using CURL
Definition: nusoap.php:2595
For creating serializable abstractions of native PHP types.
Definition: nusoap.php:2033
serialize($use='encoded')
return serialized value
Definition: nusoap.php:2106
$element_ns
Definition: nusoap.php:2061
decode()
decodes a soapval object into a PHP native type
Definition: nusoap.php:2117
$attributes
Definition: nusoap.php:2075
parses a WSDL file, allows access to it's data, other utility methods.
Definition: nusoap.php:4582
$currentMessage
Definition: nusoap.php:4594
$import
Definition: nusoap.php:4607
$username
Definition: nusoap.php:4623
$ports
Definition: nusoap.php:4600
$proxyhost
Definition: nusoap.php:4614
character_data($parser, $data)
element content handler
Definition: nusoap.php:5114
serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
serializes the attributes for a complexType
Definition: nusoap.php:6179
$opData
Definition: nusoap.php:4602
$currentSchema
Definition: nusoap.php:4590
getBindingData($binding)
Definition: nusoap.php:5144
serializeRPCParameters($operation, $direction, $parameters, $bindingType='soap')
serialize PHP values according to a WSDL message definition contrary to the method name,...
Definition: nusoap.php:5702
$currentPortType
Definition: nusoap.php:4597
addElement($attrs)
adds an element to the WSDL types
Definition: nusoap.php:6408
getTypeDef($type, $ns)
returns an array of information about a given type returns false if no type exists by the given name
Definition: nusoap.php:5261
$status
Definition: nusoap.php:4603
getOperations($bindingType='soap')
returns an assoc array of operation names => operation data
Definition: nusoap.php:5158
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:5134
$serviceName
Definition: nusoap.php:4584
$proxypassword
Definition: nusoap.php:4617
$certRequest
Definition: nusoap.php:4626
getOperationData($operation, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:5190
$currentPortOperation
Definition: nusoap.php:4586
$portTypes
Definition: nusoap.php:4596
$currentOperation
Definition: nusoap.php:4595
$messages
Definition: nusoap.php:4593
serializeParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
Definition: nusoap.php:5797
fetchWSDL($wsdl)
fetches the WSDL document and parses it
Definition: nusoap.php:4664
$password
Definition: nusoap.php:4624
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array())
adds an XML Schema simple type to the WSDL types
Definition: nusoap.php:6393
$depth
Definition: nusoap.php:4611
$bindings
Definition: nusoap.php:4598
serialize($debug=0)
serialize the parsed wsdl
Definition: nusoap.php:5460
$wsdl
Definition: nusoap.php:4587
$timeout
Definition: nusoap.php:4618
$endpoint
Definition: nusoap.php:4605
$use_curl
Definition: nusoap.php:4621
$proxyusername
Definition: nusoap.php:4616
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:5222
$documentation
Definition: nusoap.php:4604
webDescription()
prints html description of services
Definition: nusoap.php:5318
serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
serializes a PHP value according a given type definition
Definition: nusoap.php:5875
parseWSDL($wsdl='')
parses the wsdl document
Definition: nusoap.php:4768
$message
Definition: nusoap.php:4591
parametersMatchWrapped($type, &$parameters)
determine whether a set of parameters are unwrapped when they are expect to be wrapped,...
Definition: nusoap.php:5608
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:4870
$proxyport
Definition: nusoap.php:4615
$authtype
Definition: nusoap.php:4625
end_element($parser, $name)
end-element handler
Definition: nusoap.php:5083
$parser
Definition: nusoap.php:4609
$depth_array
Definition: nusoap.php:4612
serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false)
serializes the elements for a complexType
Definition: nusoap.php:6242
$position
Definition: nusoap.php:4610
$schemas
Definition: nusoap.php:4589
$currentPort
Definition: nusoap.php:4601
$complexTypes
Definition: nusoap.php:4592
$curl_options
Definition: nusoap.php:4620
$response_timeout
Definition: nusoap.php:4619
addComplexType($name, $typeClass='complexType', $phpType='array', $compositor='', $restrictionBase='', $elements=array(), $attrs=array(), $arrayType='')
adds an XML Schema complex type to the WSDL types
Definition: nusoap.php:6345
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='', $encodingStyle='')
register an operation with the server
Definition: nusoap.php:6428
$currentBinding
Definition: nusoap.php:4599
$opStatus
Definition: nusoap.php:4585
$http
Definition: deliver.php:30
$c
Definition: deliver.php:25
if($err=$client->getError()) $namespace
$_GET['cmd']
Definition: lti.php:26
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:31
$scope
Definition: ltiregstart.php:51
$path
Definition: ltiservices.php:30
if(empty($path)) $serviceName
Definition: ltiservices.php:37
$res
Definition: ltiservices.php:69
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:61
if(count($parts) !=3) $payload
Definition: ltitoken.php:67
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
catch(\Exception $e) $req
Definition: xapiproxy.php:78
$_SERVER['HTTP_HOST']
Definition: raiseError.php:26
$url
Definition: shib_logout.php:70
$param
Definition: xapitoken.php:44

Variable Documentation

◆ globalDebugLevel

if (!isset( $GLOBALS[ '_transient'])||!isset( $GLOBALS[ '_transient'][ 'static'])||!isset( $GLOBALS[ '_transient'][ 'static'][ 'nusoap_base'])||!is_object( $GLOBALS[ '_transient'][ 'static'][ 'nusoap_base'])) $GLOBALS ['_transient']['static']['nusoap_base'] globalDebugLevel = 0

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V.

ILIAS is licensed with the GPL-3.0, see https://www.gnu.org/licenses/gpl-3.0.en.html You should have received a copy of said license along with the source code, too.

If this is not the case or you just want to try ILIAS, you'll find us at: https://www.ilias.de https://github.com/ILIAS-eLearning

Definition at line 43 of file nusoap.php.