ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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
 soap_fault class, allows for creation of faults mainly used for returning faults from deployed functions in a server instance. More...
 
class  nusoap_xmlschema
 parses an XML Schema, allows access to it's data, other utility methods. More...
 
class  XMLSchema
 parses an XML Schema, allows access to it's data, other utility methods no validation... yet. More...
 
class  soapval
 for creating serializable abstractions of native PHP types NOTE: this is only really used when WSDL is not available. 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
 soap_server allows the user to create a SOAP server that is capable of receiving messages and returning responses 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
 soap_parser class parses SOAP XML messages into native PHP values 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
 

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 943 of file nusoap.php.

943 {
944 $pattern = '/'.
945 '([0-9]{4})-'. // centuries & years CCYY-
946 '([0-9]{2})-'. // months MM-
947 '([0-9]{2})'. // days DD
948 'T'. // separator T
949 '([0-9]{2}):'. // hours hh:
950 '([0-9]{2}):'. // minutes mm:
951 '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
952 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
953 '/';
954
955 if(preg_match($pattern,$datestr,$regs)){
956 // not utc
957 if($regs[8] != 'Z'){
958 $op = substr($regs[8],0,1);
959 $h = substr($regs[8],1,2);
960 $m = substr($regs[8],strlen($regs[8])-2,2);
961 if($op == '-'){
962 $regs[4] = $regs[4] + $h;
963 $regs[5] = $regs[5] + $m;
964 } elseif($op == '+'){
965 $regs[4] = $regs[4] - $h;
966 $regs[5] = $regs[5] - $m;
967 }
968 }
969 return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
970// return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
971 } else {
972 return false;
973 }
974}

◆ 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 914 of file nusoap.php.

914 {
915 $datestr = date('Y-m-d\TH:i:sO',$timestamp);
916 if($utc){
917 $pattern = '/'.
918 '([0-9]{4})-'. // centuries & years CCYY-
919 '([0-9]{2})-'. // months MM-
920 '([0-9]{2})'. // days DD
921 'T'. // separator T
922 '([0-9]{2}):'. // hours hh:
923 '([0-9]{2}):'. // minutes mm:
924 '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
925 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
926 '/';
927
928 if(preg_match($pattern,$datestr,$regs)){
929 return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
930 }
931 return false;
932 } else {
933 return $datestr;
934 }
935}
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81

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 983 of file nusoap.php.

