ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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(!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 939 of file nusoap.php.

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

References $h.

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

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

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

Variable Documentation

◆ globalDebugLevel

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

Definition at line 81 of file nusoap.php.