984{
985 $start = gettimeofday();
986
987 do
988 {
989 $stop = gettimeofday();
990 $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
991 + $stop['usec'] - $start['usec'];
992 }
993 while ($timePassed < $usec);
994}
995
996?><?php
997
998
999
1008class nusoap_fault extends nusoap_base {
1014 var $faultcode;
1020 var $faultactor;
1026 var $faultstring;
1032 var $faultdetail;
1033
1044 $this->faultcode = $faultcode;
1045 $this->faultactor = $faultactor;
1046 $this->faultstring = $faultstring;
1047 $this->faultdetail = $faultdetail;
1048 }
1049
1056 function serialize(){
1057 $ns_string = '';
1058 foreach($this->namespaces as $k => $v){
1059 $ns_string .= "\n xmlns:$k=\"$v\"";
1060 }
1061 $return_msg =
1062 '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
1063 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
1064 '<SOAP-ENV:Body>'.
1065 '<SOAP-ENV:Fault>'.
1066 $this->serialize_val($this->faultcode, 'faultcode').
1067 $this->serialize_val($this->faultstring, 'faultstring').
1068 $this->serialize_val($this->faultactor, 'faultactor').
1069 $this->serialize_val($this->faultdetail, 'detail').
1070 '</SOAP-ENV:Fault>'.
1071 '</SOAP-ENV:Body>'.
1072 '</SOAP-ENV:Envelope>';
1073 return $return_msg;
1074 }
1075}
1076
1080class soap_fault extends nusoap_fault {
1081}
1082
1083?><?php
1084
1085
1086
1096class nusoap_xmlschema extends nusoap_base {
1097
1098 // files
1099 var $schema = '';
1100 var $xml = '';
1101 // namespaces
1103 // schema info
1104 var $schemaInfo = array();
1105 var $schemaTargetNamespace = '';
1106 // types, elements, attributes defined by the schema
1107 var $attributes = array();
1108 var $complexTypes = array();
1109 var $complexTypeStack = array();
1110 var $currentComplexType = null;
1111 var $elements = array();
1112 var $elementStack = array();
1113 var $currentElement = null;
1114 var $simpleTypes = array();
1115 var $simpleTypeStack = array();
1116 var $currentSimpleType = null;
1117 // imports
1118 var $imports = array();
1119 // parser vars
1120 var $parser;
1121 var $position = 0;
1122 var $depth = 0;
1123 var $depth_array = array();
1124 var $message = array();
1125 var $defaultNamespace = array();
1126
1135 function __construct($schema='',$xml='',$namespaces=array()){
1137 $this->debug('nusoap_xmlschema class instantiated, inside constructor');
1138 // files
1139 $this->schema = $schema;
1140 $this->xml = $xml;
1141
1142 // namespaces
1143 $this->enclosingNamespaces = $namespaces;
1144 $this->namespaces = array_merge($this->namespaces, $namespaces);
1145
1146 // parse schema file
1147 if($schema != ''){
1148 $this->debug('initial schema file: '.$schema);
1149 $this->parseFile($schema, 'schema');
1150 }
1151
1152 // parse xml file
1153 if($xml != ''){
1154 $this->debug('initial xml file: '.$xml);
1155 $this->parseFile($xml, 'xml');
1156 }
1157
1158 }
1159
1168 function parseFile($xml,$type){
1169 // parse xml file
1170 if($xml != ""){
1171 $xmlStr = @join("",@file($xml));
1172 if($xmlStr == ""){
1173 $msg = 'Error reading XML from '.$xml;
1174 $this->setError($msg);
1175 $this->debug($msg);
1176 return false;
1177 } else {
1178 $this->debug("parsing $xml");
1179 $this->parseString($xmlStr,$type);
1180 $this->debug("done parsing $xml");
1181 return true;
1182 }
1183 }
1184 return false;
1185 }
1186
1194 function parseString($xml,$type){
1195 // parse xml string
1196 if($xml != ""){
1197
1198 // Create an XML parser.
1199 $this->parser = xml_parser_create();
1200 // Set the options for parsing the XML data.
1201 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1202
1203 // Set the object for the parser.
1204 xml_set_object($this->parser, $this);
1205
1206 // Set the element handlers for the parser.
1207 if($type == "schema"){
1208 xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
1209 xml_set_character_data_handler($this->parser,'schemaCharacterData');
1210 } elseif($type == "xml"){
1211 xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
1212 xml_set_character_data_handler($this->parser,'xmlCharacterData');
1213 }
1214
1215 // Parse the XML file.
1216 if(!xml_parse($this->parser,$xml,true)){
1217 // Display an error message.
1218 $errstr = sprintf('XML error parsing XML schema on line %d: %s',
1219 xml_get_current_line_number($this->parser),
1220 xml_error_string(xml_get_error_code($this->parser))
1221 );
1222 $this->debug($errstr);
1223 $this->debug("XML payload:\n" . $xml);
1224 $this->setError($errstr);
1225 }
1226
1227 xml_parser_free($this->parser);
1228 } else{
1229 $this->debug('no xml passed to parseString()!!');
1230 $this->setError('no xml passed to parseString()!!');
1231 }
1232 }
1233
1241 function CreateTypeName($ename) {
1242 $scope = '';
1243 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1244 $scope .= $this->complexTypeStack[$i] . '_';
1245 }
1246 return $scope . $ename . '_ContainedType';
1247 }
1248
1257 function schemaStartElement($parser, $name, $attrs) {
1258
1259 // position in the total number of elements, starting from 0
1260 $pos = $this->position++;
1261 $depth = $this->depth++;
1262 // set self as current value for this depth
1263 $this->depth_array[$depth] = $pos;
1264 $this->message[$pos] = array('cdata' => '');
1265 if ($depth > 0) {
1266 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1267 } else {
1268 $this->defaultNamespace[$pos] = false;
1269 }
1270
1271 // get element prefix
1272 if($prefix = $this->getPrefix($name)){
1273 // get unqualified name
1274 $name = $this->getLocalPart($name);
1275 } else {
1276 $prefix = '';
1277 }
1278
1279 // loop thru attributes, expanding, and registering namespace declarations
1280 if(count($attrs) > 0){
1281 foreach($attrs as $k => $v){
1282 // if ns declarations, add to class level array of valid namespaces
1283 if(preg_match('/^xmlns/',$k)){
1284 //$this->xdebug("$k: $v");
1285 //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
1286 if($ns_prefix = substr(strrchr($k,':'),1)){
1287 //$this->xdebug("Add namespace[$ns_prefix] = $v");
1288 $this->namespaces[$ns_prefix] = $v;
1289 } else {
1290 $this->defaultNamespace[$pos] = $v;
1291 if (! $this->getPrefixFromNamespace($v)) {
1292 $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
1293 }
1294 }
1295 if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
1296 $this->XMLSchemaVersion = $v;
1297 $this->namespaces['xsi'] = $v.'-instance';
1298 }
1299 }
1300 }
1301 foreach($attrs as $k => $v){
1302 // expand each attribute
1303 $k = strpos($k,':') ? $this->expandQname($k) : $k;
1304 $v = strpos($v,':') ? $this->expandQname($v) : $v;
1305 $eAttrs[$k] = $v;
1306 }
1307 $attrs = $eAttrs;
1308 } else {
1309 $attrs = array();
1310 }
1311 // find status, register data
1312 switch($name){
1313 case 'all': // (optional) compositor content for a complexType
1314 case 'choice':
1315 case 'group':
1316 case 'sequence':
1317 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
1318 $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
1319 //if($name == 'all' || $name == 'sequence'){
1320 // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1321 //}
1322 break;
1323 case 'attribute': // complexType attribute
1324 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
1325 $this->xdebug("parsing attribute:");
1326 $this->appendDebug($this->varDump($attrs));
1327 if (!isset($attrs['form'])) {
1328 $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
1329 }
1330 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1331 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1332 if (!strpos($v, ':')) {
1333 // no namespace in arrayType attribute value...
1334 if ($this->defaultNamespace[$pos]) {
1335 // ...so use the default
1336 $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1337 }
1338 }
1339 }
1340 if(isset($attrs['name'])){
1341 $this->attributes[$attrs['name']] = $attrs;
1342 $aname = $attrs['name'];
1343 } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1344 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1345 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1346 } else {
1347 $aname = '';
1348 }
1349 } elseif(isset($attrs['ref'])){
1350 $aname = $attrs['ref'];
1351 $this->attributes[$attrs['ref']] = $attrs;
1352 }
1353
1354 if($this->currentComplexType){ // This should *always* be
1355 $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
1356 }
1357 // arrayType attribute
1358 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
1359 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1360 $prefix = $this->getPrefix($aname);
1361 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1362 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1363 } else {
1364 $v = '';
1365 }
1366 if(strpos($v,'[,]')){
1367 $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
1368 }
1369 $v = substr($v,0,strpos($v,'[')); // clip the []
1370 if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
1371 $v = $this->XMLSchemaVersion.':'.$v;
1372 }
1373 $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
1374 }
1375 break;
1376 case 'complexContent': // (optional) content for a complexType
1377 break;
1378 case 'complexType':
1379 array_push($this->complexTypeStack, $this->currentComplexType);
1380 if(isset($attrs['name'])){
1381 // TODO: what is the scope of named complexTypes that appear
1382 // nested within other c complexTypes?
1383 $this->xdebug('processing named complexType '.$attrs['name']);
1384 //$this->currentElement = false;
1385 $this->currentComplexType = $attrs['name'];
1386 $this->complexTypes[$this->currentComplexType] = $attrs;
1387 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1388 // This is for constructs like
1389 // <complexType name="ListOfString" base="soap:Array">
1390 // <sequence>
1391 // <element name="string" type="xsd:string"
1392 // minOccurs="0" maxOccurs="unbounded" />
1393 // </sequence>
1394 // </complexType>
1395 if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1396 $this->xdebug('complexType is unusual array');
1397 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1398 } else {
1399 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1400 }
1401 } else {
1402 $name = $this->CreateTypeName($this->currentElement);
1403 $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
1404 $this->currentComplexType = $name;
1405 //$this->currentElement = false;
1406 $this->complexTypes[$this->currentComplexType] = $attrs;
1407 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1408 // This is for constructs like
1409 // <complexType name="ListOfString" base="soap:Array">
1410 // <sequence>
1411 // <element name="string" type="xsd:string"
1412 // minOccurs="0" maxOccurs="unbounded" />
1413 // </sequence>
1414 // </complexType>
1415 if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1416 $this->xdebug('complexType is unusual array');
1417 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1418 } else {
1419 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1420 }
1421 }
1422 break;
1423 case 'element':
1424 array_push($this->elementStack, $this->currentElement);
1425 if (!isset($attrs['form'])) {
1426 $attrs['form'] = $this->schemaInfo['elementFormDefault'];
1427 }
1428 if(isset($attrs['type'])){
1429 $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
1430 if (! $this->getPrefix($attrs['type'])) {
1431 if ($this->defaultNamespace[$pos]) {
1432 $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
1433 $this->xdebug('used default namespace to make type ' . $attrs['type']);
1434 }
1435 }
1436 // This is for constructs like
1437 // <complexType name="ListOfString" base="soap:Array">
1438 // <sequence>
1439 // <element name="string" type="xsd:string"
1440 // minOccurs="0" maxOccurs="unbounded" />
1441 // </sequence>
1442 // </complexType>
1443 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
1444 $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
1445 $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
1446 }
1447 $this->currentElement = $attrs['name'];
1448 $ename = $attrs['name'];
1449 } elseif(isset($attrs['ref'])){
1450 $this->xdebug("processing element as ref to ".$attrs['ref']);
1451 $this->currentElement = "ref to ".$attrs['ref'];
1452 $ename = $this->getLocalPart($attrs['ref']);
1453 } else {
1454 $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
1455 $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
1456 $this->currentElement = $attrs['name'];
1457 $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
1458 $ename = $attrs['name'];
1459 }
1460 if (isset($ename) && $this->currentComplexType) {
1461 $this->xdebug("add element $ename to complexType $this->currentComplexType");
1462 $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
1463 } elseif (!isset($attrs['ref'])) {
1464 $this->xdebug("add element $ename to elements array");
1465 $this->elements[ $attrs['name'] ] = $attrs;
1466 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
1467 }
1468 break;
1469 case 'enumeration': // restriction value list member
1470 $this->xdebug('enumeration ' . $attrs['value']);
1471 if ($this->currentSimpleType) {
1472 $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
1473 } elseif ($this->currentComplexType) {
1474 $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
1475 }
1476 break;
1477 case 'extension': // simpleContent or complexContent type extension
1478 $this->xdebug('extension ' . $attrs['base']);
1479 if ($this->currentComplexType) {
1480 $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
1481 }
1482 break;
1483 case 'import':
1484 if (isset($attrs['schemaLocation'])) {
1485 //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
1486 $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
1487 } else {
1488 //$this->xdebug('import namespace ' . $attrs['namespace']);
1489 $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
1490 if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
1491 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
1492 }
1493 }
1494 break;
1495 case 'list': // simpleType value list
1496 break;
1497 case 'restriction': // simpleType, simpleContent or complexContent value restriction
1498 $this->xdebug('restriction ' . $attrs['base']);
1499 if($this->currentSimpleType){
1500 $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
1501 } elseif($this->currentComplexType){
1502 $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
1503 if(strstr($attrs['base'],':') == ':Array'){
1504 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1505 }
1506 }
1507 break;
1508 case 'schema':
1509 $this->schemaInfo = $attrs;
1510 $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
1511 if (isset($attrs['targetNamespace'])) {
1512 $this->schemaTargetNamespace = $attrs['targetNamespace'];
1513 }
1514 if (!isset($attrs['elementFormDefault'])) {
1515 $this->schemaInfo['elementFormDefault'] = 'unqualified';
1516 }
1517 if (!isset($attrs['attributeFormDefault'])) {
1518 $this->schemaInfo['attributeFormDefault'] = 'unqualified';
1519 }
1520 break;
1521 case 'simpleContent': // (optional) content for a complexType
1522 break;
1523 case 'simpleType':
1524 array_push($this->simpleTypeStack, $this->currentSimpleType);
1525 if(isset($attrs['name'])){
1526 $this->xdebug("processing simpleType for name " . $attrs['name']);
1527 $this->currentSimpleType = $attrs['name'];
1528 $this->simpleTypes[ $attrs['name'] ] = $attrs;
1529 $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
1530 $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
1531 } else {
1532 $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
1533 $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
1534 $this->currentSimpleType = $name;
1535 //$this->currentElement = false;
1536 $this->simpleTypes[$this->currentSimpleType] = $attrs;
1537 $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
1538 }
1539 break;
1540 case 'union': // simpleType type list
1541 break;
1542 default:
1543 //$this->xdebug("do not have anything to do for element $name");
1544 }
1545 }
1546
1554 function schemaEndElement($parser, $name) {
1555 // bring depth down a notch
1556 $this->depth--;
1557 // position of current element is equal to the last value left in depth_array for my depth
1558 if(isset($this->depth_array[$this->depth])){
1559 $pos = $this->depth_array[$this->depth];
1560 }
1561 // get element prefix
1562 if ($prefix = $this->getPrefix($name)){
1563 // get unqualified name
1564 $name = $this->getLocalPart($name);
1565 } else {
1566 $prefix = '';
1567 }
1568 // move on...
1569 if($name == 'complexType'){
1570 $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
1571 $this->currentComplexType = array_pop($this->complexTypeStack);
1572 //$this->currentElement = false;
1573 }
1574 if($name == 'element'){
1575 $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
1576 $this->currentElement = array_pop($this->elementStack);
1577 }
1578 if($name == 'simpleType'){
1579 $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
1580 $this->currentSimpleType = array_pop($this->simpleTypeStack);
1581 }
1582 }
1583
1592 $pos = $this->depth_array[$this->depth - 1];
1593 $this->message[$pos]['cdata'] .= $data;
1594 }
1595
1601 function serializeSchema(){
1602
1603 $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
1604 $xml = '';
1605 // imports
1606 if (sizeof($this->imports) > 0) {
1607 foreach($this->imports as $ns => $list) {
1608 foreach ($list as $ii) {
1609 if ($ii['location'] != '') {
1610 $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
1611 } else {
1612 $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
1613 }
1614 }
1615 }
1616 }
1617 // complex types
1618 foreach($this->complexTypes as $typeName => $attrs){
1619 $contentStr = '';
1620 // serialize child elements
1621 if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
1622 foreach($attrs['elements'] as $element => $eParts){
1623 if(isset($eParts['ref'])){
1624 $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
1625 } else {
1626 $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
1627 foreach ($eParts as $aName => $aValue) {
1628 // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
1629 if ($aName != 'name' && $aName != 'type') {
1630 $contentStr .= " $aName=\"$aValue\"";
1631 }
1632 }
1633 $contentStr .= "/>\n";
1634 }
1635 }
1636 // compositor wraps elements
1637 if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
1638 $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
1639 }
1640 }
1641 // attributes
1642 if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
1643 foreach($attrs['attrs'] as $attr => $aParts){
1644 $contentStr .= " <$schemaPrefix:attribute";
1645 foreach ($aParts as $a => $v) {
1646 if ($a == 'ref' || $a == 'type') {
1647 $contentStr .= " $a=\"".$this->contractQName($v).'"';
1648 } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1649 $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
1650 $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
1651 } else {
1652 $contentStr .= " $a=\"$v\"";
1653 }
1654 }
1655 $contentStr .= "/>\n";
1656 }
1657 }
1658 // if restriction
1659 if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
1660 $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
1661 // complex or simple content
1662 if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
1663 $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
1664 }
1665 }
1666 // finalize complex type
1667 if($contentStr != ''){
1668 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
1669 } else {
1670 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1671 }
1672 $xml .= $contentStr;
1673 }
1674 // simple types
1675 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
1676 foreach($this->simpleTypes as $typeName => $eParts){
1677 $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
1678 if (isset($eParts['enumeration'])) {
1679 foreach ($eParts['enumeration'] as $e) {
1680 $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
1681 }
1682 }
1683 $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1684 }
1685 }
1686 // elements
1687 if(isset($this->elements) && count($this->elements) > 0){
1688 foreach($this->elements as $element => $eParts){
1689 $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
1690 }
1691 }
1692 // attributes
1693 if(isset($this->attributes) && count($this->attributes) > 0){
1694 foreach($this->attributes as $attr => $aParts){
1695 $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
1696 }
1697 }
1698 // finish 'er up
1699 $attr = '';
1700 foreach ($this->schemaInfo as $k => $v) {
1701 if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
1702 $attr .= " $k=\"$v\"";
1703 }
1704 }
1705 $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1706 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1707 $el .= " xmlns:$nsp=\"$ns\"";
1708 }
1709 $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
1710 return $xml;
1711 }
1712
1719 function xdebug($string){
1720 $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
1721 }
1722
1735 function getPHPType($type,$ns){
1736 if(isset($this->typemap[$ns][$type])){
1737 //print "found type '$type' and ns $ns in typemap<br>";
1738 return $this->typemap[$ns][$type];
1739 } elseif(isset($this->complexTypes[$type])){
1740 //print "getting type '$type' and ns $ns from complexTypes array<br>";
1741 return $this->complexTypes[$type]['phpType'];
1742 }
1743 return false;
1744 }
1745
1768 function getTypeDef($type){
1769 //$this->debug("in getTypeDef for type $type");
1770 if (substr($type, -1) == '^') {
1771 $is_element = 1;
1772 $type = substr($type, 0, -1);
1773 } else {
1774 $is_element = 0;
1775 }
1776
1777 if((! $is_element) && isset($this->complexTypes[$type])){
1778 $this->xdebug("in getTypeDef, found complexType $type");
1779 return $this->complexTypes[$type];
1780 } elseif((! $is_element) && isset($this->simpleTypes[$type])){
1781 $this->xdebug("in getTypeDef, found simpleType $type");
1782 if (!isset($this->simpleTypes[$type]['phpType'])) {
1783 // get info for type to tack onto the simple type
1784 // TODO: can this ever really apply (i.e. what is a simpleType really?)
1785 $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
1786 $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
1787 $etype = $this->getTypeDef($uqType);
1788 if ($etype) {
1789 $this->xdebug("in getTypeDef, found type for simpleType $type:");
1790 $this->xdebug($this->varDump($etype));
1791 if (isset($etype['phpType'])) {
1792 $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
1793 }
1794 if (isset($etype['elements'])) {
1795 $this->simpleTypes[$type]['elements'] = $etype['elements'];
1796 }
1797 }
1798 }
1799 return $this->simpleTypes[$type];
1800 } elseif(isset($this->elements[$type])){
1801 $this->xdebug("in getTypeDef, found element $type");
1802 if (!isset($this->elements[$type]['phpType'])) {
1803 // get info for type to tack onto the element
1804 $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
1805 $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
1806 $etype = $this->getTypeDef($uqType);
1807 if ($etype) {
1808 $this->xdebug("in getTypeDef, found type for element $type:");
1809 $this->xdebug($this->varDump($etype));
1810 if (isset($etype['phpType'])) {
1811 $this->elements[$type]['phpType'] = $etype['phpType'];
1812 }
1813 if (isset($etype['elements'])) {
1814 $this->elements[$type]['elements'] = $etype['elements'];
1815 }
1816 } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
1817 $this->xdebug("in getTypeDef, element $type is an XSD type");
1818 $this->elements[$type]['phpType'] = 'scalar';
1819 }
1820 }
1821 return $this->elements[$type];
1822 } elseif(isset($this->attributes[$type])){
1823 $this->xdebug("in getTypeDef, found attribute $type");
1824 return $this->attributes[$type];
1825 } elseif (preg_match('/_ContainedType$/', $type)) {
1826 $this->xdebug("in getTypeDef, have an untyped element $type");
1827 $typeDef['typeClass'] = 'simpleType';
1828 $typeDef['phpType'] = 'scalar';
1829 $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
1830 return $typeDef;
1831 }
1832 $this->xdebug("in getTypeDef, did not find $type");
1833 return false;
1834 }
1835
1844 function serializeTypeDef($type){
1845 //print "in sTD() for type $type<br>";
1846 if($typeDef = $this->getTypeDef($type)){
1847 $str .= '<'.$type;
1848 if(is_array($typeDef['attrs'])){
1849 foreach($typeDef['attrs'] as $attName => $data){
1850 $str .= " $attName=\"{type = ".$data['type']."}\"";
1851 }
1852 }
1853 $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
1854 if(count($typeDef['elements']) > 0){
1855 $str .= ">";
1856 foreach($typeDef['elements'] as $element => $eData){
1857 $str .= $this->serializeTypeDef($element);
1858 }
1859 $str .= "</$type>";
1860 } elseif($typeDef['typeClass'] == 'element') {
1861 $str .= "></$type>";
1862 } else {
1863 $str .= "/>";
1864 }
1865 return $str;
1866 }
1867 return false;
1868 }
1869
1880 function typeToForm($name,$type){
1881 // get typedef
1882 if($typeDef = $this->getTypeDef($type)){
1883 // if struct
1884 if($typeDef['phpType'] == 'struct'){
1885 $buffer .= '<table>';
1886 foreach($typeDef['elements'] as $child => $childDef){
1887 $buffer .= "
1888 <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
1889 <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
1890 }
1891 $buffer .= '</table>';
1892 // if array
1893 } elseif($typeDef['phpType'] == 'array'){
1894 $buffer .= '<table>';
1895 for($i=0;$i < 3; $i++){
1896 $buffer .= "
1897 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
1898 <td><input type='text' name='parameters[".$name."][]'></td></tr>";
1899 }
1900 $buffer .= '</table>';
1901 // if scalar
1902 } else {
1903 $buffer .= "<input type='text' name='parameters[$name]'>";
1904 }
1905 } else {
1906 $buffer .= "<input type='text' name='parameters[$name]'>";
1907 }
1908 return $buffer;
1909 }
1910
1952 function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
1953 $this->complexTypes[$name] = array(
1954 'name' => $name,
1955 'typeClass' => $typeClass,
1956 'phpType' => $phpType,
1957 'compositor'=> $compositor,
1958 'restrictionBase' => $restrictionBase,
1959 'elements' => $elements,
1960 'attrs' => $attrs,
1961 'arrayType' => $arrayType
1962 );
1963
1964 $this->xdebug("addComplexType $name:");
1965 $this->appendDebug($this->varDump($this->complexTypes[$name]));
1966 }
1967
1980 function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
1981 $this->simpleTypes[$name] = array(
1982 'name' => $name,
1983 'typeClass' => $typeClass,
1984 'phpType' => $phpType,
1985 'type' => $restrictionBase,
1986 'enumeration' => $enumeration
1987 );
1988
1989 $this->xdebug("addSimpleType $name:");
1990 $this->appendDebug($this->varDump($this->simpleTypes[$name]));
1991 }
1992
2000 function addElement($attrs) {
2001 if (! $this->getPrefix($attrs['type'])) {
2002 $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
2003 }
2004 $this->elements[ $attrs['name'] ] = $attrs;
2005 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
2006
2007 $this->xdebug("addElement " . $attrs['name']);
2008 $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
2009 }
2010}
2011
2015class XMLSchema extends nusoap_xmlschema {
2016}
2017
2018?><?php
2019
2020
2021
2033class soapval extends nusoap_base {
2040 var $name;
2047 var $type;
2054 var $value;
2061 var $element_ns;
2068 var $type_ns;
2075 var $attributes;
2076
2088 function __construct($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
2090 $this->name = $name;
2091 $this->type = $type;
2092 $this->value = $value;
2093 $this->element_ns = $element_ns;
2094 $this->type_ns = $type_ns;
2095 $this->attributes = $attributes;
2096 }
2097
2105 function serialize($use='encoded') {
2106 return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
2107 }
2108
2115 function decode(){
2116 return $this->value;
2117 }
2118}
2119
2120
2121
2122?><?php
2123
2124
2125
2135class soap_transport_http extends nusoap_base {
2136
2137 var $url = '';
2138 var $uri = '';
2139 var $digest_uri = '';
2140 var $scheme = '';
2141 var $host = '';
2142 var $port = '';
2143 var $path = '';
2144 var $request_method = 'POST';
2145 var $protocol_version = '1.0';
2146 var $encoding = '';
2147 var $outgoing_headers = array();
2148 var $incoming_headers = array();
2149 var $incoming_cookies = array();
2150 var $outgoing_payload = '';
2151 var $incoming_payload = '';
2152 var $response_status_line; // HTTP response status line
2153 var $useSOAPAction = true;
2154 var $persistentConnection = false;
2155 var $ch = false; // cURL handle
2156 var $ch_options = array(); // cURL custom options
2157 var $use_curl = false; // force cURL use
2158 var $proxy = null; // proxy information (associative array)
2159 var $username = '';
2160 var $password = '';
2161 var $authtype = '';
2162 var $digestRequest = array();
2163 var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional)
2164 // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
2165 // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
2166 // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
2167 // passphrase: SSL key password/passphrase
2168 // certpassword: SSL certificate password
2169 // verifypeer: default is 1
2170 // verifyhost: default is 1
2171
2180 function __construct($url, $curl_options = NULL, $use_curl = false){
2182 $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
2183 $this->appendDebug($this->varDump($curl_options));
2184 $this->setURL($url);
2185 if (is_array($curl_options)) {
2186 $this->ch_options = $curl_options;
2187 }
2188 $this->use_curl = $use_curl;
2189 preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
2190 $this->setHeader('User-Agent', $this->title.'/'.$this->version.' ('.$rev[1].')');
2191 }
2192
2200 function setCurlOption($option, $value) {
2201 $this->debug("setCurlOption option=$option, value=");
2202 $this->appendDebug($this->varDump($value));
2203 curl_setopt($this->ch, $option, $value);
2204 }
2205
2213 function setHeader($name, $value) {
2214 $this->outgoing_headers[$name] = $value;
2215 $this->debug("set header $name: $value");
2216 }
2217
2224 function unsetHeader($name) {
2225 if (isset($this->outgoing_headers[$name])) {
2226 $this->debug("unset header $name");
2227 unset($this->outgoing_headers[$name]);
2228 }
2229 }
2230
2237 function setURL($url) {
2238 $this->url = $url;
2239
2240 $u = parse_url($url);
2241 foreach($u as $k => $v){
2242 $this->debug("parsed URL $k = $v");
2243 $this->$k = $v;
2244 }
2245
2246 // add any GET params to path
2247 if(isset($u['query']) && $u['query'] != ''){
2248 $this->path .= '?' . $u['query'];
2249 }
2250
2251 // set default port
2252 if(!isset($u['port'])){
2253 if($u['scheme'] == 'https'){
2254 $this->port = 443;
2255 } else {
2256 $this->port = 80;
2257 }
2258 }
2259
2260 $this->uri = $this->path;
2261 $this->digest_uri = $this->uri;
2262
2263 // build headers
2264 if (!isset($u['port'])) {
2265 $this->setHeader('Host', $this->host);
2266 } else {
2267 $this->setHeader('Host', $this->host.':'.$this->port);
2268 }
2269
2270 if (isset($u['user']) && $u['user'] != '') {
2271 $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
2272 }
2273 }
2274
2281 function io_method() {
2282 if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
2283 return 'curl';
2284 if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
2285 return 'socket';
2286 return 'unknown';
2287 }
2288
2297 function connect($connection_timeout=0,$response_timeout=30){
2298 // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
2299 // "regular" socket.
2300 // TODO: disabled for now because OpenSSL must be *compiled* in (not just
2301 // loaded), and until PHP5 stream_get_wrappers is not available.
2302// if ($this->scheme == 'https') {
2303// if (version_compare(phpversion(), '4.3.0') >= 0) {
2304// if (extension_loaded('openssl')) {
2305// $this->scheme = 'ssl';
2306// $this->debug('Using SSL over OpenSSL');
2307// }
2308// }
2309// }
2310 $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2311 if ($this->io_method() == 'socket') {
2312 if (!is_array($this->proxy)) {
2315 } else {
2316 $host = $this->proxy['host'];
2317 $port = $this->proxy['port'];
2318 }
2319
2320 // use persistent connection
2321 if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
2322 if (!feof($this->fp)) {
2323 $this->debug('Re-use persistent connection');
2324 return true;
2325 }
2326 fclose($this->fp);
2327 $this->debug('Closed persistent connection at EOF');
2328 }
2329
2330 // munge host if using OpenSSL
2331 if ($this->scheme == 'ssl') {
2332 $host = 'ssl://' . $host;
2333 }
2334 $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
2335
2336 // open socket
2337 if($connection_timeout > 0){
2338 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2339 } else {
2340 $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
2341 }
2342
2343 // test pointer
2344 if(!$this->fp) {
2345 $msg = 'Couldn\'t open socket connection to server ' . $this->url;
2346 if ($this->errno) {
2347 $msg .= ', Error ('.$this->errno.'): '.$this->error_str;
2348 } else {
2349 $msg .= ' prior to connect(). This is often a problem looking up the host name.';
2350 }
2351 $this->debug($msg);
2352 $this->setError($msg);
2353 return false;
2354 }
2355
2356 // set response timeout
2357 $this->debug('set response timeout to ' . $response_timeout);
2358 socket_set_timeout( $this->fp, $response_timeout);
2359
2360 $this->debug('socket connected');
2361 return true;
2362 } else if ($this->io_method() == 'curl') {
2363 if (!extension_loaded('curl')) {
2364// $this->setError('cURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
2365 $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.');
2366 return false;
2367 }
2368 // Avoid warnings when PHP does not have these options
2369 if (defined('CURLOPT_CONNECTIONTIMEOUT'))
2370 $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2371 else
2372 $CURLOPT_CONNECTIONTIMEOUT = 78;
2373 if (defined('CURLOPT_HTTPAUTH'))
2374 $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2375 else
2376 $CURLOPT_HTTPAUTH = 107;
2377 if (defined('CURLOPT_PROXYAUTH'))
2378 $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2379 else
2380 $CURLOPT_PROXYAUTH = 111;
2381 if (defined('CURLAUTH_BASIC'))
2382 $CURLAUTH_BASIC = CURLAUTH_BASIC;
2383 else
2384 $CURLAUTH_BASIC = 1;
2385 if (defined('CURLAUTH_DIGEST'))
2386 $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2387 else
2388 $CURLAUTH_DIGEST = 2;
2389 if (defined('CURLAUTH_NTLM'))
2390 $CURLAUTH_NTLM = CURLAUTH_NTLM;
2391 else
2392 $CURLAUTH_NTLM = 8;
2393
2394 $this->debug('connect using cURL');
2395 // init CURL
2396 $this->ch = curl_init();
2397 // set url
2398 $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
2399 // add path
2400 $hostURL .= $this->path;
2401 $this->setCurlOption(CURLOPT_URL, $hostURL);
2402 // follow location headers (re-directs)
2403 if (ini_get('safe_mode') || ini_get('open_basedir')) {
2404 $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2405 $this->debug('safe_mode = ');
2406 $this->appendDebug($this->varDump(ini_get('safe_mode')));
2407 $this->debug('open_basedir = ');
2408 $this->appendDebug($this->varDump(ini_get('open_basedir')));
2409 } else {
2410 $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2411 }
2412 // ask for headers in the response output
2413 $this->setCurlOption(CURLOPT_HEADER, 1);
2414 // ask for the response output as the return value
2415 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2416 // encode
2417 // We manage this ourselves through headers and encoding
2418// if(function_exists('gzuncompress')){
2419// $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
2420// }
2421 // persistent connection
2422 if ($this->persistentConnection) {
2423 // I believe the following comment is now bogus, having applied to
2424 // the code when it used CURLOPT_CUSTOMREQUEST to send the request.
2425 // The way we send data, we cannot use persistent connections, since
2426 // there will be some "junk" at the end of our request.
2427 //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
2428 $this->persistentConnection = false;
2429 $this->setHeader('Connection', 'close');
2430 }
2431 // set timeouts
2432 if ($connection_timeout != 0) {
2433 $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2434 }
2435 if ($response_timeout != 0) {
2436 $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2437 }
2438
2439 if ($this->scheme == 'https') {
2440 $this->debug('set cURL SSL verify options');
2441 // recent versions of cURL turn on peer/host checking by default,
2442 // while PHP binaries are not compiled with a default location for the
2443 // CA cert bundle, so disable peer/host checking.
2444 //$this->setCurlOption(CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
2445 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2446 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2447
2448 // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
2449 if ($this->authtype == 'certificate') {
2450 $this->debug('set cURL certificate options');
2451 if (isset($this->certRequest['cainfofile'])) {
2452 $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
2453 }
2454 if (isset($this->certRequest['verifypeer'])) {
2455 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
2456 } else {
2457 $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2458 }
2459 if (isset($this->certRequest['verifyhost'])) {
2460 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
2461 } else {
2462 $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2463 }
2464 if (isset($this->certRequest['sslcertfile'])) {
2465 $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
2466 }
2467 if (isset($this->certRequest['sslkeyfile'])) {
2468 $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
2469 }
2470 if (isset($this->certRequest['passphrase'])) {
2471 $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
2472 }
2473 if (isset($this->certRequest['certpassword'])) {
2474 $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
2475 }
2476 }
2477 }
2478 if ($this->authtype && ($this->authtype != 'certificate')) {
2479 if ($this->username) {
2480 $this->debug('set cURL username/password');
2481 $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
2482 }
2483 if ($this->authtype == 'basic') {
2484 $this->debug('set cURL for Basic authentication');
2485 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2486 }
2487 if ($this->authtype == 'digest') {
2488 $this->debug('set cURL for digest authentication');
2489 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2490 }
2491 if ($this->authtype == 'ntlm') {
2492 $this->debug('set cURL for NTLM authentication');
2493 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2494 }
2495 }
2496 if (is_array($this->proxy)) {
2497 $this->debug('set cURL proxy options');
2498 if ($this->proxy['port'] != '') {
2499 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'].':'.$this->proxy['port']);
2500 } else {
2501 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
2502 }
2503 if ($this->proxy['username'] || $this->proxy['password']) {
2504 $this->debug('set cURL proxy authentication options');
2505 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'].':'.$this->proxy['password']);
2506 if ($this->proxy['authtype'] == 'basic') {
2507 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2508 }
2509 if ($this->proxy['authtype'] == 'ntlm') {
2510 $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2511 }
2512 }
2513 }
2514 $this->debug('cURL connection set up');
2515 return true;
2516 } else {
2517 $this->setError('Unknown scheme ' . $this->scheme);
2518 $this->debug('Unknown scheme ' . $this->scheme);
2519 return false;
2520 }
2521 }
2522
2533 function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
2534
2535 $this->debug('entered send() with data of length: '.strlen($data));
2536
2537 $this->tryagain = true;
2538 $tries = 0;
2539 while ($this->tryagain) {
2540 $this->tryagain = false;
2541 if ($tries++ < 2) {
2542 // make connnection
2543 if (!$this->connect($timeout, $response_timeout)){
2544 return false;
2545 }
2546
2547 // send request
2548 if (!$this->sendRequest($data, $cookies)){
2549 return false;
2550 }
2551
2552 // get response
2553 $respdata = $this->getResponse();
2554 } else {
2555 $this->setError("Too many tries to get an OK response ($this->response_status_line)");
2556 }
2557 }
2558 $this->debug('end of send()');
2559 return $respdata;
2560 }
2561
2562
2574 function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
2575 return $this->send($data, $timeout, $response_timeout, $cookies);
2576 }
2577
2588 function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
2589 $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
2590 $this->appendDebug($this->varDump($digestRequest));
2591 $this->debug("certRequest=");
2592 $this->appendDebug($this->varDump($certRequest));
2593 // cf. RFC 2617
2594 if ($authtype == 'basic') {
2595 $this->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
2596 } elseif ($authtype == 'digest') {
2597 if (isset($digestRequest['nonce'])) {
2598 $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
2599
2600 // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
2601
2602 // A1 = unq(username-value) ":" unq(realm-value) ":" passwd
2603 $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
2604
2605 // H(A1) = MD5(A1)
2606 $HA1 = md5($A1);
2607
2608 // A2 = Method ":" digest-uri-value
2609 $A2 = $this->request_method . ':' . $this->digest_uri;
2610
2611 // H(A2)
2612 $HA2 = md5($A2);
2613
2614 // KD(secret, data) = H(concat(secret, ":", data))
2615 // if qop == auth:
2616 // request-digest = <"> < KD ( H(A1), unq(nonce-value)
2617 // ":" nc-value
2618 // ":" unq(cnonce-value)
2619 // ":" unq(qop-value)
2620 // ":" H(A2)
2621 // ) <">
2622 // if qop is missing,
2623 // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
2624
2625 $unhashedDigest = '';
2626 $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
2627 $cnonce = $nonce;
2628 if ($digestRequest['qop'] != '') {
2629 $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
2630 } else {
2631 $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
2632 }
2633
2634 $hashedDigest = md5($unhashedDigest);
2635
2636 $opaque = '';
2637 if (isset($digestRequest['opaque'])) {
2638 $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
2639 }
2640
2641 $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 . '"');
2642 }
2643 } elseif ($authtype == 'certificate') {
2644 $this->certRequest = $certRequest;
2645 $this->debug('Authorization header not set for certificate');
2646 } elseif ($authtype == 'ntlm') {
2647 // do nothing
2648 $this->debug('Authorization header not set for ntlm');
2649 }
2650 $this->username = $username;
2651 $this->password = $password;
2652 $this->authtype = $authtype;
2653 $this->digestRequest = $digestRequest;
2654 }
2655
2662 function setSOAPAction($soapaction) {
2663 $this->setHeader('SOAPAction', '"' . $soapaction . '"');
2664 }
2665
2672 function setEncoding($enc='gzip, deflate') {
2673 if (function_exists('gzdeflate')) {
2674 $this->protocol_version = '1.1';
2675 $this->setHeader('Accept-Encoding', $enc);
2676 if (!isset($this->outgoing_headers['Connection'])) {
2677 $this->setHeader('Connection', 'close');
2678 $this->persistentConnection = false;
2679 }
2680 #set_magic_quotes_runtime(0);
2681 // deprecated
2682 $this->encoding = $enc;
2683 }
2684 }
2685
2696 function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic') {
2697 if ($proxyhost) {
2698 $this->proxy = array(
2699 'host' => $proxyhost,
2700 'port' => $proxyport,
2701 'username' => $proxyusername,
2702 'password' => $proxypassword,
2703 'authtype' => $proxyauthtype
2704 );
2705 if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
2706 $this->setHeader('Proxy-Authorization', ' Basic '.base64_encode($proxyusername.':'.$proxypassword));
2707 }
2708 } else {
2709 $this->debug('remove proxy');
2710 $proxy = null;
2711 unsetHeader('Proxy-Authorization');
2712 }
2713 }
2714
2715
2724 function isSkippableCurlHeader(&$data) {
2725 $skipHeaders = array( 'HTTP/1.1 100',
2726 'HTTP/1.0 301',
2727 'HTTP/1.1 301',
2728 'HTTP/1.0 302',
2729 'HTTP/1.1 302',
2730 'HTTP/1.0 401',
2731 'HTTP/1.1 401',
2732 'HTTP/1.0 200 Connection established');
2733 foreach ($skipHeaders as $hd) {
2734 $prefix = substr($data, 0, strlen($hd));
2735 if ($prefix == $hd) return true;
2736 }
2737
2738 return false;
2739 }
2740
2751 function decodeChunked($buffer, $lb){
2752 // length := 0
2753 $length = 0;
2754 $new = '';
2755
2756 // read chunk-size, chunk-extension (if any) and CRLF
2757 // get the position of the linebreak
2758 $chunkend = strpos($buffer, $lb);
2759 if ($chunkend == FALSE) {
2760 $this->debug('no linebreak found in decodeChunked');
2761 return $new;
2762 }
2763 $temp = substr($buffer,0,$chunkend);
2764 $chunk_size = hexdec( trim($temp) );
2765 $chunkstart = $chunkend + strlen($lb);
2766 // while (chunk-size > 0) {
2767 while ($chunk_size > 0) {
2768 $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
2769 $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
2770
2771 // Just in case we got a broken connection
2772 if ($chunkend == FALSE) {
2773 $chunk = substr($buffer,$chunkstart);
2774 // append chunk-data to entity-body
2775 $new .= $chunk;
2776 $length += strlen($chunk);
2777 break;
2778 }
2779
2780 // read chunk-data and CRLF
2781 $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2782 // append chunk-data to entity-body
2783 $new .= $chunk;
2784 // length := length + chunk-size
2785 $length += strlen($chunk);
2786 // read chunk-size and CRLF
2787 $chunkstart = $chunkend + strlen($lb);
2788
2789 $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2790 if ($chunkend == FALSE) {
2791 break; //Just in case we got a broken connection
2792 }
2793 $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2794 $chunk_size = hexdec( trim($temp) );
2795 $chunkstart = $chunkend;
2796 }
2797 return $new;
2798 }
2799
2808 function buildPayload($data, $cookie_str = '') {
2809 // Note: for cURL connections, $this->outgoing_payload is ignored,
2810 // as is the Content-Length header, but these are still created as
2811 // debugging guides.
2812
2813 // add content-length header
2814 $this->setHeader('Content-Length', strlen($data));
2815
2816 // start building outgoing payload:
2817 if ($this->proxy) {
2818 $uri = $this->url;
2819 } else {
2820 $uri = $this->uri;
2821 }
2822 $req = "$this->request_method $uri HTTP/$this->protocol_version";
2823 $this->debug("HTTP request: $req");
2824 $this->outgoing_payload = "$req\r\n";
2825
2826 // loop thru headers, serializing
2827 foreach($this->outgoing_headers as $k => $v){
2828 $hdr = $k.': '.$v;
2829 $this->debug("HTTP header: $hdr");
2830 $this->outgoing_payload .= "$hdr\r\n";
2831 }
2832
2833 // add any cookies
2834 if ($cookie_str != '') {
2835 $hdr = 'Cookie: '.$cookie_str;
2836 $this->debug("HTTP header: $hdr");
2837 $this->outgoing_payload .= "$hdr\r\n";
2838 }
2839
2840 // header/body separator
2841 $this->outgoing_payload .= "\r\n";
2842
2843 // add data
2844 $this->outgoing_payload .= $data;
2845 }
2846
2855 function sendRequest($data, $cookies = NULL) {
2856 // build cookie string
2857 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
2858
2859 // build payload
2860 $this->buildPayload($data, $cookie_str);
2861
2862 if ($this->io_method() == 'socket') {
2863 // send payload
2864 if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2865 $this->setError('couldn\'t write message data to socket');
2866 $this->debug('couldn\'t write message data to socket');
2867 return false;
2868 }
2869 $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
2870 return true;
2871 } else if ($this->io_method() == 'curl') {
2872 // set payload
2873 // cURL does say this should only be the verb, and in fact it
2874 // turns out that the URI and HTTP version are appended to this, which
2875 // some servers refuse to work with (so we no longer use this method!)
2876 //$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
2877 $curl_headers = array();
2878 foreach($this->outgoing_headers as $k => $v){
2879 if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
2880 $this->debug("Skip cURL header $k: $v");
2881 } else {
2882 $curl_headers[] = "$k: $v";
2883 }
2884 }
2885 if ($cookie_str != '') {
2886 $curl_headers[] = 'Cookie: ' . $cookie_str;
2887 }
2888 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2889 $this->debug('set cURL HTTP headers');
2890 if ($this->request_method == "POST") {
2891 $this->setCurlOption(CURLOPT_POST, 1);
2892 $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
2893 $this->debug('set cURL POST data');
2894 } else {
2895 }
2896 // insert custom user-set cURL options
2897 foreach ($this->ch_options as $key => $val) {
2898 $this->setCurlOption($key, $val);
2899 }
2900
2901 $this->debug('set cURL payload');
2902 return true;
2903 }
2904 }
2905
2912 function getResponse(){
2913 $this->incoming_payload = '';
2914
2915 if ($this->io_method() == 'socket') {
2916 // loop until headers have been retrieved
2917 $data = '';
2918 while (!isset($lb)){
2919
2920 // We might EOF during header read.
2921 if(feof($this->fp)) {
2922 $this->incoming_payload = $data;
2923 $this->debug('found no headers before EOF after length ' . strlen($data));
2924 $this->debug("received before EOF:\n" . $data);
2925 $this->setError('server failed to send headers');
2926 return false;
2927 }
2928
2929 $tmp = fgets($this->fp, 256);
2930 $tmplen = strlen($tmp);
2931 $this->debug("read line of $tmplen bytes: " . trim($tmp));
2932
2933 if ($tmplen == 0) {
2934 $this->incoming_payload = $data;
2935 $this->debug('socket read of headers timed out after length ' . strlen($data));
2936 $this->debug("read before timeout: " . $data);
2937 $this->setError('socket read of headers timed out');
2938 return false;
2939 }
2940
2941 $data .= $tmp;
2942 $pos = strpos($data,"\r\n\r\n");
2943 if($pos > 1){
2944 $lb = "\r\n";
2945 } else {
2946 $pos = strpos($data,"\n\n");
2947 if($pos > 1){
2948 $lb = "\n";
2949 }
2950 }
2951 // remove 100 headers
2952 if (isset($lb) && preg_match('/^HTTP\/1.1 100/',$data)) {
2953 unset($lb);
2954 $data = '';
2955 }//
2956 }
2957 // store header data
2958 $this->incoming_payload .= $data;
2959 $this->debug('found end of headers after length ' . strlen($data));
2960 // process headers
2961 $header_data = trim(substr($data,0,$pos));
2962 $header_array = explode($lb,$header_data);
2963 $this->incoming_headers = array();
2964 $this->incoming_cookies = array();
2965 foreach($header_array as $header_line){
2966 $arr = explode(':',$header_line, 2);
2967 if(count($arr) > 1){
2968 $header_name = strtolower(trim($arr[0]));
2969 $this->incoming_headers[$header_name] = trim($arr[1]);
2970 if ($header_name == 'set-cookie') {
2971 // TODO: allow multiple cookies from parseCookie
2972 $cookie = $this->parseCookie(trim($arr[1]));
2973 if ($cookie) {
2974 $this->incoming_cookies[] = $cookie;
2975 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
2976 } else {
2977 $this->debug('did not find cookie in ' . trim($arr[1]));
2978 }
2979 }
2980 } else if (isset($header_name)) {
2981 // append continuation line to previous header
2982 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
2983 }
2984 }
2985
2986 // loop until msg has been received
2987 if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
2988 $content_length = 2147483647; // ignore any content-length header
2989 $chunked = true;
2990 $this->debug("want to read chunked content");
2991 } elseif (isset($this->incoming_headers['content-length'])) {
2992 $content_length = $this->incoming_headers['content-length'];
2993 $chunked = false;
2994 $this->debug("want to read content of length $content_length");
2995 } else {
2996 $content_length = 2147483647;
2997 $chunked = false;
2998 $this->debug("want to read content to EOF");
2999 }
3000 $data = '';
3001 do {
3002 if ($chunked) {
3003 $tmp = fgets($this->fp, 256);
3004 $tmplen = strlen($tmp);
3005 $this->debug("read chunk line of $tmplen bytes");
3006 if ($tmplen == 0) {
3007 $this->incoming_payload = $data;
3008 $this->debug('socket read of chunk length timed out after length ' . strlen($data));
3009 $this->debug("read before timeout:\n" . $data);
3010 $this->setError('socket read of chunk length timed out');
3011 return false;
3012 }
3013 $content_length = hexdec(trim($tmp));
3014 $this->debug("chunk length $content_length");
3015 }
3016 $strlen = 0;
3017 while (($strlen < $content_length) && (!feof($this->fp))) {
3018 $readlen = min(8192, $content_length - $strlen);
3019 $tmp = fread($this->fp, $readlen);
3020 $tmplen = strlen($tmp);
3021 $this->debug("read buffer of $tmplen bytes");
3022 if (($tmplen == 0) && (!feof($this->fp))) {
3023 $this->incoming_payload = $data;
3024 $this->debug('socket read of body timed out after length ' . strlen($data));
3025 $this->debug("read before timeout:\n" . $data);
3026 $this->setError('socket read of body timed out');
3027 return false;
3028 }
3029 $strlen += $tmplen;
3030 $data .= $tmp;
3031 }
3032 if ($chunked && ($content_length > 0)) {
3033 $tmp = fgets($this->fp, 256);
3034 $tmplen = strlen($tmp);
3035 $this->debug("read chunk terminator of $tmplen bytes");
3036 if ($tmplen == 0) {
3037 $this->incoming_payload = $data;
3038 $this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
3039 $this->debug("read before timeout:\n" . $data);
3040 $this->setError('socket read of chunk terminator timed out');
3041 return false;
3042 }
3043 }
3044 } while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3045 if (feof($this->fp)) {
3046 $this->debug('read to EOF');
3047 }
3048 $this->debug('read body of length ' . strlen($data));
3049 $this->incoming_payload .= $data;
3050 $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
3051
3052 // close filepointer
3053 if(
3054 (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') ||
3055 (! $this->persistentConnection) || feof($this->fp)){
3056 fclose($this->fp);
3057 $this->fp = false;
3058 $this->debug('closed socket');
3059 }
3060
3061 // connection was closed unexpectedly
3062 if($this->incoming_payload == ''){
3063 $this->setError('no response from server');
3064 return false;
3065 }
3066
3067 // decode transfer-encoding
3068// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
3069// if(!$data = $this->decodeChunked($data, $lb)){
3070// $this->setError('Decoding of chunked data failed');
3071// return false;
3072// }
3073 //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
3074 // set decoded payload
3075// $this->incoming_payload = $header_data.$lb.$lb.$data;
3076// }
3077
3078 } else if ($this->io_method() == 'curl') {
3079 // send and receive
3080 $this->debug('send and receive with cURL');
3081 $this->incoming_payload = curl_exec($this->ch);
3083
3084 $cErr = curl_error($this->ch);
3085 if ($cErr != '') {
3086 $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
3087 // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
3088 foreach(curl_getinfo($this->ch) as $k => $v){
3089 $err .= "$k: $v<br>";
3090 }
3091 $this->debug($err);
3092 $this->setError($err);
3093 curl_close($this->ch);
3094 return false;
3095 } else {
3096 //echo '<pre>';
3097 //var_dump(curl_getinfo($this->ch));
3098 //echo '</pre>';
3099 }
3100 // close curl
3101 $this->debug('No cURL error, closing cURL');
3102 curl_close($this->ch);
3103
3104 // try removing skippable headers
3105 $savedata = $data;
3106 while ($this->isSkippableCurlHeader($data)) {
3107 $this->debug("Found HTTP header to skip");
3108 if ($pos = strpos($data,"\r\n\r\n")) {
3109 $data = ltrim(substr($data,$pos));
3110 } elseif($pos = strpos($data,"\n\n") ) {
3111 $data = ltrim(substr($data,$pos));
3112 }
3113 }
3114
3115 if ($data == '') {
3116 // have nothing left; just remove 100 header(s)
3117 $data = $savedata;
3118 while (preg_match('/^HTTP\/1.1 100/',$data)) {
3119 if ($pos = strpos($data,"\r\n\r\n")) {
3120 $data = ltrim(substr($data,$pos));
3121 } elseif($pos = strpos($data,"\n\n") ) {
3122 $data = ltrim(substr($data,$pos));
3123 }
3124 }
3125 }
3126
3127 // separate content from HTTP headers
3128 if ($pos = strpos($data,"\r\n\r\n")) {
3129 $lb = "\r\n";
3130 } elseif( $pos = strpos($data,"\n\n")) {
3131 $lb = "\n";
3132 } else {
3133 $this->debug('no proper separation of headers and document');
3134 $this->setError('no proper separation of headers and document');
3135 return false;
3136 }
3137 $header_data = trim(substr($data,0,$pos));
3138 $header_array = explode($lb,$header_data);
3139 $data = ltrim(substr($data,$pos));
3140 $this->debug('found proper separation of headers and document');
3141 $this->debug('cleaned data, stringlen: '.strlen($data));
3142 // clean headers
3143 foreach ($header_array as $header_line) {
3144 $arr = explode(':',$header_line,2);
3145 if(count($arr) > 1){
3146 $header_name = strtolower(trim($arr[0]));
3147 $this->incoming_headers[$header_name] = trim($arr[1]);
3148 if ($header_name == 'set-cookie') {
3149 // TODO: allow multiple cookies from parseCookie
3150 $cookie = $this->parseCookie(trim($arr[1]));
3151 if ($cookie) {
3152 $this->incoming_cookies[] = $cookie;
3153 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3154 } else {
3155 $this->debug('did not find cookie in ' . trim($arr[1]));
3156 }
3157 }
3158 } else if (isset($header_name)) {
3159 // append continuation line to previous header
3160 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3161 }
3162 }
3163 }
3164
3165 $this->response_status_line = $header_array[0];
3166 $arr = explode(' ', $this->response_status_line, 3);
3167 $http_version = $arr[0];
3168 $http_status = intval($arr[1]);
3169 $http_reason = count($arr) > 2 ? $arr[2] : '';
3170
3171 // see if we need to resend the request with http digest authentication
3172 if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
3173 $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
3174 $this->setURL($this->incoming_headers['location']);
3175 $this->tryagain = true;
3176 return false;
3177 }
3178
3179 // see if we need to resend the request with http digest authentication
3180 if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
3181 $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
3182 if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
3183 $this->debug('Server wants digest authentication');
3184 // remove "Digest " from our elements
3185 $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
3186
3187 // parse elements into array
3188 $digestElements = explode(',', $digestString);
3189 foreach ($digestElements as $val) {
3190 $tempElement = explode('=', trim($val), 2);
3191 $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
3192 }
3193
3194 // should have (at least) qop, realm, nonce
3195 if (isset($digestRequest['nonce'])) {
3196 $this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
3197 $this->tryagain = true;
3198 return false;
3199 }
3200 }
3201 $this->debug('HTTP authentication failed');
3202 $this->setError('HTTP authentication failed');
3203 return false;
3204 }
3205
3206 if (
3207 ($http_status >= 300 && $http_status <= 307) ||
3208 ($http_status >= 400 && $http_status <= 417) ||
3209 ($http_status >= 501 && $http_status <= 505)
3210 ) {
3211 $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3212 return false;
3213 }
3214
3215 // decode content-encoding
3216 if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
3217 if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
3218 // if decoding works, use it. else assume data wasn't gzencoded
3219 if(function_exists('gzinflate')){
3220 //$timer->setMarker('starting decoding of gzip/deflated content');
3221 // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
3222 // this means there are no Zlib headers, although there should be
3223 $this->debug('The gzinflate function exists');
3224 $datalen = strlen($data);
3225 if ($this->incoming_headers['content-encoding'] == 'deflate') {
3226 if ($degzdata = @gzinflate($data)) {
3227 $data = $degzdata;
3228 $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
3229 if (strlen($data) < $datalen) {
3230 // test for the case that the payload has been compressed twice
3231 $this->debug('The inflated payload is smaller than the gzipped one; try again');
3232 if ($degzdata = @gzinflate($data)) {
3233 $data = $degzdata;
3234 $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
3235 }
3236 }
3237 } else {
3238 $this->debug('Error using gzinflate to inflate the payload');
3239 $this->setError('Error using gzinflate to inflate the payload');
3240 }
3241 } elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
3242 if ($degzdata = @gzinflate(substr($data, 10))) { // do our best
3243 $data = $degzdata;
3244 $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
3245 if (strlen($data) < $datalen) {
3246 // test for the case that the payload has been compressed twice
3247 $this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
3248 if ($degzdata = @gzinflate(substr($data, 10))) {
3249 $data = $degzdata;
3250 $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
3251 }
3252 }
3253 } else {
3254 $this->debug('Error using gzinflate to un-gzip the payload');
3255 $this->setError('Error using gzinflate to un-gzip the payload');
3256 }
3257 }
3258 //$timer->setMarker('finished decoding of gzip/deflated content');
3259 //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
3260 // set decoded payload
3261 $this->incoming_payload = $header_data.$lb.$lb.$data;
3262 } else {
3263 $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3264 $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3265 }
3266 } else {
3267 $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3268 $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3269 }
3270 } else {
3271 $this->debug('No Content-Encoding header');
3272 }
3273
3274 if(strlen($data) == 0){
3275 $this->debug('no data after headers!');
3276 $this->setError('no data present after HTTP headers');
3277 return false;
3278 }
3279
3280 return $data;
3281 }
3282
3290 function setContentType($type, $charset = false) {
3291 $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
3292 }
3293
3300 function usePersistentConnection(){
3301 if (isset($this->outgoing_headers['Accept-Encoding'])) {
3302 return false;
3303 }
3304 $this->protocol_version = '1.1';
3305 $this->persistentConnection = true;
3306 $this->setHeader('Connection', 'Keep-Alive');
3307 return true;
3308 }
3309
3317 /*
3318 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
3319 */
3320 function parseCookie($cookie_str) {
3321 $cookie_str = str_replace('; ', ';', $cookie_str) . ';';
3322 $data = split(';', $cookie_str);
3323 $value_str = $data[0];
3324
3325 $cookie_param = 'domain=';
3326 $start = strpos($cookie_str, $cookie_param);
3327 if ($start > 0) {
3328 $domain = substr($cookie_str, $start + strlen($cookie_param));
3329 $domain = substr($domain, 0, strpos($domain, ';'));
3330 } else {
3331 $domain = '';
3332 }
3333
3334 $cookie_param = 'expires=';
3335 $start = strpos($cookie_str, $cookie_param);
3336 if ($start > 0) {
3337 $expires = substr($cookie_str, $start + strlen($cookie_param));
3338 $expires = substr($expires, 0, strpos($expires, ';'));
3339 } else {
3340 $expires = '';
3341 }
3342
3343 $cookie_param = 'path=';
3344 $start = strpos($cookie_str, $cookie_param);
3345 if ( $start > 0 ) {
3346 $path = substr($cookie_str, $start + strlen($cookie_param));
3347 $path = substr($path, 0, strpos($path, ';'));
3348 } else {
3349 $path = '/';
3350 }
3351
3352 $cookie_param = ';secure;';
3353 if (strpos($cookie_str, $cookie_param) !== FALSE) {
3354 $secure = true;
3355 } else {
3356 $secure = false;
3357 }
3358
3359 $sep_pos = strpos($value_str, '=');
3360
3361 if ($sep_pos) {
3362 $name = substr($value_str, 0, $sep_pos);
3363 $value = substr($value_str, $sep_pos + 1);
3364 $cookie= array( 'name' => $name,
3365 'value' => $value,
3366 'domain' => $domain,
3367 'path' => $path,
3368 'expires' => $expires,
3369 'secure' => $secure
3370 );
3371 return $cookie;
3372 }
3373 return false;
3374 }
3375
3384 function getCookiesForRequest($cookies, $secure=false) {
3385 $cookie_str = '';
3386 if ((! is_null($cookies)) && (is_array($cookies))) {
3387 foreach ($cookies as $cookie) {
3388 if (! is_array($cookie)) {
3389 continue;
3390 }
3391 $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
3392 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
3393 if (strtotime($cookie['expires']) <= time()) {
3394 $this->debug('cookie has expired');
3395 continue;
3396 }
3397 }
3398 if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
3399 $domain = preg_quote($cookie['domain']);
3400 if (! preg_match("'.*$domain$'i", $this->host)) {
3401 $this->debug('cookie has different domain');
3402 continue;
3403 }
3404 }
3405 if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
3406 $path = preg_quote($cookie['path']);
3407 if (! preg_match("'^$path.*'i", $this->path)) {
3408 $this->debug('cookie is for a different path');
3409 continue;
3410 }
3411 }
3412 if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
3413 $this->debug('cookie is secure, transport is not');
3414 continue;
3415 }
3416 $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
3417 $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
3418 }
3419 }
3420 return $cookie_str;
3421 }
3422}
3423
3424?><?php
3425
3426
3427
3438class nusoap_server extends nusoap_base {
3444 var $headers = array();
3450 var $request = '';
3456 var $requestHeaders = '';
3462 var $requestHeader = NULL;
3468 var $document = '';
3474 var $requestSOAP = '';
3480 var $methodURI = '';
3486 var $methodname = '';
3492 var $methodparams = array();
3498 var $SOAPAction = '';
3504 var $xml_encoding = '';
3510 var $decode_utf8 = true;
3511
3517 var $outgoing_headers = array();
3523 var $response = '';
3529 var $responseHeaders = '';
3535 var $responseSOAP = '';
3541 var $methodreturn = false;
3547 var $methodreturnisliteralxml = false;
3553 var $fault = false;
3559 var $result = 'successful';
3560
3567 var $operations = array();
3573 var $wsdl = false;
3579 var $externalWSDLURL = false;
3585 var $debug_flag = false;
3586
3587
3595 function __construct($wsdl=false){
3597 // turn on debugging?
3598 global $debug;
3599 global $HTTP_SERVER_VARS;
3600
3601 if (isset($_SERVER)) {
3602 $this->debug("_SERVER is defined:");
3603 $this->appendDebug($this->varDump($_SERVER));
3604 } elseif (isset($HTTP_SERVER_VARS)) {
3605 $this->debug("HTTP_SERVER_VARS is defined:");
3606 $this->appendDebug($this->varDump($HTTP_SERVER_VARS));
3607 } else {
3608 $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3609 }
3610
3611 if (isset($debug)) {
3612 $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
3613 $this->debug_flag = $debug;
3614 } elseif (isset($_SERVER['QUERY_STRING'])) {
3615 $qs = explode('&', $_SERVER['QUERY_STRING']);
3616 foreach ($qs as $v) {
3617 if (substr($v, 0, 6) == 'debug=') {
3618 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
3619 $this->debug_flag = substr($v, 6);
3620 }
3621 }
3622 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3623 $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
3624 foreach ($qs as $v) {
3625 if (substr($v, 0, 6) == 'debug=') {
3626 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
3627 $this->debug_flag = substr($v, 6);
3628 }
3629 }
3630 }
3631
3632 // wsdl
3633 if($wsdl){
3634 $this->debug("In nusoap_server, WSDL is specified");
3635 if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
3636 $this->wsdl = $wsdl;
3637 $this->externalWSDLURL = $this->wsdl->wsdl;
3638 $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
3639 } else {
3640 $this->debug('Create wsdl from ' . $wsdl);
3641 $this->wsdl = new wsdl($wsdl);
3642 $this->externalWSDLURL = $wsdl;
3643 }
3644 $this->appendDebug($this->wsdl->getDebug());
3645 $this->wsdl->clearDebug();
3646 if($err = $this->wsdl->getError()){
3647 die('WSDL ERROR: '.$err);
3648 }
3649 }
3650 }
3651
3658 function service($data){
3659 global $HTTP_SERVER_VARS;
3660
3661 if (isset($_SERVER['QUERY_STRING'])) {
3662 $qs = $_SERVER['QUERY_STRING'];
3663 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3664 $qs = $HTTP_SERVER_VARS['QUERY_STRING'];
3665 } else {
3666 $qs = '';
3667 }
3668 $this->debug("In service, query string=$qs");
3669
3670 if (preg_match('/wsdl/', $qs) ){
3671 $this->debug("In service, this is a request for WSDL");
3672 if($this->externalWSDLURL){
3673 if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
3674 header('Location: '.$this->externalWSDLURL);
3675 } else { // assume file
3676 header("Content-Type: text/xml\r\n");
3677 $fp = fopen($this->externalWSDLURL, 'r');
3678 fpassthru($fp);
3679 }
3680 } elseif ($this->wsdl) {
3681 header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
3682 print $this->wsdl->serialize($this->debug_flag);
3683 if ($this->debug_flag) {
3684 $this->debug('wsdl:');
3685 $this->appendDebug($this->varDump($this->wsdl));
3686 print $this->getDebugAsXMLComment();
3687 }
3688 } else {
3689 header("Content-Type: text/html; charset=ISO-8859-1\r\n");
3690 print "This service does not provide WSDL";
3691 }
3692 } elseif ($data == '' && $this->wsdl) {
3693 $this->debug("In service, there is no data, so return Web description");
3694 print $this->wsdl->webDescription();
3695 } else {
3696 $this->debug("In service, invoke the request");
3697 $this->parse_request($data);
3698 if (! $this->fault) {
3699 $this->invoke_method();
3700 }
3701 if (! $this->fault) {
3702 $this->serialize_return();
3703 }
3704 $this->send_response();
3705 }
3706 }
3707
3720 function parse_http_headers() {
3721 global $HTTP_SERVER_VARS;
3722
3723 $this->request = '';
3724 $this->SOAPAction = '';
3725 if(function_exists('getallheaders')){
3726 $this->debug("In parse_http_headers, use getallheaders");
3727 $headers = getallheaders();
3728 foreach($headers as $k=>$v){
3729 $k = strtolower($k);
3730 $this->headers[$k] = $v;
3731 $this->request .= "$k: $v\r\n";
3732 $this->debug("$k: $v");
3733 }
3734 // get SOAPAction header
3735 if(isset($this->headers['soapaction'])){
3736 $this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
3737 }
3738 // get the character encoding of the incoming request
3739 if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
3740 $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
3741 if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
3742 $this->xml_encoding = strtoupper($enc);
3743 } else {
3744 $this->xml_encoding = 'US-ASCII';
3745 }
3746 } else {
3747 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3748 $this->xml_encoding = 'ISO-8859-1';
3749 }
3750 } elseif(isset($_SERVER) && is_array($_SERVER)){
3751 $this->debug("In parse_http_headers, use _SERVER");
3752 foreach ($_SERVER as $k => $v) {
3753 if (substr($k, 0, 5) == 'HTTP_') {
3754 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
3755 } else {
3756 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
3757 }
3758 if ($k == 'soapaction') {
3759 // get SOAPAction header
3760 $k = 'SOAPAction';
3761 $v = str_replace('"', '', $v);
3762 $v = str_replace('\\', '', $v);
3763 $this->SOAPAction = $v;
3764 } else if ($k == 'content-type') {
3765 // get the character encoding of the incoming request
3766 if (strpos($v, '=')) {
3767 $enc = substr(strstr($v, '='), 1);
3768 $enc = str_replace('"', '', $enc);
3769 $enc = str_replace('\\', '', $enc);
3770 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3771 $this->xml_encoding = strtoupper($enc);
3772 } else {
3773 $this->xml_encoding = 'US-ASCII';
3774 }
3775 } else {
3776 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3777 $this->xml_encoding = 'ISO-8859-1';
3778 }
3779 }
3780 $this->headers[$k] = $v;
3781 $this->request .= "$k: $v\r\n";
3782 $this->debug("$k: $v");
3783 }
3784 } elseif (is_array($HTTP_SERVER_VARS)) {
3785 $this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
3786 foreach ($HTTP_SERVER_VARS as $k => $v) {
3787 if (substr($k, 0, 5) == 'HTTP_') {
3788 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
3789 } else {
3790 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k);
3791 }
3792 if ($k == 'soapaction') {
3793 // get SOAPAction header
3794 $k = 'SOAPAction';
3795 $v = str_replace('"', '', $v);
3796 $v = str_replace('\\', '', $v);
3797 $this->SOAPAction = $v;
3798 } else if ($k == 'content-type') {
3799 // get the character encoding of the incoming request
3800 if (strpos($v, '=')) {
3801 $enc = substr(strstr($v, '='), 1);
3802 $enc = str_replace('"', '', $enc);
3803 $enc = str_replace('\\', '', $enc);
3804 if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3805 $this->xml_encoding = strtoupper($enc);
3806 } else {
3807 $this->xml_encoding = 'US-ASCII';
3808 }
3809 } else {
3810 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3811 $this->xml_encoding = 'ISO-8859-1';
3812 }
3813 }
3814 $this->headers[$k] = $v;
3815 $this->request .= "$k: $v\r\n";
3816 $this->debug("$k: $v");
3817 }
3818 } else {
3819 $this->debug("In parse_http_headers, HTTP headers not accessible");
3820 $this->setError("HTTP headers not accessible");
3821 }
3822 }
3823
3846 function parse_request($data='') {
3847 $this->debug('entering parse_request()');
3848 $this->parse_http_headers();
3849 $this->debug('got character encoding: '.$this->xml_encoding);
3850 // uncompress if necessary
3851 if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
3852 $this->debug('got content encoding: ' . $this->headers['content-encoding']);
3853 if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
3854 // if decoding works, use it. else assume data wasn't gzencoded
3855 if (function_exists('gzuncompress')) {
3856 if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
3857 $data = $degzdata;
3858 } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
3859 $data = $degzdata;
3860 } else {
3861 $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
3862 return;
3863 }
3864 } else {
3865 $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
3866 return;
3867 }
3868 }
3869 }
3870 $this->request .= "\r\n".$data;
3871 $data = $this->parseRequest($this->headers, $data);
3872 $this->requestSOAP = $data;
3873 $this->debug('leaving parse_request');
3874 }
3875
3893 function invoke_method() {
3894 $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
3895
3896 if ($this->wsdl) {
3897 if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
3898 $this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
3899 $this->appendDebug('opData=' . $this->varDump($this->opData));
3900 } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
3901 // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
3902 $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
3903 $this->appendDebug('opData=' . $this->varDump($this->opData));
3904 $this->methodname = $this->opData['name'];
3905 } else {
3906 $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
3907 $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
3908 return;
3909 }
3910 } else {
3911 $this->debug('in invoke_method, no WSDL to validate method');
3912 }
3913
3914 // if a . is present in $this->methodname, we see if there is a class in scope,
3915 // which could be referred to. We will also distinguish between two deliminators,
3916 // to allow methods to be called a the class or an instance
3917 $class = '';
3918 $method = '';
3919 if (strpos($this->methodname, '..') > 0) {
3920 $delim = '..';
3921 } else if (strpos($this->methodname, '.') > 0) {
3922 $delim = '.';
3923 } else {
3924 $delim = '';
3925 }
3926
3927 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3928 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3929 // get the class and method name
3930 $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3931 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3932 $this->debug("in invoke_method, class=$class method=$method delim=$delim");
3933 }
3934 // set class handler
3935 // added to support single operations
3936 if ($class == '' && $this->class !='')
3937 {
3938 $class = $this->class;
3939 $delim = "..";
3940 $method = $this->methodname;
3941 }
3942
3943 // does method exist?
3944 if ($class == '') {
3945 if (!function_exists($this->methodname)) {
3946 $this->debug("in invoke_method, function '$this->methodname' not found!");
3947 $this->result = 'fault: method not found';
3948 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
3949 return;
3950 }
3951 } else {
3952 $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
3953 if (!in_array($method_to_compare, get_class_methods($class))) {
3954 $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
3955 $this->result = 'fault: method not found';
3956 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
3957 return;
3958 }
3959 }
3960
3961 // evaluate message, getting back parameters
3962 // verify that request parameters match the method's signature
3963 if(! $this->verify_method($this->methodname,$this->methodparams)){
3964 // debug
3965 $this->debug('ERROR: request not verified against method signature');
3966 $this->result = 'fault: request failed validation against method signature';
3967 // return fault
3968 $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
3969 return;
3970 }
3971
3972 // if there are parameters to pass
3973 $this->debug('in invoke_method, params:');
3974 $this->appendDebug($this->varDump($this->methodparams));
3975 $this->debug("in invoke_method, calling '$this->methodname'");
3976 if (!function_exists('call_user_func_array')) {
3977 if ($class == '') {
3978 $this->debug('in invoke_method, calling function using eval()');
3979 $funcCall = "\$this->methodreturn = $this->methodname(";
3980 } else {
3981 if ($delim == '..') {
3982 $this->debug('in invoke_method, calling class method using eval()');
3983 $funcCall = "\$this->methodreturn = ".$class."::".$method."(";
3984 } else {
3985 $this->debug('in invoke_method, calling instance method using eval()');
3986 // generate unique instance name
3987 $instname = "\$inst_".time();
3988 $funcCall = $instname." = new ".$class."(); ";
3989 $funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
3990 }
3991 }
3992 if ($this->methodparams) {
3993 foreach ($this->methodparams as $param) {
3994 if (is_array($param) || is_object($param)) {
3995 $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
3996 return;
3997 }
3998 $funcCall .= "\"$param\",";
3999 }
4000 $funcCall = substr($funcCall, 0, -1);
4001 }
4002 $funcCall .= ');';
4003 $this->debug('in invoke_method, function call: '.$funcCall);
4004 @eval($funcCall);
4005 } else {
4006 if ($class == '') {
4007 $this->debug('in invoke_method, calling function using call_user_func_array()');
4008 $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array()
4009 } elseif ($delim == '..') {
4010 $this->debug('in invoke_method, calling class method using call_user_func_array()');
4011 $call_arg = array ($class, $method);
4012 } else {
4013 $this->debug('in invoke_method, calling instance method using call_user_func_array()');
4014 $instance = new $class ();
4015 $call_arg = array(&$instance, $method);
4016 }
4017 if (is_array($this->methodparams)) {
4018 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4019 } else {
4020 $this->methodreturn = call_user_func_array($call_arg, array());
4021 }
4022 }
4023 $this->debug('in invoke_method, methodreturn:');
4024 $this->appendDebug($this->varDump($this->methodreturn));
4025 $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
4026 }
4027
4039 function serialize_return() {
4040 $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
4041 // if fault
4042 if (isset($this->methodreturn) && ((get_class((object)$this->methodreturn) == 'soap_fault') || (get_class((object)$this->methodreturn) == 'nusoap_fault'))) {
4043 $this->debug('got a fault object from method');
4044 $this->fault = $this->methodreturn;
4045 return;
4046 } elseif ($this->methodreturnisliteralxml) {
4047 $return_val = $this->methodreturn;
4048 // returned value(s)
4049 } else {
4050 $this->debug('got a(n) '.gettype($this->methodreturn).' from method');
4051 $this->debug('serializing return value');
4052 if($this->wsdl){
4053 if (sizeof($this->opData['output']['parts']) > 1) {
4054 $this->debug('more than one output part, so use the method return unchanged');
4055 $opParams = $this->methodreturn;
4056 } elseif (sizeof($this->opData['output']['parts']) == 1) {
4057 $this->debug('exactly one output part, so wrap the method return in a simple array');
4058 // TODO: verify that it is not already wrapped!
4059 //foreach ($this->opData['output']['parts'] as $name => $type) {
4060 // $this->debug('wrap in element named ' . $name);
4061 //}
4062 $opParams = array($this->methodreturn);
4063 }
4064 $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
4065 $this->appendDebug($this->wsdl->getDebug());
4066 $this->wsdl->clearDebug();
4067 if($errstr = $this->wsdl->getError()){
4068 $this->debug('got wsdl error: '.$errstr);
4069 $this->fault('SOAP-ENV:Server', 'unable to serialize result');
4070 return;
4071 }
4072 } else {
4073 if (isset($this->methodreturn)) {
4074 $return_val = $this->serialize_val($this->methodreturn, 'return');
4075 } else {
4076 $return_val = '';
4077 $this->debug('in absence of WSDL, assume void return for backward compatibility');
4078 }
4079 }
4080 }
4081 $this->debug('return value:');
4082 $this->appendDebug($this->varDump($return_val));
4083
4084 $this->debug('serializing response');
4085 if ($this->wsdl) {
4086 $this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
4087 if ($this->opData['style'] == 'rpc') {
4088 $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
4089 if ($this->opData['output']['use'] == 'literal') {
4090 // 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
4091 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4092 } else {
4093 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4094 }
4095 } else {
4096 $this->debug('style is not rpc for serialization: assume document');
4097 $payload = $return_val;
4098 }
4099 } else {
4100 $this->debug('do not have WSDL for serialization: assume rpc/encoded');
4101 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4102 }
4103 $this->result = 'successful';
4104 if($this->wsdl){
4105 //if($this->debug_flag){
4106 $this->appendDebug($this->wsdl->getDebug());
4107 // }
4108 if (isset($opData['output']['encodingStyle'])) {
4109 $encodingStyle = $opData['output']['encodingStyle'];
4110 } else {
4111 $encodingStyle = '';
4112 }
4113 // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
4114 $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
4115 } else {
4116 $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
4117 }
4118 $this->debug("Leaving serialize_return");
4119 }
4120
4131 function send_response() {
4132 $this->debug('Enter send_response');
4133 if ($this->fault) {
4134 $payload = $this->fault->serialize();
4135 $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
4136 $this->outgoing_headers[] = "Status: 500 Internal Server Error";
4137 } else {
4138 $payload = $this->responseSOAP;
4139 // Some combinations of PHP+Web server allow the Status
4140 // to come through as a header. Since OK is the default
4141 // just do nothing.
4142 // $this->outgoing_headers[] = "HTTP/1.0 200 OK";
4143 // $this->outgoing_headers[] = "Status: 200 OK";
4144 }
4145 // add debug data if in debug mode
4146 if(isset($this->debug_flag) && $this->debug_flag){
4147 $payload .= $this->getDebugAsXMLComment();
4148 }
4149 $this->outgoing_headers[] = "Server: $this->title Server v$this->version";
4150 preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
4151 $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
4152 // Let the Web server decide about this
4153 //$this->outgoing_headers[] = "Connection: Close\r\n";
4154 $payload = $this->getHTTPBody($payload);
4155 $type = $this->getHTTPContentType();
4156 $charset = $this->getHTTPContentTypeCharset();
4157 $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
4158 //begin code to compress payload - by John
4159 // NOTE: there is no way to know whether the Web server will also compress
4160 // this data.
4161 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {
4162 if (strstr($this->headers['accept-encoding'], 'gzip')) {
4163 if (function_exists('gzencode')) {
4164 if (isset($this->debug_flag) && $this->debug_flag) {
4165 $payload .= "<!-- Content being gzipped -->";
4166 }
4167 $this->outgoing_headers[] = "Content-Encoding: gzip";
4168 $payload = gzencode($payload);
4169 } else {
4170 if (isset($this->debug_flag) && $this->debug_flag) {
4171 $payload .= "<!-- Content will not be gzipped: no gzencode -->";
4172 }
4173 }
4174 } elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
4175 // Note: MSIE requires gzdeflate output (no Zlib header and checksum),
4176 // instead of gzcompress output,
4177 // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
4178 if (function_exists('gzdeflate')) {
4179 if (isset($this->debug_flag) && $this->debug_flag) {
4180 $payload .= "<!-- Content being deflated -->";
4181 }
4182 $this->outgoing_headers[] = "Content-Encoding: deflate";
4183 $payload = gzdeflate($payload);
4184 } else {
4185 if (isset($this->debug_flag) && $this->debug_flag) {
4186 $payload .= "<!-- Content will not be deflated: no gzcompress -->";
4187 }
4188 }
4189 }
4190 }
4191 //end code
4192 $this->outgoing_headers[] = "Content-Length: ".strlen($payload);
4193 reset($this->outgoing_headers);
4194 foreach($this->outgoing_headers as $hdr){
4195 header($hdr, false);
4196 }
4197 print $payload;
4198 $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
4199 }
4200
4210 function verify_method($operation,$request){
4211 if(isset($this->wsdl) && is_object($this->wsdl)){
4212 if($this->wsdl->getOperationData($operation)){
4213 return true;
4214 }
4215 } elseif(isset($this->operations[$operation])){
4216 return true;
4217 }
4218 return false;
4219 }
4220
4229 function parseRequest($headers, $data) {
4230 $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
4231 if (!strstr($headers['content-type'], 'text/xml')) {
4232 $this->setError('Request not of type text/xml');
4233 return false;
4234 }
4235 if (strpos($headers['content-type'], '=')) {
4236 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
4237 $this->debug('Got response encoding: ' . $enc);
4238 if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
4239 $this->xml_encoding = strtoupper($enc);
4240 } else {
4241 $this->xml_encoding = 'US-ASCII';
4242 }
4243 } else {
4244 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
4245 $this->xml_encoding = 'ISO-8859-1';
4246 }
4247 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
4248 // parse response, get soap parser obj
4249 $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
4250 // parser debug
4251 $this->debug("parser debug: \n".$parser->getDebug());
4252 // if fault occurred during message parsing
4253 if($err = $parser->getError()){
4254 $this->result = 'fault: error in msg parsing: '.$err;
4255 $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
4256 // else successfully parsed request into soapval object
4257 } else {
4258 // get/set methodname
4259 $this->methodURI = $parser->root_struct_namespace;
4260 $this->methodname = $parser->root_struct_name;
4261 $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
4262 $this->debug('calling parser->get_soapbody()');
4263 $this->methodparams = $parser->get_soapbody();
4264 // get SOAP headers
4265 $this->requestHeaders = $parser->getHeaders();
4266 // get SOAP Header
4267 $this->requestHeader = $parser->get_soapheader();
4268 // add document for doclit support
4269 $this->document = $parser->document;
4270 }
4271 }
4272
4280 function getHTTPBody($soapmsg) {
4281 return $soapmsg;
4282 }
4283
4292 function getHTTPContentType() {
4293 return 'text/xml';
4294 }
4295
4305 function getHTTPContentTypeCharset() {
4307 }
4308
4318 function add_to_map($methodname,$in,$out){
4319 $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
4320 }
4321
4336 function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
4337 global $HTTP_SERVER_VARS;
4338
4339 if($this->externalWSDLURL){
4340 die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4341 }
4342 if (! $name) {
4343 die('You must specify a name when you register an operation');
4344 }
4345 if (!is_array($in)) {
4346 die('You must provide an array for operation inputs');
4347 }
4348 if (!is_array($out)) {
4349 die('You must provide an array for operation outputs');
4350 }
4351 if(false == $namespace) {
4352 }
4353 if(false == $soapaction) {
4354 if (isset($_SERVER)) {
4355 $SERVER_NAME = $_SERVER['SERVER_NAME'];
4356 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4357 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4358 } elseif (isset($HTTP_SERVER_VARS)) {
4359 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4360 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4361 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4362 } else {
4363 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4364 }
4365 if ($HTTPS == '1' || $HTTPS == 'on') {
4366 $SCHEME = 'https';
4367 } else {
4368 $SCHEME = 'http';
4369 }
4370 $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4371 }
4372 if(false == $style) {
4373 $style = "rpc";
4374 }
4375 if(false == $use) {
4376 $use = "encoded";
4377 }
4378 if ($use == 'encoded' && $encodingStyle = '') {
4379 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
4380 }
4381
4382 $this->operations[$name] = array(
4383 'name' => $name,
4384 'in' => $in,
4385 'out' => $out,
4386 'namespace' => $namespace,
4387 'soapaction' => $soapaction,
4388 'style' => $style);
4389 if($this->wsdl){
4390 $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
4391 }
4392 return true;
4393 }
4394
4405 function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
4406 if ($faultdetail == '' && $this->debug_flag) {
4407 $faultdetail = $this->getDebug();
4408 }
4409 $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
4410 $this->fault->soap_defencoding = $this->soap_defencoding;
4411 }
4412
4424 function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
4425 {
4426 global $HTTP_SERVER_VARS;
4427
4428 if (isset($_SERVER)) {
4429 $SERVER_NAME = $_SERVER['SERVER_NAME'];
4430 $SERVER_PORT = $_SERVER['SERVER_PORT'];
4431 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4432 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4433 } elseif (isset($HTTP_SERVER_VARS)) {
4434 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4435 $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
4436 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4437 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4438 } else {
4439 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4440 }
4441 // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
4442 $colon = strpos($SERVER_NAME,":");
4443 if ($colon) {
4444 $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4445 }
4446 if ($SERVER_PORT == 80) {
4447 $SERVER_PORT = '';
4448 } else {
4449 $SERVER_PORT = ':' . $SERVER_PORT;
4450 }
4451 if(false == $namespace) {
4452 $namespace = "http://$SERVER_NAME/soap/$serviceName";
4453 }
4454
4455 if(false == $endpoint) {
4456 if ($HTTPS == '1' || $HTTPS == 'on') {
4457 $SCHEME = 'https';
4458 } else {
4459 $SCHEME = 'http';
4460 }
4461 $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4462 }
4463
4464 if(false == $schemaTargetNamespace) {
4465 $schemaTargetNamespace = $namespace;
4466 }
4467
4468 $this->wsdl = new wsdl;
4469 $this->wsdl->serviceName = $serviceName;
4470 $this->wsdl->endpoint = $endpoint;
4471 $this->wsdl->namespaces['tns'] = $namespace;
4472 $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
4473 $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
4474 if ($schemaTargetNamespace != $namespace) {
4475 $this->wsdl->namespaces['types'] = $schemaTargetNamespace;
4476 }
4477 $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
4478 if ($style == 'document') {
4479 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
4480 }
4481 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4482 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
4483 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
4484 $this->wsdl->bindings[$serviceName.'Binding'] = array(
4485 'name'=>$serviceName.'Binding',
4486 'style'=>$style,
4487 'transport'=>$transport,
4488 'portType'=>$serviceName.'PortType');
4489 $this->wsdl->ports[$serviceName.'Port'] = array(
4490 'binding'=>$serviceName.'Binding',
4491 'location'=>$endpoint,
4492 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
4493 }
4494}
4495
4499class soap_server extends nusoap_server {
4500}
4501
4502?><?php
4503
4504
4505
4515class wsdl extends nusoap_base {
4516 // URL or filename of the root of this WSDL
4517 var $wsdl;
4518 // define internal arrays of bindings, ports, operations, messages, etc.
4519 var $schemas = array();
4520 var $currentSchema;
4521 var $message = array();
4522 var $complexTypes = array();
4523 var $messages = array();
4524 var $currentMessage;
4526 var $portTypes = array();
4527 var $currentPortType;
4528 var $bindings = array();
4529 var $currentBinding;
4530 var $ports = array();
4531 var $currentPort;
4532 var $opData = array();
4533 var $status = '';
4534 var $documentation = false;
4535 var $endpoint = '';
4536 // array of wsdl docs to import
4537 var $import = array();
4538 // parser vars
4539 var $parser;
4540 var $position = 0;
4541 var $depth = 0;
4542 var $depth_array = array();
4543 // for getting wsdl
4544 var $proxyhost = '';
4545 var $proxyport = '';
4546 var $proxyusername = '';
4547 var $proxypassword = '';
4548 var $timeout = 0;
4549 var $response_timeout = 30;
4550 var $curl_options = array(); // User-specified cURL options
4551 var $use_curl = false; // whether to always try to use cURL
4552 // for HTTP authentication
4553 var $username = ''; // Username for HTTP authentication
4554 var $password = ''; // Password for HTTP authentication
4555 var $authtype = ''; // Type of HTTP authentication
4556 var $certRequest = array(); // Certificate for HTTP SSL authentication
4557
4574 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4575 $this->proxyhost = $proxyhost;
4576 $this->proxyport = $proxyport;
4577 $this->proxyusername = $proxyusername;
4578 $this->proxypassword = $proxypassword;
4579 $this->timeout = $timeout;
4580 $this->response_timeout = $response_timeout;
4581 if (is_array($curl_options))
4582 $this->curl_options = $curl_options;
4583 $this->use_curl = $use_curl;
4584 $this->fetchWSDL($wsdl);
4585 }
4586
4592 function fetchWSDL($wsdl) {
4593 $this->debug("parse and process WSDL path=$wsdl");
4594 $this->wsdl = $wsdl;
4595 // parse wsdl file
4596 if ($this->wsdl != "") {
4597 $this->parseWSDL($this->wsdl);
4598 }
4599 // imports
4600 // TODO: handle imports more properly, grabbing them in-line and nesting them
4601 $imported_urls = array();
4602 $imported = 1;
4603 while ($imported > 0) {
4604 $imported = 0;
4605 // Schema imports
4606 foreach ($this->schemas as $ns => $list) {
4607 foreach ($list as $xs) {
4608 $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4609 foreach ($xs->imports as $ns2 => $list2) {
4610 for ($ii = 0; $ii < count($list2); $ii++) {
4611 if (! $list2[$ii]['loaded']) {
4612 $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
4613 $url = $list2[$ii]['location'];
4614 if ($url != '') {
4615 $urlparts = parse_url($url);
4616 if (!isset($urlparts['host'])) {
4617 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
4618 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4619 }
4620 if (! in_array($url, $imported_urls)) {
4621 $this->parseWSDL($url);
4622 $imported++;
4623 $imported_urls[] = $url;
4624 }
4625 } else {
4626 $this->debug("Unexpected scenario: empty URL for unloaded import");
4627 }
4628 }
4629 }
4630 }
4631 }
4632 }
4633 // WSDL imports
4634 $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4635 foreach ($this->import as $ns => $list) {
4636 for ($ii = 0; $ii < count($list); $ii++) {
4637 if (! $list[$ii]['loaded']) {
4638 $this->import[$ns][$ii]['loaded'] = true;
4639 $url = $list[$ii]['location'];
4640 if ($url != '') {
4641 $urlparts = parse_url($url);
4642 if (!isset($urlparts['host'])) {
4643 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
4644 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4645 }
4646 if (! in_array($url, $imported_urls)) {
4647 $this->parseWSDL($url);
4648 $imported++;
4649 $imported_urls[] = $url;
4650 }
4651 } else {
4652 $this->debug("Unexpected scenario: empty URL for unloaded import");
4653 }
4654 }
4655 }
4656 }
4657 }
4658 // add new data to operation data
4659 foreach($this->bindings as $binding => $bindingData) {
4660 if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
4661 foreach($bindingData['operations'] as $operation => $data) {
4662 $this->debug('post-parse data gathering for ' . $operation);
4663 $this->bindings[$binding]['operations'][$operation]['input'] =
4664 isset($this->bindings[$binding]['operations'][$operation]['input']) ?
4665 array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
4666 $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
4667 $this->bindings[$binding]['operations'][$operation]['output'] =
4668 isset($this->bindings[$binding]['operations'][$operation]['output']) ?
4669 array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
4670 $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
4671 if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
4672 $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
4673 }
4674 if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
4675 $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
4676 }
4677 // Set operation style if necessary, but do not override one already provided
4678 if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
4679 $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
4680 }
4681 $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
4682 $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
4683 $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
4684 }
4685 }
4686 }
4687 }
4688
4695 function parseWSDL($wsdl = '') {
4696 $this->debug("parse WSDL at path=$wsdl");
4697
4698 if ($wsdl == '') {
4699 $this->debug('no wsdl passed to parseWSDL()!!');
4700 $this->setError('no wsdl passed to parseWSDL()!!');
4701 return false;
4702 }
4703
4704 // parse $wsdl for url format
4705 $wsdl_props = parse_url($wsdl);
4706
4707 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
4708 $this->debug('getting WSDL http(s) URL ' . $wsdl);
4709 // get wsdl
4710 $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
4711 $tr->request_method = 'GET';
4712 $tr->useSOAPAction = false;
4713 if($this->proxyhost && $this->proxyport){
4714 $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
4715 }
4716 if ($this->authtype != '') {
4717 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4718 }
4719 $tr->setEncoding('gzip, deflate');
4720 $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
4721 //$this->debug("WSDL request\n" . $tr->outgoing_payload);
4722 //$this->debug("WSDL response\n" . $tr->incoming_payload);
4723 $this->appendDebug($tr->getDebug());
4724 // catch errors
4725 if($err = $tr->getError() ){
4726 $errstr = 'HTTP ERROR: '.$err;
4727 $this->debug($errstr);
4728 $this->setError($errstr);
4729 unset($tr);
4730 return false;
4731 }
4732 unset($tr);
4733 $this->debug("got WSDL URL");
4734 } else {
4735 // $wsdl is not http(s), so treat it as a file URL or plain file path
4736 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
4737 $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
4738 } else {
4739 $path = $wsdl;
4740 }
4741 $this->debug('getting WSDL file ' . $path);
4742 if ($fp = @fopen($path, 'r')) {
4743 $wsdl_string = '';
4744 while ($data = fread($fp, 32768)) {
4745 $wsdl_string .= $data;
4746 }
4747 fclose($fp);
4748 } else {
4749 $errstr = "Bad path to WSDL file $path";
4750 $this->debug($errstr);
4751 $this->setError($errstr);
4752 return false;
4753 }
4754 }
4755 $this->debug('Parse WSDL');
4756 // end new code added
4757 // Create an XML parser.
4758 $this->parser = xml_parser_create();
4759 // Set the options for parsing the XML data.
4760 // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
4761 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4762 // Set the object for the parser.
4763 xml_set_object($this->parser, $this);
4764 // Set the element handlers for the parser.
4765 xml_set_element_handler($this->parser, 'start_element', 'end_element');
4766 xml_set_character_data_handler($this->parser, 'character_data');
4767 // Parse the XML file.
4768 if (!xml_parse($this->parser, $wsdl_string, true)) {
4769 // Display an error message.
4770 $errstr = sprintf(
4771 'XML error parsing WSDL from %s on line %d: %s',
4772 $wsdl,
4773 xml_get_current_line_number($this->parser),
4774 xml_error_string(xml_get_error_code($this->parser))
4775 );
4776 $this->debug($errstr);
4777 $this->debug("XML payload:\n" . $wsdl_string);
4778 $this->setError($errstr);
4779 return false;
4780 }
4781 // free the parser
4782 xml_parser_free($this->parser);
4783 $this->debug('Parsing WSDL done');
4784 // catch wsdl parse errors
4785 if($this->getError()){
4786 return false;
4787 }
4788 return true;
4789 }
4790
4799 function start_element($parser, $name, $attrs)
4800 {
4801 if ($this->status == 'schema') {
4802 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4803 $this->appendDebug($this->currentSchema->getDebug());
4804 $this->currentSchema->clearDebug();
4805 } elseif (preg_match('/schema$/', $name)) {
4806 $this->debug('Parsing WSDL schema');
4807 // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
4808 $this->status = 'schema';
4809 $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
4810 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4811 $this->appendDebug($this->currentSchema->getDebug());
4812 $this->currentSchema->clearDebug();
4813 } else {
4814 // position in the total number of elements, starting from 0
4815 $pos = $this->position++;
4816 $depth = $this->depth++;
4817 // set self as current value for this depth
4818 $this->depth_array[$depth] = $pos;
4819 $this->message[$pos] = array('cdata' => '');
4820 // process attributes
4821 if (count($attrs) > 0) {
4822 // register namespace declarations
4823 foreach($attrs as $k => $v) {
4824 if (preg_match('/^xmlns/',$k)) {
4825 if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
4826 $this->namespaces[$ns_prefix] = $v;
4827 } else {
4828 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
4829 }
4830 if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
4831 $this->XMLSchemaVersion = $v;
4832 $this->namespaces['xsi'] = $v . '-instance';
4833 }
4834 }
4835 }
4836 // expand each attribute prefix to its namespace
4837 foreach($attrs as $k => $v) {
4838 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
4839 if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
4840 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
4841 }
4842 $eAttrs[$k] = $v;
4843 }
4844 $attrs = $eAttrs;
4845 } else {
4846 $attrs = array();
4847 }
4848 // get element prefix, namespace and name
4849 if (preg_match('/:/', $name)) {
4850 // get ns prefix
4851 $prefix = substr($name, 0, strpos($name, ':'));
4852 // get ns
4853 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : '';
4854 // get unqualified name
4855 $name = substr(strstr($name, ':'), 1);
4856 }
4857 // process attributes, expanding any prefixes to namespaces
4858 // find status, register data
4859 switch ($this->status) {
4860 case 'message':
4861 if ($name == 'part') {
4862 if (isset($attrs['type'])) {
4863 $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
4864 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
4865 }
4866 if (isset($attrs['element'])) {
4867 $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
4868 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
4869 }
4870 }
4871 break;
4872 case 'portType':
4873 switch ($name) {
4874 case 'operation':
4875 $this->currentPortOperation = $attrs['name'];
4876 $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
4877 if (isset($attrs['parameterOrder'])) {
4878 $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
4879 }
4880 break;
4881 case 'documentation':
4882 $this->documentation = true;
4883 break;
4884 // merge input/output data
4885 default:
4886 $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
4887 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
4888 break;
4889 }
4890 break;
4891 case 'binding':
4892 switch ($name) {
4893 case 'binding':
4894 // get ns prefix
4895 if (isset($attrs['style'])) {
4896 $this->bindings[$this->currentBinding]['prefix'] = $prefix;
4897 }
4898 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4899 break;
4900 case 'header':
4901 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
4902 break;
4903 case 'operation':
4904 if (isset($attrs['soapAction'])) {
4905 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
4906 }
4907 if (isset($attrs['style'])) {
4908 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
4909 }
4910 if (isset($attrs['name'])) {
4911 $this->currentOperation = $attrs['name'];
4912 $this->debug("current binding operation: $this->currentOperation");
4913 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
4914 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
4915 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
4916 }
4917 break;
4918 case 'input':
4919 $this->opStatus = 'input';
4920 break;
4921 case 'output':
4922 $this->opStatus = 'output';
4923 break;
4924 case 'body':
4925 if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
4926 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
4927 } else {
4928 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
4929 }
4930 break;
4931 }
4932 break;
4933 case 'service':
4934 switch ($name) {
4935 case 'port':
4936 $this->currentPort = $attrs['name'];
4937 $this->debug('current port: ' . $this->currentPort);
4938 $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
4939
4940 break;
4941 case 'address':
4942 $this->ports[$this->currentPort]['location'] = $attrs['location'];
4943 $this->ports[$this->currentPort]['bindingType'] = $namespace;
4944 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
4945 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
4946 break;
4947 }
4948 break;
4949 }
4950 // set status
4951 switch ($name) {
4952 case 'import':
4953 if (isset($attrs['location'])) {
4954 $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
4955 $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
4956 } else {
4957 $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
4958 if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
4959 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
4960 }
4961 $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
4962 }
4963 break;
4964 //wait for schema
4965 //case 'types':
4966 // $this->status = 'schema';
4967 // break;
4968 case 'message':
4969 $this->status = 'message';
4970 $this->messages[$attrs['name']] = array();
4971 $this->currentMessage = $attrs['name'];
4972 break;
4973 case 'portType':
4974 $this->status = 'portType';
4975 $this->portTypes[$attrs['name']] = array();
4976 $this->currentPortType = $attrs['name'];
4977 break;
4978 case "binding":
4979 if (isset($attrs['name'])) {
4980 // get binding name
4981 if (strpos($attrs['name'], ':')) {
4982 $this->currentBinding = $this->getLocalPart($attrs['name']);
4983 } else {
4984 $this->currentBinding = $attrs['name'];
4985 }
4986 $this->status = 'binding';
4987 $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
4988 $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
4989 }
4990 break;
4991 case 'service':
4992 $this->serviceName = $attrs['name'];
4993 $this->status = 'service';
4994 $this->debug('current service: ' . $this->serviceName);
4995 break;
4996 case 'definitions':
4997 foreach ($attrs as $name => $value) {
4998 $this->wsdl_info[$name] = $value;
4999 }
5000 break;
5001 }
5002 }
5003 }
5004
5012 function end_element($parser, $name){
5013 // unset schema status
5014 if (/*preg_match('/types$/', $name) ||*/ preg_match('/schema$/', $name)) {
5015 $this->status = "";
5016 $this->appendDebug($this->currentSchema->getDebug());
5017 $this->currentSchema->clearDebug();
5018 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5019 $this->debug('Parsing WSDL schema done');
5020 }
5021 if ($this->status == 'schema') {
5022 $this->currentSchema->schemaEndElement($parser, $name);
5023 } else {
5024 // bring depth down a notch
5025 $this->depth--;
5026 }
5027 // end documentation
5028 if ($this->documentation) {
5029 //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
5030 //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
5031 $this->documentation = false;
5032 }
5033 }
5034
5042 function character_data($parser, $data)
5043 {
5044 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5045 if (isset($this->message[$pos]['cdata'])) {
5046 $this->message[$pos]['cdata'] .= $data;
5047 }
5048 if ($this->documentation) {
5049 $this->documentation .= $data;
5050 }
5051 }
5052
5062 function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
5063 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
5064 $this->appendDebug($this->varDump($certRequest));
5065 $this->username = $username;
5066 $this->password = $password;
5067 $this->authtype = $authtype;
5068 $this->certRequest = $certRequest;
5069 }
5070
5071 function getBindingData($binding)
5072 {
5073 if (is_array($this->bindings[$binding])) {
5074 return $this->bindings[$binding];
5075 }
5076 }
5077
5085 function getOperations($bindingType = 'soap') {
5086 $ops = array();
5087 if ($bindingType == 'soap') {
5088 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5089 } elseif ($bindingType == 'soap12') {
5090 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5091 }
5092 // loop thru ports
5093 foreach($this->ports as $port => $portData) {
5094 // binding type of port matches parameter
5095 if ($portData['bindingType'] == $bindingType) {
5096 //$this->debug("getOperations for port $port");
5097 //$this->debug("port data: " . $this->varDump($portData));
5098 //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
5099 // merge bindings
5100 if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
5101 $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
5102 }
5103 }
5104 }
5105 return $ops;
5106 }
5107
5116 function getOperationData($operation, $bindingType = 'soap')
5117 {
5118 if ($bindingType == 'soap') {
5119 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5120 } elseif ($bindingType == 'soap12') {
5121 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5122 }
5123 // loop thru ports
5124 foreach($this->ports as $port => $portData) {
5125 // binding type of port matches parameter
5126 if ($portData['bindingType'] == $bindingType) {
5127 // get binding
5128 //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5129 foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
5130 // note that we could/should also check the namespace here
5131 if ($operation == $bOperation) {
5132 $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
5133 return $opData;
5134 }
5135 }
5136 }
5137 }
5138 }
5139
5148 function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
5149 if ($bindingType == 'soap') {
5150 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5151 } elseif ($bindingType == 'soap12') {
5152 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5153 }
5154 // loop thru ports
5155 foreach($this->ports as $port => $portData) {
5156 // binding type of port matches parameter
5157 if ($portData['bindingType'] == $bindingType) {
5158 // loop through operations for the binding
5159 foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5160 if ($opData['soapAction'] == $soapAction) {
5161 return $opData;
5162 }
5163 }
5164 }
5165 }
5166 }
5167
5186 function getTypeDef($type, $ns) {
5187 $this->debug("in getTypeDef: type=$type, ns=$ns");
5188 if ((! $ns) && isset($this->namespaces['tns'])) {
5189 $ns = $this->namespaces['tns'];
5190 $this->debug("in getTypeDef: type namespace forced to $ns");
5191 }
5192 if (!isset($this->schemas[$ns])) {
5193 foreach ($this->schemas as $ns0 => $schema0) {
5194 if (strcasecmp($ns, $ns0) == 0) {
5195 $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
5196 $ns = $ns0;
5197 break;
5198 }
5199 }
5200 }
5201 if (isset($this->schemas[$ns])) {
5202 $this->debug("in getTypeDef: have schema for namespace $ns");
5203 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5204 $xs = &$this->schemas[$ns][$i];
5205 $t = $xs->getTypeDef($type);
5206 //$this->appendDebug($xs->getDebug());
5207 //$xs->clearDebug();
5208 if ($t) {
5209 if (!isset($t['phpType'])) {
5210 // get info for type to tack onto the element
5211 $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
5212 $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
5213 $etype = $this->getTypeDef($uqType, $ns);
5214 if ($etype) {
5215 $this->debug("found type for [element] $type:");
5216 $this->debug($this->varDump($etype));
5217 if (isset($etype['phpType'])) {
5218 $t['phpType'] = $etype['phpType'];
5219 }
5220 if (isset($etype['elements'])) {
5221 $t['elements'] = $etype['elements'];
5222 }
5223 if (isset($etype['attrs'])) {
5224 $t['attrs'] = $etype['attrs'];
5225 }
5226 }
5227 }
5228 return $t;
5229 }
5230 }
5231 } else {
5232 $this->debug("in getTypeDef: do not have schema for namespace $ns");
5233 }
5234 return false;
5235 }
5236
5242 function webDescription(){
5243 global $HTTP_SERVER_VARS;
5244
5245 if (isset($_SERVER)) {
5246 $PHP_SELF = $_SERVER['PHP_SELF'];
5247 } elseif (isset($HTTP_SERVER_VARS)) {
5248 $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
5249 } else {
5250 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
5251 }
5252 // begin-patch: https://mantis.ilias.de/view.php?id=28866
5253 $PHP_SELF = filter_var($PHP_SELF, FILTER_SANITIZE_STRING);
5254 // end-patch
5255
5256 $b = '
5257 <html><head><title>NuSOAP: '.$this->serviceName.'</title>
5258 <style type="text/css">
5259 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
5260 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
5261 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
5262 ul { margin-top: 10px; margin-left: 20px; }
5263 li { list-style-type: none; margin-top: 10px; color: #000000; }
5264 .content{
5265 margin-left: 0px; padding-bottom: 2em; }
5266 .nav {
5267 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
5268 margin-top: 10px; margin-left: 0px; color: #000000;
5269 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
5270 .title {
5271 font-family: arial; font-size: 26px; color: #ffffff;
5272 background-color: #999999; width: 105%; margin-left: 0px;
5273 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
5274 .hidden {
5275 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
5276 font-family: arial; overflow: hidden; width: 600;
5277 padding: 20px; font-size: 10px; background-color: #999999;
5278 layer-background-color:#FFFFFF; }
5279 a,a:active { color: charcoal; font-weight: bold; }
5280 a:visited { color: #666666; font-weight: bold; }
5281 a:hover { color: cc3300; font-weight: bold; }
5282 </style>
5283 <script language="JavaScript" type="text/javascript">
5284 <!--
5285 // POP-UP CAPTIONS...
5286 function lib_bwcheck(){ //Browsercheck (needed)
5287 this.ver=navigator.appVersion
5288 this.agent=navigator.userAgent
5289 this.dom=document.getElementById?1:0
5290 this.opera5=this.agent.indexOf("Opera 5")>-1
5291 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
5292 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
5293 this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
5294 this.ie=this.ie4||this.ie5||this.ie6
5295 this.mac=this.agent.indexOf("Mac")>-1
5296 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
5297 this.ns4=(document.layers && !this.dom)?1:0;
5298 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
5299 return this
5300 }
5301 var bw = new lib_bwcheck()
5302 //Makes crossbrowser object.
5303 function makeObj(obj){
5304 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
5305 if(!this.evnt) return false
5306 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
5307 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
5308 this.writeIt=b_writeIt;
5309 return this
5310 }
5311 // A unit of measure that will be added when setting the position of a layer.
5312 //var px = bw.ns4||window.opera?"":"px";
5313 function b_writeIt(text){
5314 if (bw.ns4){this.wref.write(text);this.wref.close()}
5315 else this.wref.innerHTML = text
5316 }
5317 //Shows the messages
5318 var oDesc;
5319 function popup(divid){
5320 if(oDesc = new makeObj(divid)){
5321 oDesc.css.visibility = "visible"
5322 }
5323 }
5324 function popout(){ // Hides message
5325 if(oDesc) oDesc.css.visibility = "hidden"
5326 }
5327 //-->
5328 </script>
5329 </head>
5330 <body>
5331 <div class=content>
5332 <br><br>
5333 <div class=title>'.$this->serviceName.'</div>
5334 <div class=nav>
5335 <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
5336 Click on an operation name to view it&apos;s details.</p>
5337 <ul>';
5338 foreach($this->getOperations() as $op => $data){
5339 // begin-patch: https://mantis.ilias.de/view.php?id=28866
5340 if (isset($data['endpoint'])) {
5341 $data['endpoint'] = filter_var($data['endpoint'], FILTER_SANITIZE_STRING);
5342 }
5343 // end-patch
5344 $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5345 // create hidden div
5346 $b .= "<div id='$op' class='hidden'>
5347 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5348 foreach($data as $donnie => $marie){ // loop through opdata
5349 if($donnie == 'input' || $donnie == 'output'){ // show input/output data
5350 $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
5351 foreach($marie as $captain => $tenille){ // loop through data
5352 if($captain == 'parts'){ // loop thru parts
5353 $b .= "&nbsp;&nbsp;$captain:<br>";
5354 //if(is_array($tenille)){
5355 foreach($tenille as $joanie => $chachi){
5356 $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
5357 }
5358 //}
5359 } else {
5360 $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
5361 }
5362 }
5363 } else {
5364 $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
5365 }
5366 }
5367 $b .= '</div>';
5368 }
5369 $b .= '
5370 <ul>
5371 </div>
5372 </div></body></html>';
5373 return $b;
5374 }
5375
5383 function serialize($debug = 0)
5384 {
5385 $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
5386 $xml .= "\n<definitions";
5387 foreach($this->namespaces as $k => $v) {
5388 $xml .= " xmlns:$k=\"$v\"";
5389 }
5390 // 10.9.02 - add poulter fix for wsdl and tns declarations
5391 if (isset($this->namespaces['wsdl'])) {
5392 $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
5393 }
5394 if (isset($this->namespaces['tns'])) {
5395 $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
5396 }
5397 $xml .= '>';
5398 // imports
5399 if (sizeof($this->import) > 0) {
5400 foreach($this->import as $ns => $list) {
5401 foreach ($list as $ii) {
5402 if ($ii['location'] != '') {
5403 $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
5404 } else {
5405 $xml .= '<import namespace="' . $ns . '" />';
5406 }
5407 }
5408 }
5409 }
5410 // types
5411 if (count($this->schemas)>=1) {
5412 $xml .= "\n<types>\n";
5413 foreach ($this->schemas as $ns => $list) {
5414 foreach ($list as $xs) {
5415 $xml .= $xs->serializeSchema();
5416 }
5417 }
5418 $xml .= '</types>';
5419 }
5420 // messages
5421 if (count($this->messages) >= 1) {
5422 foreach($this->messages as $msgName => $msgParts) {
5423 $xml .= "\n<message name=\"" . $msgName . '">';
5424 if(is_array($msgParts)){
5425 foreach($msgParts as $partName => $partType) {
5426 // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
5427 if (strpos($partType, ':')) {
5428 $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
5429 } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
5430 // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
5431 $typePrefix = 'xsd';
5432 } else {
5433 foreach($this->typemap as $ns => $types) {
5434 if (isset($types[$partType])) {
5435 $typePrefix = $this->getPrefixFromNamespace($ns);
5436 }
5437 }
5438 if (!isset($typePrefix)) {
5439 die("$partType has no namespace!");
5440 }
5441 }
5442 $ns = $this->getNamespaceFromPrefix($typePrefix);
5443 $localPart = $this->getLocalPart($partType);
5444 $typeDef = $this->getTypeDef($localPart, $ns);
5445 if ($typeDef['typeClass'] == 'element') {
5446 $elementortype = 'element';
5447 if (substr($localPart, -1) == '^') {
5448 $localPart = substr($localPart, 0, -1);
5449 }
5450 } else {
5451 $elementortype = 'type';
5452 }
5453 $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
5454 }
5455 }
5456 $xml .= '</message>';
5457 }
5458 }
5459 // bindings & porttypes
5460 if (count($this->bindings) >= 1) {
5461 $binding_xml = '';
5462 $portType_xml = '';
5463 foreach($this->bindings as $bindingName => $attrs) {
5464 $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
5465 $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
5466 $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
5467 foreach($attrs['operations'] as $opName => $opParts) {
5468 $binding_xml .= "\n" . ' <operation name="' . $opName . '">';
5469 $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
5470 if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
5471 $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
5472 } else {
5473 $enc_style = '';
5474 }
5475 $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
5476 if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
5477 $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
5478 } else {
5479 $enc_style = '';
5480 }
5481 $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
5482 $binding_xml .= "\n" . ' </operation>';
5483 $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"';
5484 if (isset($opParts['parameterOrder'])) {
5485 $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
5486 }
5487 $portType_xml .= '>';
5488 if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
5489 $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
5490 }
5491 $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>';
5492 $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>';
5493 $portType_xml .= "\n" . ' </operation>';
5494 }
5495 $portType_xml .= "\n" . '</portType>';
5496 $binding_xml .= "\n" . '</binding>';
5497 }
5498 $xml .= $portType_xml . $binding_xml;
5499 }
5500 // services
5501 $xml .= "\n<service name=\"" . $this->serviceName . '">';
5502 $has_client = isset($_GET['client_id']);
5503 if (count($this->ports) >= 1) {
5504 foreach($this->ports as $pName => $attrs) {
5505 $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
5506 $address = $attrs['location'] . ($debug || $has_client ? "?" : "")
5507 . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&amp;" : "")
5508 . ($has_client ? 'client_id=' . $_GET['client_id'] : '');
5509 $xml .= "\n" . ' <soap:address location="' . $address. '"/>';
5510 $xml .= "\n" . ' </port>';
5511 }
5512 }
5513
5514 $xml .= "\n" . '</service>';
5515 return $xml . "\n</definitions>";
5516 }
5517
5527 function parametersMatchWrapped($type, &$parameters) {
5528 $this->debug("in parametersMatchWrapped type=$type, parameters=");
5529 $this->appendDebug($this->varDump($parameters));
5530
5531 // split type into namespace:unqualified-type
5532 if (strpos($type, ':')) {
5533 $uqType = substr($type, strrpos($type, ':') + 1);
5534 $ns = substr($type, 0, strrpos($type, ':'));
5535 $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5536 if ($this->getNamespaceFromPrefix($ns)) {
5537 $ns = $this->getNamespaceFromPrefix($ns);
5538 $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5539 }
5540 } else {
5541 // TODO: should the type be compared to types in XSD, and the namespace
5542 // set to XSD if the type matches?
5543 $this->debug("in parametersMatchWrapped: No namespace for type $type");
5544 $ns = '';
5545 $uqType = $type;
5546 }
5547
5548 // get the type information
5549 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5550 $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5551 return false;
5552 }
5553 $this->debug("in parametersMatchWrapped: found typeDef=");
5554 $this->appendDebug($this->varDump($typeDef));
5555 if (substr($uqType, -1) == '^') {
5556 $uqType = substr($uqType, 0, -1);
5557 }
5558 $phpType = $typeDef['phpType'];
5559 $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
5560 $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5561
5562 // we expect a complexType or element of complexType
5563 if ($phpType != 'struct') {
5564 $this->debug("in parametersMatchWrapped: not a struct");
5565 return false;
5566 }
5567
5568 // see whether the parameter names match the elements
5569 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
5570 $elements = 0;
5571 $matches = 0;
5572 $change = false;
5573 if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
5574 $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5575 $change = true;
5576 }
5577 foreach ($typeDef['elements'] as $name => $attrs) {
5578 if ($change) {
5579 $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
5580 $parameters[$name] = $parameters[$elements];
5581 unset($parameters[$elements]);
5582 $matches++;
5583 } elseif (isset($parameters[$name])) {
5584 $this->debug("in parametersMatchWrapped: have parameter named $name");
5585 $matches++;
5586 } else {
5587 $this->debug("in parametersMatchWrapped: do not have parameter named $name");
5588 }
5589 $elements++;
5590 }
5591
5592 $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5593 if ($matches == 0) {
5594 return false;
5595 }
5596 return true;
5597 }
5598
5599 // since there are no elements for the type, if the user passed no
5600 // parameters, the parameters match wrapped.
5601 $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
5602 return count($parameters) == 0;
5603 }
5604
5620 function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
5621 $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5622 $this->appendDebug('parameters=' . $this->varDump($parameters));
5623
5624 if ($direction != 'input' && $direction != 'output') {
5625 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5626 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5627 return false;
5628 }
5629 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5630 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5631 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5632 return false;
5633 }
5634 $this->debug('in serializeRPCParameters: opData:');
5635 $this->appendDebug($this->varDump($opData));
5636
5637 // Get encoding style for output and set to current
5638 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5639 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5640 $encodingStyle = $opData['output']['encodingStyle'];
5641 $enc_style = $encodingStyle;
5642 }
5643
5644 // set input params
5645 $xml = '';
5646 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5647 $parts = &$opData[$direction]['parts'];
5648 $part_count = sizeof($parts);
5649 $style = $opData['style'];
5650 $use = $opData[$direction]['use'];
5651 $this->debug("have $part_count part(s) to serialize using $style/$use");
5652 if (is_array($parameters)) {
5653 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5654 $parameter_count = count($parameters);
5655 $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5656 // check for Microsoft-style wrapped parameters
5657 if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
5658 $this->debug('check whether the caller has wrapped the parameters');
5659 if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
5660 $this->debug('check whether caller\'s parameters match the wrapped ones');
5661 if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
5662 $this->debug('wrap the parameters for the caller');
5663 $parameters = array('parameters' => $parameters);
5664 $parameter_count = 1;
5665 }
5666 }
5667 }
5668 foreach ($parts as $name => $type) {
5669 $this->debug("serializing part $name of type $type");
5670 // Track encoding style
5671 if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5672 $encodingStyle = $opData[$direction]['encodingStyle'];
5673 $enc_style = $encodingStyle;
5674 } else {
5675 $enc_style = false;
5676 }
5677 // NOTE: add error handling here
5678 // if serializeType returns false, then catch global error and fault
5679 if ($parametersArrayType == 'arraySimple') {
5680 $p = array_shift($parameters);
5681 $this->debug('calling serializeType w/indexed param');
5682 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5683 } elseif (isset($parameters[$name])) {
5684 $this->debug('calling serializeType w/named param');
5685 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5686 } else {
5687 // TODO: only send nillable
5688 $this->debug('calling serializeType w/null param');
5689 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5690 }
5691 }
5692 } else {
5693 $this->debug('no parameters passed.');
5694 }
5695 }
5696 $this->debug("serializeRPCParameters returning: $xml");
5697 return $xml;
5698 }
5699
5714 function serializeParameters($operation, $direction, $parameters)
5715 {
5716 $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5717 $this->appendDebug('parameters=' . $this->varDump($parameters));
5718
5719 if ($direction != 'input' && $direction != 'output') {
5720 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5721 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5722 return false;
5723 }
5724 if (!$opData = $this->getOperationData($operation)) {
5725 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
5726 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
5727 return false;
5728 }
5729 $this->debug('opData:');
5730 $this->appendDebug($this->varDump($opData));
5731
5732 // Get encoding style for output and set to current
5733 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5734 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5735 $encodingStyle = $opData['output']['encodingStyle'];
5736 $enc_style = $encodingStyle;
5737 }
5738
5739 // set input params
5740 $xml = '';
5741 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5742
5743 $use = $opData[$direction]['use'];
5744 $this->debug("use=$use");
5745 $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
5746 if (is_array($parameters)) {
5747 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5748 $this->debug('have ' . $parametersArrayType . ' parameters');
5749 foreach($opData[$direction]['parts'] as $name => $type) {
5750 $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
5751 // Track encoding style
5752 if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5753 $encodingStyle = $opData[$direction]['encodingStyle'];
5754 $enc_style = $encodingStyle;
5755 } else {
5756 $enc_style = false;
5757 }
5758 // NOTE: add error handling here
5759 // if serializeType returns false, then catch global error and fault
5760 if ($parametersArrayType == 'arraySimple') {
5761 $p = array_shift($parameters);
5762 $this->debug('calling serializeType w/indexed param');
5763 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5764 } elseif (isset($parameters[$name])) {
5765 $this->debug('calling serializeType w/named param');
5766 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5767 } else {
5768 // TODO: only send nillable
5769 $this->debug('calling serializeType w/null param');
5770 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5771 }
5772 }
5773 } else {
5774 $this->debug('no parameters passed.');
5775 }
5776 }
5777 $this->debug("serializeParameters returning: $xml");
5778 return $xml;
5779 }
5780
5793 function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
5794 {
5795 $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
5796 $this->appendDebug("value=" . $this->varDump($value));
5797 if($use == 'encoded' && $encodingStyle) {
5798 $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
5799 }
5800
5801 // if a soapval has been supplied, let its type override the WSDL
5802 if (is_object($value) && get_class($value) == 'soapval') {
5803 if ($value->type_ns) {
5804 $type = $value->type_ns . ':' . $value->type;
5805 $forceType = true;
5806 $this->debug("in serializeType: soapval overrides type to $type");
5807 } elseif ($value->type) {
5808 $type = $value->type;
5809 $forceType = true;
5810 $this->debug("in serializeType: soapval overrides type to $type");
5811 } else {
5812 $forceType = false;
5813 $this->debug("in serializeType: soapval does not override type");
5814 }
5815 $attrs = $value->attributes;
5816 $value = $value->value;
5817 $this->debug("in serializeType: soapval overrides value to $value");
5818 if ($attrs) {
5819 if (!is_array($value)) {
5820 $value['!'] = $value;
5821 }
5822 foreach ($attrs as $n => $v) {
5823 $value['!' . $n] = $v;
5824 }
5825 $this->debug("in serializeType: soapval provides attributes");
5826 }
5827 } else {
5828 $forceType = false;
5829 }
5830
5831 $xml = '';
5832 if (strpos($type, ':')) {
5833 $uqType = substr($type, strrpos($type, ':') + 1);
5834 $ns = substr($type, 0, strrpos($type, ':'));
5835 $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
5836 if ($this->getNamespaceFromPrefix($ns)) {
5837 $ns = $this->getNamespaceFromPrefix($ns);
5838 $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
5839 }
5840
5841 if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
5842 $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5843 if ($unqualified && $use == 'literal') {
5844 $elementNS = " xmlns=\"\"";
5845 } else {
5846 $elementNS = '';
5847 }
5848 if (is_null($value)) {
5849 if ($use == 'literal') {
5850 // TODO: depends on minOccurs
5851 $xml = "<$name$elementNS/>";
5852 } else {
5853 // TODO: depends on nillable, which should be checked before calling this method
5854 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5855 }
5856 $this->debug("in serializeType: returning: $xml");
5857 return $xml;
5858 }
5859 if ($uqType == 'Array') {
5860 // JBoss/Axis does this sometimes
5861 return $this->serialize_val($value, $name, false, false, false, false, $use);
5862 }
5863 if ($uqType == 'boolean') {
5864 if ((is_string($value) && $value == 'false') || (! $value)) {
5865 $value = 'false';
5866 } else {
5867 $value = 'true';
5868 }
5869 }
5870 if ($uqType == 'string' && gettype($value) == 'string') {
5871 $value = $this->expandEntities($value);
5872 }
5873 if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
5874 $value = sprintf("%.0lf", $value);
5875 }
5876 // it's a scalar
5877 // TODO: what about null/nil values?
5878 // check type isn't a custom type extending xmlschema namespace
5879 if (!$this->getTypeDef($uqType, $ns)) {
5880 if ($use == 'literal') {
5881 if ($forceType) {
5882 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
5883 } else {
5884 $xml = "<$name$elementNS>$value</$name>";
5885 }
5886 } else {
5887 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
5888 }
5889 $this->debug("in serializeType: returning: $xml");
5890 return $xml;
5891 }
5892 $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5893 } else if ($ns == 'http://xml.apache.org/xml-soap') {
5894 $this->debug('in serializeType: appears to be Apache SOAP type');
5895 if ($uqType == 'Map') {
5896 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5897 if (! $tt_prefix) {
5898 $this->debug('in serializeType: Add namespace for Apache SOAP type');
5899 $tt_prefix = 'ns' . rand(1000, 9999);
5900 $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
5901 // force this to be added to usedNamespaces
5902 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5903 }
5904 $contents = '';
5905 foreach($value as $k => $v) {
5906 $this->debug("serializing map element: key $k, value $v");
5907 $contents .= '<item>';
5908 $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
5909 $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
5910 $contents .= '</item>';
5911 }
5912 if ($use == 'literal') {
5913 if ($forceType) {
5914 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
5915 } else {
5916 $xml = "<$name>$contents</$name>";
5917 }
5918 } else {
5919 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
5920 }
5921 $this->debug("in serializeType: returning: $xml");
5922 return $xml;
5923 }
5924 $this->debug('in serializeType: Apache SOAP type, but only support Map');
5925 }
5926 } else {
5927 // TODO: should the type be compared to types in XSD, and the namespace
5928 // set to XSD if the type matches?
5929 $this->debug("in serializeType: No namespace for type $type");
5930 $ns = '';
5931 $uqType = $type;
5932 }
5933 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5934 $this->setError("$type ($uqType) is not a supported type.");
5935 $this->debug("in serializeType: $type ($uqType) is not a supported type.");
5936 return false;
5937 } else {
5938 $this->debug("in serializeType: found typeDef");
5939 $this->appendDebug('typeDef=' . $this->varDump($typeDef));
5940 if (substr($uqType, -1) == '^') {
5941 $uqType = substr($uqType, 0, -1);
5942 }
5943 }
5944 $phpType = $typeDef['phpType'];
5945 $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
5946 // if php type == struct, map value to the <all> element names
5947 if ($phpType == 'struct') {
5948 if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
5949 $elementName = $uqType;
5950 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5951 $elementNS = " xmlns=\"$ns\"";
5952 } else {
5953 $elementNS = " xmlns=\"\"";
5954 }
5955 } else {
5956 $elementName = $name;
5957 if ($unqualified) {
5958 $elementNS = " xmlns=\"\"";
5959 } else {
5960 $elementNS = '';
5961 }
5962 }
5963 if (is_null($value)) {
5964 if ($use == 'literal') {
5965 // TODO: depends on minOccurs
5966 $xml = "<$elementName$elementNS/>";
5967 } else {
5968 $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5969 }
5970 $this->debug("in serializeType: returning: $xml");
5971 return $xml;
5972 }
5973 if (is_object($value)) {
5974 $value = get_object_vars($value);
5975 }
5976 if (is_array($value)) {
5977 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5978 if ($use == 'literal') {
5979 if ($forceType) {
5980 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
5981 } else {
5982 $xml = "<$elementName$elementNS$elementAttrs>";
5983 }
5984 } else {
5985 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
5986 }
5987
5988 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5989 $xml .= "</$elementName>";
5990 } else {
5991 $this->debug("in serializeType: phpType is struct, but value is not an array");
5992 $this->setError("phpType is struct, but value is not an array: see debug output for details");
5993 $xml = '';
5994 }
5995 } elseif ($phpType == 'array') {
5996 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5997 $elementNS = " xmlns=\"$ns\"";
5998 } else {
5999 if ($unqualified) {
6000 $elementNS = " xmlns=\"\"";
6001 } else {
6002 $elementNS = '';
6003 }
6004 }
6005 if (is_null($value)) {
6006 if ($use == 'literal') {
6007 // TODO: depends on minOccurs
6008 $xml = "<$name$elementNS/>";
6009 } else {
6010 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6011 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6012 ":Array\" " .
6013 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6014 ':arrayType="' .
6015 $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
6016 ':' .
6017 $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
6018 }
6019 $this->debug("in serializeType: returning: $xml");
6020 return $xml;
6021 }
6022 if (isset($typeDef['multidimensional'])) {
6023 $nv = array();
6024 foreach($value as $v) {
6025 $cols = ',' . sizeof($v);
6026 $nv = array_merge($nv, $v);
6027 }
6028 $value = $nv;
6029 } else {
6030 $cols = '';
6031 }
6032 if (is_array($value) && sizeof($value) >= 1) {
6033 $rows = sizeof($value);
6034 $contents = '';
6035 foreach($value as $k => $v) {
6036 $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
6037 //if (strpos($typeDef['arrayType'], ':') ) {
6038 if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
6039 $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
6040 } else {
6041 $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
6042 }
6043 }
6044 } else {
6045 $rows = 0;
6046 $contents = null;
6047 }
6048 // TODO: for now, an empty value will be serialized as a zero element
6049 // array. Revisit this when coding the handling of null/nil values.
6050 if ($use == 'literal') {
6051 $xml = "<$name$elementNS>"
6052 .$contents
6053 ."</$name>";
6054 } else {
6055 $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
6056 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
6057 .':arrayType="'
6058 .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
6059 .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
6060 .$contents
6061 ."</$name>";
6062 }
6063 } elseif ($phpType == 'scalar') {
6064 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6065 $elementNS = " xmlns=\"$ns\"";
6066 } else {
6067 if ($unqualified) {
6068 $elementNS = " xmlns=\"\"";
6069 } else {
6070 $elementNS = '';
6071 }
6072 }
6073 if ($use == 'literal') {
6074 if ($forceType) {
6075 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
6076 } else {
6077 $xml = "<$name$elementNS>$value</$name>";
6078 }
6079 } else {
6080 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
6081 }
6082 }
6083 $this->debug("in serializeType: returning: $xml");
6084 return $xml;
6085 }
6086
6097 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6098 $xml = '';
6099 if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
6100 $this->debug("serialize attributes for XML Schema type $ns:$uqType");
6101 if (is_array($value)) {
6102 $xvalue = $value;
6103 } elseif (is_object($value)) {
6104 $xvalue = get_object_vars($value);
6105 } else {
6106 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6107 $xvalue = array();
6108 }
6109 foreach ($typeDef['attrs'] as $aName => $attrs) {
6110 if (isset($xvalue['!' . $aName])) {
6111 $xname = '!' . $aName;
6112 $this->debug("value provided for attribute $aName with key $xname");
6113 } elseif (isset($xvalue[$aName])) {
6114 $xname = $aName;
6115 $this->debug("value provided for attribute $aName with key $xname");
6116 } elseif (isset($attrs['default'])) {
6117 $xname = '!' . $aName;
6118 $xvalue[$xname] = $attrs['default'];
6119 $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
6120 } else {
6121 $xname = '';
6122 $this->debug("no value provided for attribute $aName");
6123 }
6124 if ($xname) {
6125 $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
6126 }
6127 }
6128 } else {
6129 $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
6130 }
6131 if (isset($typeDef['extensionBase'])) {
6132 $ns = $this->getPrefix($typeDef['extensionBase']);
6133 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6134 if ($this->getNamespaceFromPrefix($ns)) {
6135 $ns = $this->getNamespaceFromPrefix($ns);
6136 }
6137 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6138 $this->debug("serialize attributes for extension base $ns:$uqType");
6139 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6140 } else {
6141 $this->debug("extension base $ns:$uqType is not a supported type");
6142 }
6143 }
6144 return $xml;
6145 }
6146
6159 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
6160 $xml = '';
6161 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
6162 $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6163 if (is_array($value)) {
6164 $xvalue = $value;
6165 } elseif (is_object($value)) {
6166 $xvalue = get_object_vars($value);
6167 } else {
6168 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6169 $xvalue = array();
6170 }
6171 // toggle whether all elements are present - ideally should validate against schema
6172 if (count($typeDef['elements']) != count($xvalue)){
6173 $optionals = true;
6174 }
6175 foreach ($typeDef['elements'] as $eName => $attrs) {
6176 if (!isset($xvalue[$eName])) {
6177 if (isset($attrs['default'])) {
6178 $xvalue[$eName] = $attrs['default'];
6179 $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
6180 }
6181 }
6182 // if user took advantage of a minOccurs=0, then only serialize named parameters
6183 if (isset($optionals)
6184 && (!isset($xvalue[$eName]))
6185 && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
6186 ){
6187 if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
6188 $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
6189 }
6190 // do nothing
6191 $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6192 } else {
6193 // get value
6194 if (isset($xvalue[$eName])) {
6195 $v = $xvalue[$eName];
6196 } else {
6197 $v = null;
6198 }
6199 if (isset($attrs['form'])) {
6200 $unqualified = ($attrs['form'] == 'unqualified');
6201 } else {
6202 $unqualified = false;
6203 }
6204 if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
6205 $vv = $v;
6206 foreach ($vv as $k => $v) {
6207 if (isset($attrs['type']) || isset($attrs['ref'])) {
6208 // serialize schema-defined type
6209 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6210 } else {
6211 // serialize generic type (can this ever really happen?)
6212 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6213 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6214 }
6215 }
6216 } else {
6217 if (isset($attrs['type']) || isset($attrs['ref'])) {
6218 // serialize schema-defined type
6219 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6220 } else {
6221 // serialize generic type (can this ever really happen?)
6222 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6223 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6224 }
6225 }
6226 }
6227 }
6228 } else {
6229 $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
6230 }
6231 if (isset($typeDef['extensionBase'])) {
6232 $ns = $this->getPrefix($typeDef['extensionBase']);
6233 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6234 if ($this->getNamespaceFromPrefix($ns)) {
6235 $ns = $this->getNamespaceFromPrefix($ns);
6236 }
6237 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6238 $this->debug("serialize elements for extension base $ns:$uqType");
6239 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6240 } else {
6241 $this->debug("extension base $ns:$uqType is not a supported type");
6242 }
6243 }
6244 return $xml;
6245 }
6246
6261 function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
6262 if (count($elements) > 0) {
6263 $eElements = array();
6264 foreach($elements as $n => $e){
6265 // expand each element
6266 $ee = array();
6267 foreach ($e as $k => $v) {
6268 $k = strpos($k,':') ? $this->expandQname($k) : $k;
6269 $v = strpos($v,':') ? $this->expandQname($v) : $v;
6270 $ee[$k] = $v;
6271 }
6272 $eElements[$n] = $ee;
6273 }
6274 $elements = $eElements;
6275 }
6276
6277 if (count($attrs) > 0) {
6278 foreach($attrs as $n => $a){
6279 // expand each attribute
6280 foreach ($a as $k => $v) {
6281 $k = strpos($k,':') ? $this->expandQname($k) : $k;
6282 $v = strpos($v,':') ? $this->expandQname($v) : $v;
6283 $aa[$k] = $v;
6284 }
6285 $eAttrs[$n] = $aa;
6286 }
6287 $attrs = $eAttrs;
6288 }
6289
6290 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6291 $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
6292
6293 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6294 $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6295 }
6296
6308 function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
6309 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6310
6311 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6312 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6313 }
6314
6322 function addElement($attrs) {
6323 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6324 $this->schemas[$typens][0]->addElement($attrs);
6325 }
6326
6341 function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
6342 if ($use == 'encoded' && $encodingStyle == '') {
6343 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
6344 }
6345
6346 if ($style == 'document') {
6347 $elements = array();
6348 foreach ($in as $n => $t) {
6349 $elements[$n] = array('name' => $n, 'type' => $t);
6350 }
6351 $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
6352 $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
6353 $in = array('parameters' => 'tns:' . $name . '^');
6354
6355 $elements = array();
6356 foreach ($out as $n => $t) {
6357 $elements[$n] = array('name' => $n, 'type' => $t);
6358 }
6359 $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
6360 $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
6361 $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
6362 }
6363
6364 // get binding
6365 $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
6366 array(
6367 'name' => $name,
6368 'binding' => $this->serviceName . 'Binding',
6369 'endpoint' => $this->endpoint,
6370 'soapAction' => $soapaction,
6371 'style' => $style,
6372 'input' => array(
6373 'use' => $use,
6374 'namespace' => $namespace,
6375 'encodingStyle' => $encodingStyle,
6376 'message' => $name . 'Request',
6377 'parts' => $in),
6378 'output' => array(
6379 'use' => $use,
6380 'namespace' => $namespace,
6381 'encodingStyle' => $encodingStyle,
6382 'message' => $name . 'Response',
6383 'parts' => $out),
6384 'namespace' => $namespace,
6385 'transport' => 'http://schemas.xmlsoap.org/soap/http',
6386 'documentation' => $documentation);
6387 // add portTypes
6388 // add messages
6389 if($in)
6390 {
6391 foreach($in as $pName => $pType)
6392 {
6393 if(strpos($pType,':')) {
6394 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6395 }
6396 $this->messages[$name.'Request'][$pName] = $pType;
6397 }
6398 } else {
6399 $this->messages[$name.'Request']= '0';
6400 }
6401 if($out)
6402 {
6403 foreach($out as $pName => $pType)
6404 {
6405 if(strpos($pType,':')) {
6406 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6407 }
6408 $this->messages[$name.'Response'][$pName] = $pType;
6409 }
6410 } else {
6411 $this->messages[$name.'Response']= '0';
6412 }
6413 return true;
6414 }
6415}
6416?><?php
6417
6418
6419
6429class nusoap_parser extends nusoap_base {
6430
6431 var $xml = '';
6432 var $xml_encoding = '';
6433 var $method = '';
6434 var $root_struct = '';
6435 var $root_struct_name = '';
6436 var $root_struct_namespace = '';
6437 var $root_header = '';
6438 var $document = ''; // incoming SOAP body (text)
6439 // determines where in the message we are (envelope,header,body,method)
6440 var $status = '';
6441 var $position = 0;
6442 var $depth = 0;
6443 var $default_namespace = '';
6444 var $namespaces = array();
6445 var $message = array();
6446 var $parent = '';
6447 var $fault = false;
6448 var $fault_code = '';
6449 var $fault_str = '';
6450 var $fault_detail = '';
6451 var $depth_array = array();
6452 var $debug_flag = true;
6453 var $soapresponse = NULL; // parsed SOAP Body
6454 var $soapheader = NULL; // parsed SOAP Header
6455 var $responseHeaders = ''; // incoming SOAP headers (text)
6456 var $body_position = 0;
6457 // for multiref parsing:
6458 // array of id => pos
6459 var $ids = array();
6460 // array of id => hrefs => pos
6461 var $multirefs = array();
6462 // toggle for auto-decoding element content
6463 var $decode_utf8 = true;
6464
6474 function __construct($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
6476 $this->xml = $xml;
6477 $this->xml_encoding = $encoding;
6478 $this->method = $method;
6479 $this->decode_utf8 = $decode_utf8;
6480
6481 // Check whether content has been read.
6482 if(!empty($xml)){
6483 // Check XML encoding
6484 $pos_xml = strpos($xml, '<?xml');
6485 if ($pos_xml !== FALSE) {
6486 $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
6487 if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
6488 $xml_encoding = $res[1];
6489 if (strtoupper($xml_encoding) != $encoding) {
6490 $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
6491 $this->debug($err);
6492 if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
6493 $this->setError($err);
6494 return;
6495 }
6496 // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
6497 } else {
6498 $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
6499 }
6500 } else {
6501 $this->debug('No encoding specified in XML declaration');
6502 }
6503 } else {
6504 $this->debug('No XML declaration');
6505 }
6506 $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
6507 // Create an XML parser - why not xml_parser_create_ns?
6508 $this->parser = xml_parser_create($this->xml_encoding);
6509 // Set the options for parsing the XML data.
6510 //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
6511 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6512 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6513 // Set the object for the parser.
6514 xml_set_object($this->parser, $this);
6515 // Set the element handlers for the parser.
6516 xml_set_element_handler($this->parser, 'start_element','end_element');
6517 xml_set_character_data_handler($this->parser,'character_data');
6518
6519 // Parse the XML file.
6520 if(!xml_parse($this->parser,$xml,true)){
6521 // Display an error message.
6522 $err = sprintf('XML error parsing SOAP payload on line %d: %s',
6523 xml_get_current_line_number($this->parser),
6524 xml_error_string(xml_get_error_code($this->parser)));
6525 $this->debug($err);
6526 $this->debug("XML payload:\n" . $xml);
6527 $this->setError($err);
6528 } else {
6529 $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
6530 // get final value
6531 $this->soapresponse = $this->message[$this->root_struct]['result'];
6532 // get header value
6533 if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
6534 $this->soapheader = $this->message[$this->root_header]['result'];
6535 }
6536 // resolve hrefs/ids
6537 if(sizeof($this->multirefs) > 0){
6538 foreach($this->multirefs as $id => $hrefs){
6539 $this->debug('resolving multirefs for id: '.$id);
6540 $idVal = $this->buildVal($this->ids[$id]);
6541 if (is_array($idVal) && isset($idVal['!id'])) {
6542 unset($idVal['!id']);
6543 }
6544 foreach($hrefs as $refPos => $ref){
6545 $this->debug('resolving href at pos '.$refPos);
6546 $this->multirefs[$id][$refPos] = $idVal;
6547 }
6548 }
6549 }
6550 }
6551 xml_parser_free($this->parser);
6552 } else {
6553 $this->debug('xml was empty, didn\'t parse!');
6554 $this->setError('xml was empty, didn\'t parse!');
6555 }
6556 }
6557
6566 function start_element($parser, $name, $attrs) {
6567 // position in a total number of elements, starting from 0
6568 // update class level pos
6569 $pos = $this->position++;
6570 // and set mine
6571 $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
6572 // depth = how many levels removed from root?
6573 // set mine as current global depth and increment global depth value
6574 $this->message[$pos]['depth'] = $this->depth++;
6575
6576 // else add self as child to whoever the current parent is
6577 if($pos != 0){
6578 $this->message[$this->parent]['children'] .= '|'.$pos;
6579 }
6580 // set my parent
6581 $this->message[$pos]['parent'] = $this->parent;
6582 // set self as current parent
6583 $this->parent = $pos;
6584 // set self as current value for this depth
6585 $this->depth_array[$this->depth] = $pos;
6586 // get element prefix
6587 if(strpos($name,':')){
6588 // get ns prefix
6589 $prefix = substr($name,0,strpos($name,':'));
6590 // get unqualified name
6591 $name = substr(strstr($name,':'),1);
6592 }
6593 // set status
6594 if($name == 'Envelope'){
6595 $this->status = 'envelope';
6596 } elseif($name == 'Header' && $this->status = 'envelope'){
6597 $this->root_header = $pos;
6598 $this->status = 'header';
6599 } elseif($name == 'Body' && $this->status = 'envelope'){
6600 $this->status = 'body';
6601 $this->body_position = $pos;
6602 // set method
6603 } elseif($this->status == 'body' && $pos == ($this->body_position+1)){
6604 $this->status = 'method';
6605 $this->root_struct_name = $name;
6606 $this->root_struct = $pos;
6607 $this->message[$pos]['type'] = 'struct';
6608 $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
6609 }
6610 // set my status
6611 $this->message[$pos]['status'] = $this->status;
6612 // set name
6613 $this->message[$pos]['name'] = htmlspecialchars($name);
6614 // set attrs
6615 $this->message[$pos]['attrs'] = $attrs;
6616
6617 // loop through atts, logging ns and type declarations
6618 $attstr = '';
6619 foreach($attrs as $key => $value){
6620 $key_prefix = $this->getPrefix($key);
6621 $key_localpart = $this->getLocalPart($key);
6622 // if ns declarations, add to class level array of valid namespaces
6623 if($key_prefix == 'xmlns'){
6624 if(preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6625 $this->XMLSchemaVersion = $value;
6626 $this->namespaces['xsd'] = $this->XMLSchemaVersion;
6627 $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
6628 }
6629 $this->namespaces[$key_localpart] = $value;
6630 // set method namespace
6631 if($name == $this->root_struct_name){
6632 $this->methodNamespace = $value;
6633 }
6634 // if it's a type declaration, set type
6635 } elseif($key_localpart == 'type'){
6636 if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
6637 // do nothing: already processed arrayType
6638 } else {
6639 $value_prefix = $this->getPrefix($value);
6640 $value_localpart = $this->getLocalPart($value);
6641 $this->message[$pos]['type'] = $value_localpart;
6642 $this->message[$pos]['typePrefix'] = $value_prefix;
6643 if(isset($this->namespaces[$value_prefix])){
6644 $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
6645 } else if(isset($attrs['xmlns:'.$value_prefix])) {
6646 $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
6647 }
6648 // should do something here with the namespace of specified type?
6649 }
6650 } elseif($key_localpart == 'arrayType'){
6651 $this->message[$pos]['type'] = 'array';
6652 /* do arrayType ereg here
6653 [1] arrayTypeValue ::= atype asize
6654 [2] atype ::= QName rank*
6655 [3] rank ::= '[' (',')* ']'
6656 [4] asize ::= '[' length~ ']'
6657 [5] length ::= nextDimension* Digit+
6658 [6] nextDimension ::= Digit+ ','
6659 */
6660 $expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6661 if(preg_match($expr,$value,$regs)){
6662 $this->message[$pos]['typePrefix'] = $regs[1];
6663 $this->message[$pos]['arrayTypePrefix'] = $regs[1];
6664 if (isset($this->namespaces[$regs[1]])) {
6665 $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6666 } else if (isset($attrs['xmlns:'.$regs[1]])) {
6667 $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
6668 }
6669 $this->message[$pos]['arrayType'] = $regs[2];
6670 $this->message[$pos]['arraySize'] = $regs[3];
6671 $this->message[$pos]['arrayCols'] = $regs[4];
6672 }
6673 // specifies nil value (or not)
6674 } elseif ($key_localpart == 'nil'){
6675 $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
6676 // some other attribute
6677 } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
6678 $this->message[$pos]['xattrs']['!' . $key] = $value;
6679 }
6680
6681 if ($key == 'xmlns') {
6682 $this->default_namespace = $value;
6683 }
6684 // log id
6685 if($key == 'id'){
6686 $this->ids[$value] = $pos;
6687 }
6688 // root
6689 if($key_localpart == 'root' && $value == 1){
6690 $this->status = 'method';
6691 $this->root_struct_name = $name;
6692 $this->root_struct = $pos;
6693 $this->debug("found root struct $this->root_struct_name, pos $pos");
6694 }
6695 // for doclit
6696 $attstr .= " $key=\"$value\"";
6697 }
6698 // get namespace - must be done after namespace atts are processed
6699 if(isset($prefix)){
6700 $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
6701 $this->default_namespace = $this->namespaces[$prefix];
6702 } else {
6703 $this->message[$pos]['namespace'] = $this->default_namespace;
6704 }
6705 if($this->status == 'header'){
6706 if ($this->root_header != $pos) {
6707 $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6708 }
6709 } elseif($this->root_struct_name != ''){
6710 $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6711 }
6712 }
6713
6721 function end_element($parser, $name) {
6722 // position of current element is equal to the last value left in depth_array for my depth
6723 $pos = $this->depth_array[$this->depth--];
6724
6725 // get element prefix
6726 if(strpos($name,':')){
6727 // get ns prefix
6728 $prefix = substr($name,0,strpos($name,':'));
6729 // get unqualified name
6730 $name = substr(strstr($name,':'),1);
6731 }
6732
6733 // build to native type
6734 if(isset($this->body_position) && $pos > $this->body_position){
6735 // deal w/ multirefs
6736 if(isset($this->message[$pos]['attrs']['href'])){
6737 // get id
6738 $id = substr($this->message[$pos]['attrs']['href'],1);
6739 // add placeholder to href array
6740 $this->multirefs[$id][$pos] = 'placeholder';
6741 // add set a reference to it as the result value
6742 $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
6743 // build complexType values
6744 } elseif($this->message[$pos]['children'] != ''){
6745 // if result has already been generated (struct/array)
6746 if(!isset($this->message[$pos]['result'])){
6747 $this->message[$pos]['result'] = $this->buildVal($pos);
6748 }
6749 // build complexType values of attributes and possibly simpleContent
6750 } elseif (isset($this->message[$pos]['xattrs'])) {
6751 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6752 $this->message[$pos]['xattrs']['!'] = null;
6753 } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6754 if (isset($this->message[$pos]['type'])) {
6755 $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'] : '');
6756 } else {
6757 $parent = $this->message[$pos]['parent'];
6758 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6759 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6760 } else {
6761 $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
6762 }
6763 }
6764 }
6765 $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
6766 // set value of simpleType (or nil complexType)
6767 } else {
6768 //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
6769 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6770 $this->message[$pos]['xattrs']['!'] = null;
6771 } elseif (isset($this->message[$pos]['type'])) {
6772 $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'] : '');
6773 } else {
6774 $parent = $this->message[$pos]['parent'];
6775 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6776 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6777 } else {
6778 $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
6779 }
6780 }
6781
6782 /* add value to parent's result, if parent is struct/array
6783 $parent = $this->message[$pos]['parent'];
6784 if($this->message[$parent]['type'] != 'map'){
6785 if(strtolower($this->message[$parent]['type']) == 'array'){
6786 $this->message[$parent]['result'][] = $this->message[$pos]['result'];
6787 } else {
6788 $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
6789 }
6790 }
6791 */
6792 }
6793 }
6794
6795 // for doclit
6796 if($this->status == 'header'){
6797 if ($this->root_header != $pos) {
6798 $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6799 }
6800 } elseif($pos >= $this->root_struct){
6801 $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6802 }
6803 // switch status
6804 if($pos == $this->root_struct){
6805 $this->status = 'body';
6806 $this->root_struct_namespace = $this->message[$pos]['namespace'];
6807 } elseif($name == 'Body'){
6808 $this->status = 'envelope';
6809 } elseif($name == 'Header'){
6810 $this->status = 'envelope';
6811 } elseif($name == 'Envelope'){
6812 //
6813 }
6814 // set parent back to my parent
6815 $this->parent = $this->message[$pos]['parent'];
6816 }
6817
6825 function character_data($parser, $data){
6826 $pos = $this->depth_array[$this->depth];
6827 if ($this->xml_encoding=='UTF-8'){
6828 // TODO: add an option to disable this for folks who want
6829 // raw UTF-8 that, e.g., might not map to iso-8859-1
6830 // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
6831 if($this->decode_utf8){
6832 $data = utf8_decode($data);
6833 }
6834 }
6835 $this->message[$pos]['cdata'] .= $data;
6836 // for doclit
6837 if($this->status == 'header'){
6838 $this->responseHeaders .= $data;
6839 } else {
6840 $this->document .= $data;
6841 }
6842 }
6843
6851 function get_response(){
6852 return $this->soapresponse;
6853 }
6854
6861 function get_soapbody(){
6862 return $this->soapresponse;
6863 }
6864
6871 function get_soapheader(){
6872 return $this->soapheader;
6873 }
6874
6881 function getHeaders(){
6883 }
6884
6894 function decodeSimple($value, $type, $typens) {
6895 // TODO: use the namespace!
6896 if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
6897 return (string) $value;
6898 }
6899 if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
6900 return (int) $value;
6901 }
6902 if ($type == 'float' || $type == 'double' || $type == 'decimal') {
6903 return (double) $value;
6904 }
6905 if ($type == 'boolean') {
6906 if (strtolower($value) == 'false' || strtolower($value) == 'f') {
6907 return false;
6908 }
6909 return (boolean) $value;
6910 }
6911 if ($type == 'base64' || $type == 'base64Binary') {
6912 $this->debug('Decode base64 value');
6913 return base64_decode($value);
6914 }
6915 // obscure numeric types
6916 if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
6917 || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
6918 || $type == 'unsignedInt'
6919 || $type == 'unsignedShort' || $type == 'unsignedByte') {
6920 return (int) $value;
6921 }
6922 // bogus: parser treats array with no elements as a simple type
6923 if ($type == 'array') {
6924 return array();
6925 }
6926 // everything else
6927 return (string) $value;
6928 }
6929
6938 function buildVal($pos){
6939 if(!isset($this->message[$pos]['type'])){
6940 $this->message[$pos]['type'] = '';
6941 }
6942 $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
6943 // if there are children...
6944 if($this->message[$pos]['children'] != ''){
6945 $this->debug('in buildVal, there are children');
6946 $children = explode('|',$this->message[$pos]['children']);
6947 array_shift($children); // knock off empty
6948 // md array
6949 if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
6950 $r=0; // rowcount
6951 $c=0; // colcount
6952 foreach($children as $child_pos){
6953 $this->debug("in buildVal, got an MD array element: $r, $c");
6954 $params[$r][] = $this->message[$child_pos]['result'];
6955 $c++;
6956 if($c == $this->message[$pos]['arrayCols']){
6957 $c = 0;
6958 $r++;
6959 }
6960 }
6961 // array
6962 } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
6963 $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
6964 foreach($children as $child_pos){
6965 $params[] = &$this->message[$child_pos]['result'];
6966 }
6967 // apache Map type: java hashtable
6968 } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
6969 $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
6970 foreach($children as $child_pos){
6971 $kv = explode("|",$this->message[$child_pos]['children']);
6972 $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
6973 }
6974 // generic compound type
6975 //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
6976 } else {
6977 // Apache Vector type: treat as an array
6978 $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
6979 if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
6980 $notstruct = 1;
6981 } else {
6982 $notstruct = 0;
6983 }
6984 //
6985 foreach($children as $child_pos){
6986 if($notstruct){
6987 $params[] = &$this->message[$child_pos]['result'];
6988 } else {
6989 if (isset($params[$this->message[$child_pos]['name']])) {
6990 // de-serialize repeated element name into an array
6991 if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
6992 $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
6993 }
6994 $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
6995 } else {
6996 $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
6997 }
6998 }
6999 }
7000 }
7001 if (isset($this->message[$pos]['xattrs'])) {
7002 $this->debug('in buildVal, handling attributes');
7003 foreach ($this->message[$pos]['xattrs'] as $n => $v) {
7004 $params[$n] = $v;
7005 }
7006 }
7007 // handle simpleContent
7008 if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
7009 $this->debug('in buildVal, handling simpleContent');
7010 if (isset($this->message[$pos]['type'])) {
7011 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7012 } else {
7013 $parent = $this->message[$pos]['parent'];
7014 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7015 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7016 } else {
7017 $params['!'] = $this->message[$pos]['cdata'];
7018 }
7019 }
7020 }
7021 $ret = is_array($params) ? $params : array();
7022 $this->debug('in buildVal, return:');
7023 $this->appendDebug($this->varDump($ret));
7024 return $ret;
7025 } else {
7026 $this->debug('in buildVal, no children, building scalar');
7027 $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
7028 if (isset($this->message[$pos]['type'])) {
7029 $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7030 $this->debug("in buildVal, return: $ret");
7031 return $ret;
7032 }
7033 $parent = $this->message[$pos]['parent'];
7034 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7035 $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7036 $this->debug("in buildVal, return: $ret");
7037 return $ret;
7038 }
7039 $ret = $this->message[$pos]['cdata'];
7040 $this->debug("in buildVal, return: $ret");
7041 return $ret;
7042 }
7043 }
7044}
7045
7049class soap_parser extends nusoap_parser {
7050}
7051
7052?><?php
7053
7054
7055
7076class nusoap_client extends nusoap_base {
7077
7078 var $username = ''; // Username for HTTP authentication
7079 var $password = ''; // Password for HTTP authentication
7080 var $authtype = ''; // Type of HTTP authentication
7081 var $certRequest = array(); // Certificate for HTTP SSL authentication
7082 var $requestHeaders = false; // SOAP headers in request (text)
7083 var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
7084 var $responseHeader = NULL; // SOAP Header from response (parsed)
7085 var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
7086 var $endpoint;
7087 var $forceEndpoint = ''; // overrides WSDL endpoint
7088 var $proxyhost = '';
7089 var $proxyport = '';
7090 var $proxyusername = '';
7091 var $proxypassword = '';
7092 var $xml_encoding = ''; // character set encoding of incoming (response) messages
7093 var $http_encoding = false;
7094 var $timeout = 0; // HTTP connection timeout
7095 var $response_timeout = 30; // HTTP response timeout
7096 var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
7097 var $persistentConnection = false;
7098 var $defaultRpcParams = false; // This is no longer used
7099 var $request = ''; // HTTP request
7100 var $response = ''; // HTTP response
7101 var $responseData = ''; // SOAP payload of response
7102 var $cookies = array(); // Cookies from response or for request
7103 var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
7104 var $operations = array(); // WSDL operations, empty for WSDL initialization error
7105 var $curl_options = array(); // User-specified cURL options
7106 var $bindingType = ''; // WSDL operation binding type
7107 var $use_curl = false; // whether to always try to use cURL
7108
7109 /*
7110 * fault related variables
7111 */
7116 var $fault;
7121 var $faultcode;
7126 var $faultstring;
7131 var $faultdetail;
7132
7147 function __construct($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
7149 $this->endpoint = $endpoint;
7150 $this->proxyhost = $proxyhost;
7151 $this->proxyport = $proxyport;
7152 $this->proxyusername = $proxyusername;
7153 $this->proxypassword = $proxypassword;
7154 $this->timeout = $timeout;
7155 $this->response_timeout = $response_timeout;
7156
7157 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7158 $this->appendDebug('endpoint=' . $this->varDump($endpoint));
7159
7160 // make values
7161 if($wsdl){
7162 if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
7163 $this->wsdl = $endpoint;
7164 $this->endpoint = $this->wsdl->wsdl;
7165 $this->wsdlFile = $this->endpoint;
7166 $this->debug('existing wsdl instance created from ' . $this->endpoint);
7167 $this->checkWSDL();
7168 } else {
7169 $this->wsdlFile = $this->endpoint;
7170 $this->wsdl = null;
7171 $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
7172 }
7173 $this->endpointType = 'wsdl';
7174 } else {
7175 $this->debug("instantiate SOAP with endpoint at $endpoint");
7176 $this->endpointType = 'soap';
7177 }
7178 }
7179
7205 function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
7206 $this->operation = $operation;
7207 $this->fault = false;
7208 $this->setError('');
7209 $this->request = '';
7210 $this->response = '';
7211 $this->responseData = '';
7212 $this->faultstring = '';
7213 $this->faultcode = '';
7214 $this->opData = array();
7215
7216 $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7217 $this->appendDebug('params=' . $this->varDump($params));
7218 $this->appendDebug('headers=' . $this->varDump($headers));
7219 if ($headers) {
7220 $this->requestHeaders = $headers;
7221 }
7222 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7223 $this->loadWSDL();
7224 if ($this->getError())
7225 return false;
7226 }
7227 // serialize parameters
7228 if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
7229 // use WSDL for operation
7230 $this->opData = $opData;
7231 $this->debug("found operation");
7232 $this->appendDebug('opData=' . $this->varDump($opData));
7233 if (isset($opData['soapAction'])) {
7234 $soapAction = $opData['soapAction'];
7235 }
7236 if (! $this->forceEndpoint) {
7237 $this->endpoint = $opData['endpoint'];
7238 } else {
7239 $this->endpoint = $this->forceEndpoint;
7240 }
7241 $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
7242 $style = $opData['style'];
7243 $use = $opData['input']['use'];
7244 // add ns to ns array
7245 if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
7246 $nsPrefix = 'ns' . rand(1000, 9999);
7247 $this->wsdl->namespaces[$nsPrefix] = $namespace;
7248 }
7249 $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
7250 // serialize payload
7251 if (is_string($params)) {
7252 $this->debug("serializing param string for WSDL operation $operation");
7253 $payload = $params;
7254 } elseif (is_array($params)) {
7255 $this->debug("serializing param array for WSDL operation $operation");
7256 $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
7257 } else {
7258 $this->debug('params must be array or string');
7259 $this->setError('params must be array or string');
7260 return false;
7261 }
7262 $usedNamespaces = $this->wsdl->usedNamespaces;
7263 if (isset($opData['input']['encodingStyle'])) {
7264 $encodingStyle = $opData['input']['encodingStyle'];
7265 } else {
7266 $encodingStyle = '';
7267 }
7268 $this->appendDebug($this->wsdl->getDebug());
7269 $this->wsdl->clearDebug();
7270 if ($errstr = $this->wsdl->getError()) {
7271 $this->debug('got wsdl error: '.$errstr);
7272 $this->setError('wsdl error: '.$errstr);
7273 return false;
7274 }
7275 } elseif($this->endpointType == 'wsdl') {
7276 // operation not in WSDL
7277 $this->appendDebug($this->wsdl->getDebug());
7278 $this->wsdl->clearDebug();
7279 $this->setError( 'operation '.$operation.' not present.');
7280 $this->debug("operation '$operation' not present.");
7281 return false;
7282 } else {
7283 // no WSDL
7284 //$this->namespaces['ns1'] = $namespace;
7285 $nsPrefix = 'ns' . rand(1000, 9999);
7286 // serialize
7287 $payload = '';
7288 if (is_string($params)) {
7289 $this->debug("serializing param string for operation $operation");
7290 $payload = $params;
7291 } elseif (is_array($params)) {
7292 $this->debug("serializing param array for operation $operation");
7293 foreach($params as $k => $v){
7294 $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
7295 }
7296 } else {
7297 $this->debug('params must be array or string');
7298 $this->setError('params must be array or string');
7299 return false;
7300 }
7301 $usedNamespaces = array();
7302 if ($use == 'encoded') {
7303 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
7304 } else {
7305 $encodingStyle = '';
7306 }
7307 }
7308 // wrap RPC calls with method element
7309 if ($style == 'rpc') {
7310 if ($use == 'literal') {
7311 $this->debug("wrapping RPC request with literal method element");
7312 if ($namespace) {
7313 // 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
7314 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7315 $payload .
7316 "</$nsPrefix:$operation>";
7317 } else {
7318 $payload = "<$operation>" . $payload . "</$operation>";
7319 }
7320 } else {
7321 $this->debug("wrapping RPC request with encoded method element");
7322 if ($namespace) {
7323 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7324 $payload .
7325 "</$nsPrefix:$operation>";
7326 } else {
7327 $payload = "<$operation>" .
7328 $payload .
7329 "</$operation>";
7330 }
7331 }
7332 }
7333 // serialize envelope
7334 $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
7335 $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7336 $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7337 // send
7338 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7339 if($errstr = $this->getError()){
7340 $this->debug('Error: '.$errstr);
7341 return false;
7342 } else {
7343 $this->return = $return;
7344 $this->debug('sent message successfully and got a(n) '.gettype($return));
7345 $this->appendDebug('return=' . $this->varDump($return));
7346
7347 // fault?
7348 if(is_array($return) && isset($return['faultcode'])){
7349 $this->debug('got fault');
7350 $this->setError($return['faultcode'].': '.$return['faultstring']);
7351 $this->fault = true;
7352 foreach($return as $k => $v){
7353 $this->$k = $v;
7354 $this->debug("$k = $v<br>");
7355 }
7356 return $return;
7357 } elseif ($style == 'document') {
7358 // NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
7359 // we are only going to return the first part here...sorry about that
7360 return $return;
7361 } else {
7362 // array of return values
7363 if(is_array($return)){
7364 // multiple 'out' parameters, which we return wrapped up
7365 // in the array
7366 if(sizeof($return) > 1){
7367 return $return;
7368 }
7369 // single 'out' parameter (normally the return value)
7370 $return = array_shift($return);
7371 $this->debug('return shifted value: ');
7372 $this->appendDebug($this->varDump($return));
7373 return $return;
7374 // nothing returned (ie, echoVoid)
7375 } else {
7376 return "";
7377 }
7378 }
7379 }
7380 }
7381
7387 function checkWSDL() {
7388 $this->appendDebug($this->wsdl->getDebug());
7389 $this->wsdl->clearDebug();
7390 $this->debug('checkWSDL');
7391 // catch errors
7392 if ($errstr = $this->wsdl->getError()) {
7393 $this->debug('got wsdl error: '.$errstr);
7394 $this->setError('wsdl error: '.$errstr);
7395 } elseif ($this->operations = $this->wsdl->getOperations('soap')) {
7396 $this->bindingType = 'soap';
7397 $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7398 } elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
7399 $this->bindingType = 'soap12';
7400 $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7401 $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
7402 } else {
7403 $this->debug('getOperations returned false');
7404 $this->setError('no operations defined in the WSDL document!');
7405 }
7406 }
7407
7413 function loadWSDL() {
7414 $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
7415 $this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7416 $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7417 $this->wsdl->fetchWSDL($this->wsdlFile);
7418 $this->checkWSDL();
7419 }
7420
7428 function getOperationData($operation){
7429 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7430 $this->loadWSDL();
7431 if ($this->getError())
7432 return false;
7433 }
7434 if(isset($this->operations[$operation])){
7435 return $this->operations[$operation];
7436 }
7437 $this->debug("No data for operation: $operation");
7438 }
7439
7454 function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
7455 $this->checkCookies();
7456 // detect transport
7457 switch(true){
7458 // http(s)
7459 case preg_match('/^http/',$this->endpoint):
7460 $this->debug('transporting via HTTP');
7461 if($this->persistentConnection == true && is_object($this->persistentConnection)){
7463 } else {
7464 $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
7465 if ($this->persistentConnection) {
7466 $http->usePersistentConnection();
7467 }
7468 }
7469 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7470 $http->setSOAPAction($soapaction);
7471 if($this->proxyhost && $this->proxyport){
7472 $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7473 }
7474 if($this->authtype != '') {
7475 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7476 }
7477 if($this->http_encoding != ''){
7478 $http->setEncoding($this->http_encoding);
7479 }
7480 $this->debug('sending message, length='.strlen($msg));
7481 if(preg_match('/^http:/',$this->endpoint)){
7482 //if(strpos($this->endpoint,'http:')){
7483 $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
7484 } elseif(preg_match('/^https/',$this->endpoint)){
7485 //} elseif(strpos($this->endpoint,'https:')){
7486 //if(phpversion() == '4.3.0-dev'){
7487 //$response = $http->send($msg,$timeout,$response_timeout);
7488 //$this->request = $http->outgoing_payload;
7489 //$this->response = $http->incoming_payload;
7490 //} else
7491 $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7492 } else {
7493 $this->setError('no http/s in endpoint url');
7494 }
7495 $this->request = $http->outgoing_payload;
7496 $this->response = $http->incoming_payload;
7497 $this->appendDebug($http->getDebug());
7498 $this->UpdateCookies($http->incoming_cookies);
7499
7500 // save transport object if using persistent connections
7501 if ($this->persistentConnection) {
7502 $http->clearDebug();
7503 if (!is_object($this->persistentConnection)) {
7504 $this->persistentConnection = $http;
7505 }
7506 }
7507
7508 if($err = $http->getError()){
7509 $this->setError('HTTP Error: '.$err);
7510 return false;
7511 } elseif($this->getError()){
7512 return false;
7513 } else {
7514 $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
7515 return $this->parseResponse($http->incoming_headers, $this->responseData);
7516 }
7517 break;
7518 default:
7519 $this->setError('no transport found, or selected transport is not yet supported!');
7520 return false;
7521 break;
7522 }
7523 }
7524
7533 function parseResponse($headers, $data) {
7534 $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
7535 $this->appendDebug($this->varDump($headers));
7536 if (!strstr($headers['content-type'], 'text/xml')) {
7537 $this->setError('Response not of type text/xml: ' . $headers['content-type']);
7538 return false;
7539 }
7540 if (strpos($headers['content-type'], '=')) {
7541 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
7542 $this->debug('Got response encoding: ' . $enc);
7543 if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7544 $this->xml_encoding = strtoupper($enc);
7545 } else {
7546 $this->xml_encoding = 'US-ASCII';
7547 }
7548 } else {
7549 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
7550 $this->xml_encoding = 'ISO-8859-1';
7551 }
7552 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
7553 $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7554 // add parser debug data to our debug
7555 $this->appendDebug($parser->getDebug());
7556 // if parse errors
7557 if($errstr = $parser->getError()){
7558 $this->setError( $errstr);
7559 // destroy the parser object
7560 unset($parser);
7561 return false;
7562 } else {
7563 // get SOAP headers
7564 $this->responseHeaders = $parser->getHeaders();
7565 // get SOAP headers
7566 $this->responseHeader = $parser->get_soapheader();
7567 // get decoded message
7568 $return = $parser->get_soapbody();
7569 // add document for doclit support
7570 $this->document = $parser->document;
7571 // destroy the parser object
7572 unset($parser);
7573 // return decode message
7574 return $return;
7575 }
7576 }
7577
7585 function setCurlOption($option, $value) {
7586 $this->debug("setCurlOption option=$option, value=");
7587 $this->appendDebug($this->varDump($value));
7588 $this->curl_options[$option] = $value;
7589 }
7590
7597 function setEndpoint($endpoint) {
7598 $this->debug("setEndpoint(\"$endpoint\")");
7599 $this->forceEndpoint = $endpoint;
7600 }
7601
7608 function setHeaders($headers){
7609 $this->debug("setHeaders headers=");
7610 $this->appendDebug($this->varDump($headers));
7611 $this->requestHeaders = $headers;
7612 }
7613
7620 function getHeaders(){
7622 }
7623
7630 function getHeader(){
7631 return $this->responseHeader;
7632 }
7633
7644 $this->proxyhost = $proxyhost;
7645 $this->proxyport = $proxyport;
7646 $this->proxyusername = $proxyusername;
7647 $this->proxypassword = $proxypassword;
7648 }
7649
7659 function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
7660 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
7661 $this->appendDebug($this->varDump($certRequest));
7662 $this->username = $username;
7663 $this->password = $password;
7664 $this->authtype = $authtype;
7665 $this->certRequest = $certRequest;
7666 }
7667
7674 function setHTTPEncoding($enc='gzip, deflate'){
7675 $this->debug("setHTTPEncoding(\"$enc\")");
7676 $this->http_encoding = $enc;
7677 }
7678
7685 function setUseCURL($use) {
7686 $this->debug("setUseCURL($use)");
7687 $this->use_curl = $use;
7688 }
7689
7695 function useHTTPPersistentConnection(){
7696 $this->debug("useHTTPPersistentConnection");
7697 $this->persistentConnection = true;
7698 }
7699
7711 function getDefaultRpcParams() {
7713 }
7714
7726 function setDefaultRpcParams($rpcParams) {
7727 $this->defaultRpcParams = $rpcParams;
7728 }
7729
7737 function getProxy() {
7738 $r = rand();
7739 $evalStr = $this->_getProxyClassCode($r);
7740 //$this->debug("proxy class: $evalStr");
7741 if ($this->getError()) {
7742 $this->debug("Error from _getProxyClassCode, so return NULL");
7743 return null;
7744 }
7745 // eval the class
7746 eval($evalStr);
7747 // instantiate proxy object
7748 eval("\$proxy = new nusoap_proxy_$r('');");
7749 // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
7750 $proxy->endpointType = 'wsdl';
7751 $proxy->wsdlFile = $this->wsdlFile;
7752 $proxy->wsdl = $this->wsdl;
7753 $proxy->operations = $this->operations;
7754 $proxy->defaultRpcParams = $this->defaultRpcParams;
7755 // transfer other state
7756 $proxy->soap_defencoding = $this->soap_defencoding;
7757 $proxy->username = $this->username;
7758 $proxy->password = $this->password;
7759 $proxy->authtype = $this->authtype;
7760 $proxy->certRequest = $this->certRequest;
7761 $proxy->requestHeaders = $this->requestHeaders;
7762 $proxy->endpoint = $this->endpoint;
7763 $proxy->forceEndpoint = $this->forceEndpoint;
7764 $proxy->proxyhost = $this->proxyhost;
7765 $proxy->proxyport = $this->proxyport;
7766 $proxy->proxyusername = $this->proxyusername;
7767 $proxy->proxypassword = $this->proxypassword;
7768 $proxy->http_encoding = $this->http_encoding;
7769 $proxy->timeout = $this->timeout;
7770 $proxy->response_timeout = $this->response_timeout;
7771 $proxy->persistentConnection = &$this->persistentConnection;
7772 $proxy->decode_utf8 = $this->decode_utf8;
7773 $proxy->curl_options = $this->curl_options;
7774 $proxy->bindingType = $this->bindingType;
7775 $proxy->use_curl = $this->use_curl;
7776 return $proxy;
7777 }
7778
7785 function _getProxyClassCode($r) {
7786 $this->debug("in getProxy endpointType=$this->endpointType");
7787 $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
7788 if ($this->endpointType != 'wsdl') {
7789 $evalStr = 'A proxy can only be created for a WSDL client';
7790 $this->setError($evalStr);
7791 $evalStr = "echo \"$evalStr\";";
7792 return $evalStr;
7793 }
7794 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7795 $this->loadWSDL();
7796 if ($this->getError()) {
7797 return "echo \"" . $this->getError() . "\";";
7798 }
7799 }
7800 $evalStr = '';
7801 foreach ($this->operations as $operation => $opData) {
7802 if ($operation != '') {
7803 // create param string and param comment string
7804 if (sizeof($opData['input']['parts']) > 0) {
7805 $paramStr = '';
7806 $paramArrayStr = '';
7807 $paramCommentStr = '';
7808 foreach ($opData['input']['parts'] as $name => $type) {
7809 $paramStr .= "\$$name, ";
7810 $paramArrayStr .= "'$name' => \$$name, ";
7811 $paramCommentStr .= "$type \$$name, ";
7812 }
7813 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7814 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7815 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7816 } else {
7817 $paramStr = '';
7818 $paramArrayStr = '';
7819 $paramCommentStr = 'void';
7820 }
7821 $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
7822 $evalStr .= "// $paramCommentStr
7823 function " . str_replace('.', '__', $operation) . "($paramStr) {
7824 \$params = array($paramArrayStr);
7825 return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
7826 }
7827 ";
7828 unset($paramStr);
7829 unset($paramCommentStr);
7830 }
7831 }
7832 $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
7833 '.$evalStr.'
7834}';
7835 return $evalStr;
7836 }
7837
7844 function getProxyClassCode() {
7845 $r = rand();
7846 return $this->_getProxyClassCode($r);
7847 }
7848
7856 function getHTTPBody($soapmsg) {
7857 return $soapmsg;
7858 }
7859
7868 function getHTTPContentType() {
7869 return 'text/xml';
7870 }
7871
7881 function getHTTPContentTypeCharset() {
7883 }
7884
7885 /*
7886 * whether or not parser should decode utf8 element content
7887 *
7888 * @return always returns true
7889 * @access public
7890 */
7891 function decodeUTF8($bool){
7892 $this->decode_utf8 = $bool;
7893 return true;
7894 }
7895
7904 function setCookie($name, $value) {
7905 if (strlen($name) == 0) {
7906 return false;
7907 }
7908 $this->cookies[] = array('name' => $name, 'value' => $value);
7909 return true;
7910 }
7911
7918 function getCookies() {
7919 return $this->cookies;
7920 }
7921
7928 function checkCookies() {
7929 if (sizeof($this->cookies) == 0) {
7930 return true;
7931 }
7932 $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
7933 $curr_cookies = $this->cookies;
7934 $this->cookies = array();
7935 foreach ($curr_cookies as $cookie) {
7936 if (! is_array($cookie)) {
7937 $this->debug('Remove cookie that is not an array');
7938 continue;
7939 }
7940 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
7941 if (strtotime($cookie['expires']) > time()) {
7942 $this->cookies[] = $cookie;
7943 } else {
7944 $this->debug('Remove expired cookie ' . $cookie['name']);
7945 }
7946 } else {
7947 $this->cookies[] = $cookie;
7948 }
7949 }
7950 $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
7951 return true;
7952 }
7953
7961 function UpdateCookies($cookies) {
7962 if (sizeof($this->cookies) == 0) {
7963 // no existing cookies: take whatever is new
7964 if (sizeof($cookies) > 0) {
7965 $this->debug('Setting new cookie(s)');
7966 $this->cookies = $cookies;
7967 }
7968 return true;
7969 }
7970 if (sizeof($cookies) == 0) {
7971 // no new cookies: keep what we've got
7972 return true;
7973 }
7974 // merge
7975 foreach ($cookies as $newCookie) {
7976 if (!is_array($newCookie)) {
7977 continue;
7978 }
7979 if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
7980 continue;
7981 }
7982 $newName = $newCookie['name'];
7983
7984 $found = false;
7985 for ($i = 0; $i < count($this->cookies); $i++) {
7986 $cookie = $this->cookies[$i];
7987 if (!is_array($cookie)) {
7988 continue;
7989 }
7990 if (!isset($cookie['name'])) {
7991 continue;
7992 }
7993 if ($newName != $cookie['name']) {
7994 continue;
7995 }
7996 $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
7997 $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
7998 if ($newDomain != $domain) {
7999 continue;
8000 }
8001 $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
8002 $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
8003 if ($newPath != $path) {
8004 continue;
8005 }
8006 $this->cookies[$i] = $newCookie;
8007 $found = true;
8008 $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
8009 break;
8010 }
8011 if (! $found) {
8012 $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
8013 $this->cookies[] = $newCookie;
8014 }
8015 }
8016 return true;
8017 }
8018}
8019
8020if (!extension_loaded('soap')) {
8024 class soapclient extends nusoap_client {
8025 }
8026}
$parser
Definition: BPMN2Parser.php:23
$n
Definition: RandomTest.php:85
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
if(! $in) print
$_GET["client_id"]
An exception for terminatinating execution or to throw for unit testing.
parses an XML Schema, allows access to it's data, other utility methods no validation....
Definition: nusoap.php:734
nusoap_base
Definition: nusoap.php:61
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
Definition: nusoap.php:525
& getDebug()
gets the current debug data for this instance
Definition: nusoap.php:323
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
Definition: nusoap.php:336
setError($str)
sets error string
Definition: nusoap.php:184
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace returns false if no namespace registered with the given pref...
Definition: nusoap.php:541
debug($string)
adds debug data to the class level debug string
Definition: nusoap.php:144
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
Definition: nusoap.php:557
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded')
Definition: nusoap.php:212
clearDebug()
clears the current debug data for this instance
Definition: nusoap.php:311
expandEntities($val)
expands entities, e.g.
Definition: nusoap.php:154
$soap_defencoding
Definition: nusoap.php:86
expandQname($qname)
expands a qualified name
Definition: nusoap.php:483
$XMLSchemaVersion
Definition: nusoap.php:78
varDump($data)
Definition: nusoap.php:567
$error_str
Current error string (manipulated by getError/setError)
Definition: nusoap.php:66
getError()
returns error string if present
Definition: nusoap.php:171
appendDebug($string)
adds debug data to the instance debug string without formatting
Definition: nusoap.php:298
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed
Definition: nusoap.php:508
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded')
serialize message
Definition: nusoap.php:417
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
Definition: nusoap.php:195
__construct()
constructor
Definition: nusoap.php:236
[nu]soapclient higher level class for easy usage.
Definition: nusoap.php:7076
setCurlOption($option, $value)
sets user-specified cURL options
Definition: nusoap.php:7585
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:7659
setHTTPProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='')
set proxy info here
Definition: nusoap.php:7643
getProxy()
dynamically creates an instance of a proxy class, allowing user to directly call methods from wsdl
Definition: nusoap.php:7737
send($msg, $soapaction='', $timeout=0, $response_timeout=30)
send the SOAP message
Definition: nusoap.php:7454
setUseCURL($use)
Set whether to try to use cURL connections if possible.
Definition: nusoap.php:7685
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:7205
getProxyClassCode()
dynamically creates proxy class code
Definition: nusoap.php:7844
checkCookies()
checks all Cookies and delete those which are expired
Definition: nusoap.php:7928
getHTTPContentType()
gets the HTTP content type for the current request.
Definition: nusoap.php:7868
setHTTPEncoding($enc='gzip, deflate')
use HTTP encoding
Definition: nusoap.php:7674
getHeader()
get the SOAP response Header (parsed)
Definition: nusoap.php:7630
decodeUTF8($bool)
Definition: nusoap.php:7891
useHTTPPersistentConnection()
use HTTP persistent connections if possible
Definition: nusoap.php:7695
setCookie($name, $value)
adds a new Cookie into $this->cookies array
Definition: nusoap.php:7904
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current request.
Definition: nusoap.php:7881
getOperationData($operation)
get available data pertaining to an operation
Definition: nusoap.php:7428
getDefaultRpcParams()
gets the default RPC parameter setting.
Definition: nusoap.php:7711
checkWSDL()
check WSDL passed as an instance or pulled from an endpoint
Definition: nusoap.php:7387
setHeaders($headers)
set the SOAP headers
Definition: nusoap.php:7608
loadWSDL()
instantiate wsdl object and parse wsdl file
Definition: nusoap.php:7413
getHTTPBody($soapmsg)
gets the HTTP body for the current request.
Definition: nusoap.php:7856
setDefaultRpcParams($rpcParams)
sets the default RPC parameter setting.
Definition: nusoap.php:7726
setEndpoint($endpoint)
sets the SOAP endpoint, which can override WSDL
Definition: nusoap.php:7597
UpdateCookies($cookies)
updates the current cookies with a new set
Definition: nusoap.php:7961
getHeaders()
get the SOAP response headers (namespace resolution incomplete)
Definition: nusoap.php:7620
_getProxyClassCode($r)
dynamically creates proxy class code
Definition: nusoap.php:7785
getCookies()
gets all Cookies
Definition: nusoap.php:7918
parseResponse($headers, $data)
processes SOAP message returned from server
Definition: nusoap.php:7533
Contains information for a SOAP fault.
Definition: nusoap.php:1008
serialize()
serialize a fault
Definition: nusoap.php:1056
nusoap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:6429
$root_struct_namespace
Definition: nusoap.php:6436
character_data($parser, $data)
element content handler
Definition: nusoap.php:6825
get_soapbody()
get the parsed SOAP Body (NULL if there was none)
Definition: nusoap.php:6861
end_element($parser, $name)
end-element handler
Definition: nusoap.php:6721
getHeaders()
get the unparsed SOAP Header
Definition: nusoap.php:6881
get_response()
get the parsed message (SOAP Body)
Definition: nusoap.php:6851
decodeSimple($value, $type, $typens)
decodes simple types into PHP variables
Definition: nusoap.php:6894
get_soapheader()
get the parsed SOAP Header (NULL if there was none)
Definition: nusoap.php:6871
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:6566
buildVal($pos)
builds response structures for compound values (arrays/structs) and scalars
Definition: nusoap.php:6938
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
Definition: nusoap.php:3438
verify_method($operation, $request)
takes the value that was created by parsing the request and compares to the method's signature,...
Definition: nusoap.php:4210
$methodreturnisliteralxml
Definition: nusoap.php:3547
getHTTPBody($soapmsg)
gets the HTTP body for the current response.
Definition: nusoap.php:4280
invoke_method()
invokes a PHP function for the requested SOAP method
Definition: nusoap.php:3893
add_to_map($methodname, $in, $out)
add a method to the dispatch map (this has been replaced by the register method)
Definition: nusoap.php:4318
getHTTPContentType()
gets the HTTP content type for the current response.
Definition: nusoap.php:4292
parse_request($data='')
parses a request
Definition: nusoap.php:3846
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current response.
Definition: nusoap.php:4305
serialize_return()
serializes the return value from a PHP function into a full SOAP Envelope
Definition: nusoap.php:4039
send_response()
sends an HTTP response
Definition: nusoap.php:4131
fault($faultcode, $faultstring, $faultactor='', $faultdetail='')
Specify a fault to be returned to the client.
Definition: nusoap.php:4405
parse_http_headers()
parses HTTP request headers.
Definition: nusoap.php:3720
service($data)
processes request and returns response
Definition: nusoap.php:3658
parseRequest($headers, $data)
processes SOAP message received from client
Definition: nusoap.php:4229
configureWSDL($serviceName, $namespace=false, $endpoint=false, $style='rpc', $transport='http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace=false)
Sets up wsdl object.
Definition: nusoap.php:4424
parses an XML Schema, allows access to it's data, other utility methods.
Definition: nusoap.php:1096
schemaCharacterData($parser, $data)
element content handler
Definition: nusoap.php:1591
getTypeDef($type)
returns an associative array of information about a given type returns false if no type exists by the...
Definition: nusoap.php:1768
addComplexType($name, $typeClass='complexType', $phpType='array', $compositor='', $restrictionBase='', $elements=array(), $attrs=array(), $arrayType='')
adds a complex type to the schema
Definition: nusoap.php:1952
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:1880
addElement($attrs)
adds an element to the schema
Definition: nusoap.php:2000
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:1735
xdebug($string)
adds debug data to the clas level debug string
Definition: nusoap.php:1719
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array())
adds a simple type to the schema
Definition: nusoap.php:1980
serializeSchema()
serialize the schema
Definition: nusoap.php:1601
parseString($xml, $type)
Definition: nusoap.php:1194
schemaEndElement($parser, $name)
end-element handler
Definition: nusoap.php:1554
schemaStartElement($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:1257
serializeTypeDef($type)
returns a sample serialization of a given type, or false if no type by the given name
Definition: nusoap.php:1844
parseFile($xml, $type)
parse an XML file
Definition: nusoap.php:1168
CreateTypeName($ename)
gets a type name for an unnamed type
Definition: nusoap.php:1241
soap_fault class, allows for creation of faults mainly used for returning faults from deployed functi...
Definition: nusoap.php:669
soap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:4431
soap_server allows the user to create a SOAP server that is capable of receiving messages and returni...
Definition: nusoap.php:2313
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
Definition: nusoap.php:1552
setCurlOption($option, $value)
sets a cURL option
Definition: nusoap.php:2200
getCookiesForRequest($cookies, $secure=false)
sort out cookies for the current request
Definition: nusoap.php:3384
send($data, $timeout=0, $response_timeout=30)
send the SOAP message via HTTP
Definition: nusoap.php:1741
parseCookie($cookie_str)
parse an incoming Cookie into it's parts
Definition: nusoap.php:3320
setURL($url)
sets the URL to which to connect
Definition: nusoap.php:2237
setProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='')
set proxy info here
Definition: nusoap.php:1890
setContentType($type, $charset=false)
Definition: nusoap.php:2284
unsetHeader($name)
unsets an HTTP header
Definition: nusoap.php:2224
sendHTTPS($data, $timeout=0, $response_timeout=30)
send the SOAP message via HTTPS 1.0 using CURL
Definition: nusoap.php:1780
isSkippableCurlHeader(&$data)
Test if the given string starts with a header that is to be skipped.
Definition: nusoap.php:2724
setSOAPAction($soapaction)
set the soapaction value
Definition: nusoap.php:1861
setEncoding($enc='gzip, deflate')
use http encoding
Definition: nusoap.php:1871
connect($connection_timeout=0, $response_timeout=30)
Definition: nusoap.php:1615
setHeader($name, $value)
sets an HTTP header
Definition: nusoap.php:2213
io_method()
gets the I/O method to use
Definition: nusoap.php:2281
decodeChunked($buffer, $lb)
decode a string that is encoded w/ "chunked' transfer encoding as defined in RFC2068 19....
Definition: nusoap.php:1908
setCredentials($username, $password, $authtype='basic', $digestRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:1793
for creating serializable abstractions of native PHP types NOTE: this is only really used when WSDL i...
Definition: nusoap.php:1495
serialize($use='encoded')
return serialized value
Definition: nusoap.php:1522
$element_ns
Definition: nusoap.php:2061
decode()
decodes a soapval object into a PHP native type
Definition: nusoap.php:1533
$attributes
Definition: nusoap.php:2075
parses a WSDL file, allows access to it's data, other utility methods
Definition: nusoap.php:3133
$currentMessage
Definition: nusoap.php:3142
$import
Definition: nusoap.php:3155
$username
Definition: nusoap.php:4553
$ports
Definition: nusoap.php:3148
$proxyhost
Definition: nusoap.php:3162
character_data($parser, $data)
element content handler
Definition: nusoap.php:3624
serializeType($name, $type, $value, $use='encoded', $encodingStyle=false)
serializes a PHP value according a given type definition
Definition: nusoap.php:4020
serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
serializes the attributes for a complexType
Definition: nusoap.php:6097
$opData
Definition: nusoap.php:3150
$currentSchema
Definition: nusoap.php:3138
getBindingData($binding)
Definition: nusoap.php:3635
wsdl($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
Definition: nusoap.php:3181
$currentPortType
Definition: nusoap.php:3145
addElement($attrs)
adds an element to the WSDL types
Definition: nusoap.php:6322
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:3718
$status
Definition: nusoap.php:3151
serialize()
serialize the parsed wsdl
Definition: nusoap.php:3741
getOperations($bindingType='soap')
returns an assoc array of operation names => operation data
Definition: nusoap.php:3649
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:5062
serializeRPCParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
Definition: nusoap.php:3870
$proxypassword
Definition: nusoap.php:3165
$certRequest
Definition: nusoap.php:4556
getOperationData($operation, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:3679
$portTypes
Definition: nusoap.php:3144
$currentOperation
Definition: nusoap.php:3143
$messages
Definition: nusoap.php:3141
serializeParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
Definition: nusoap.php:3945
fetchWSDL($wsdl)
fetches the WSDL document and parses it
Definition: nusoap.php:4592
$password
Definition: nusoap.php:4554
$depth
Definition: nusoap.php:3159
$bindings
Definition: nusoap.php:3146
$wsdl
Definition: nusoap.php:3135
$timeout
Definition: nusoap.php:3166
$endpoint
Definition: nusoap.php:3153
$use_curl
Definition: nusoap.php:4551
$proxyusername
Definition: nusoap.php:3164
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:5148
$documentation
Definition: nusoap.php:3152
webDescription()
prints html description of services
Definition: nusoap.php:5242
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar')
adds an XML Schema simple type to the WSDL types
Definition: nusoap.php:4342
parseWSDL($wsdl='')
parses the wsdl document
Definition: nusoap.php:3290
$message
Definition: nusoap.php:3139
parametersMatchWrapped($type, &$parameters)
determine whether a set of parameters are unwrapped when they are expect to be wrapped,...
Definition: nusoap.php:5527
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:3389
$proxyport
Definition: nusoap.php:3163
$authtype
Definition: nusoap.php:4555
end_element($parser, $name)
end-element handler
Definition: nusoap.php:3597
$parser
Definition: nusoap.php:3157
$depth_array
Definition: nusoap.php:3160
serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false)
serializes the elements for a complexType
Definition: nusoap.php:6159
$position
Definition: nusoap.php:3158
$schemas
Definition: nusoap.php:3137
$currentPort
Definition: nusoap.php:3149
$complexTypes
Definition: nusoap.php:3140
$curl_options
Definition: nusoap.php:4550
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='')
register a service with the server
Definition: nusoap.php:4362
$response_timeout
Definition: nusoap.php:3167
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:4298
$currentBinding
Definition: nusoap.php:3147
if($err=$client->getError()) $namespace
if($format !==null) $name
Definition: metadata.php:230
$i
Definition: metadata.php:24
$xml
Definition: metadata.php:332
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$ret
Definition: parser.php:6
$type
$url
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
$http
Definition: raiseError.php:7
foreach($_POST as $key=> $value) $res
$data
Definition: storeScorm.php:23
$param
Definition: xapitoken.php:31
$cols
Definition: xhr_table.php:11
$rows
Definition: xhr_table.php:10

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

Definition at line 85 of file nusoap.php.