ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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, and $m.

◆ 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}
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81

References $timestamp, date, and sprintf.

◆ 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::__construct();
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 __construct($schema='',$xml='',$namespaces=array()){
1132 parent::__construct();
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 __construct($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
2085 parent::__construct();
2086 $this->name = $name;
2087 $this->type = $type;
2088 $this->value = $value;
2089 $this->element_ns = $element_ns;
2090 $this->type_ns = $type_ns;
2091 $this->attributes = $attributes;
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 __construct($url, $curl_options = NULL, $use_curl = false){
2177 parent::__construct();
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 __construct($wsdl=false){
3592 parent::__construct();
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
4569 parent::__construct();
4570 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4571 $this->proxyhost = $proxyhost;
4572 $this->proxyport = $proxyport;
4573 $this->proxyusername = $proxyusername;
4574 $this->proxypassword = $proxypassword;
4575 $this->timeout = $timeout;
4576 $this->response_timeout = $response_timeout;
4577 if (is_array($curl_options))
4578 $this->curl_options = $curl_options;
4579 $this->use_curl = $use_curl;
4580 $this->fetchWSDL($wsdl);
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 $has_client = isset($_GET['client_id']);
5491 if (count($this->ports) >= 1) {
5492 foreach($this->ports as $pName => $attrs) {
5493 $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
5494 $address = $attrs['location'] . ($debug || $has_client ? "?" : "")
5495 . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&amp;" : "")
5496 . ($has_client ? 'client_id=' . $_GET['client_id'] : '');
5497 $xml .= "\n" . ' <soap:address location="' . $address. '"/>';
5498 $xml .= "\n" . ' </port>';
5499 }
5500 }
5501
5502 $xml .= "\n" . '</service>';
5503 return $xml . "\n</definitions>";
5504 }
5505
5515 function parametersMatchWrapped($type, &$parameters) {
5516 $this->debug("in parametersMatchWrapped type=$type, parameters=");
5517 $this->appendDebug($this->varDump($parameters));
5518
5519 // split type into namespace:unqualified-type
5520 if (strpos($type, ':')) {
5521 $uqType = substr($type, strrpos($type, ':') + 1);
5522 $ns = substr($type, 0, strrpos($type, ':'));
5523 $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5524 if ($this->getNamespaceFromPrefix($ns)) {
5525 $ns = $this->getNamespaceFromPrefix($ns);
5526 $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5527 }
5528 } else {
5529 // TODO: should the type be compared to types in XSD, and the namespace
5530 // set to XSD if the type matches?
5531 $this->debug("in parametersMatchWrapped: No namespace for type $type");
5532 $ns = '';
5533 $uqType = $type;
5534 }
5535
5536 // get the type information
5537 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5538 $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5539 return false;
5540 }
5541 $this->debug("in parametersMatchWrapped: found typeDef=");
5542 $this->appendDebug($this->varDump($typeDef));
5543 if (substr($uqType, -1) == '^') {
5544 $uqType = substr($uqType, 0, -1);
5545 }
5546 $phpType = $typeDef['phpType'];
5547 $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
5548 $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5549
5550 // we expect a complexType or element of complexType
5551 if ($phpType != 'struct') {
5552 $this->debug("in parametersMatchWrapped: not a struct");
5553 return false;
5554 }
5555
5556 // see whether the parameter names match the elements
5557 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
5558 $elements = 0;
5559 $matches = 0;
5560 $change = false;
5561 if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
5562 $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5563 $change = true;
5564 }
5565 foreach ($typeDef['elements'] as $name => $attrs) {
5566 if ($change) {
5567 $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
5568 $parameters[$name] = $parameters[$elements];
5569 unset($parameters[$elements]);
5570 $matches++;
5571 } elseif (isset($parameters[$name])) {
5572 $this->debug("in parametersMatchWrapped: have parameter named $name");
5573 $matches++;
5574 } else {
5575 $this->debug("in parametersMatchWrapped: do not have parameter named $name");
5576 }
5577 $elements++;
5578 }
5579
5580 $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5581 if ($matches == 0) {
5582 return false;
5583 }
5584 return true;
5585 }
5586
5587 // since there are no elements for the type, if the user passed no
5588 // parameters, the parameters match wrapped.
5589 $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
5590 return count($parameters) == 0;
5591 }
5592
5608 function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
5609 $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5610 $this->appendDebug('parameters=' . $this->varDump($parameters));
5611
5612 if ($direction != 'input' && $direction != 'output') {
5613 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5614 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5615 return false;
5616 }
5617 if (!$opData = $this->getOperationData($operation, $bindingType)) {
5618 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5619 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5620 return false;
5621 }
5622 $this->debug('in serializeRPCParameters: opData:');
5623 $this->appendDebug($this->varDump($opData));
5624
5625 // Get encoding style for output and set to current
5626 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5627 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5628 $encodingStyle = $opData['output']['encodingStyle'];
5629 $enc_style = $encodingStyle;
5630 }
5631
5632 // set input params
5633 $xml = '';
5634 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5635 $parts = &$opData[$direction]['parts'];
5636 $part_count = sizeof($parts);
5637 $style = $opData['style'];
5638 $use = $opData[$direction]['use'];
5639 $this->debug("have $part_count part(s) to serialize using $style/$use");
5640 if (is_array($parameters)) {
5641 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5642 $parameter_count = count($parameters);
5643 $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5644 // check for Microsoft-style wrapped parameters
5645 if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
5646 $this->debug('check whether the caller has wrapped the parameters');
5647 if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
5648 $this->debug('check whether caller\'s parameters match the wrapped ones');
5649 if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
5650 $this->debug('wrap the parameters for the caller');
5651 $parameters = array('parameters' => $parameters);
5652 $parameter_count = 1;
5653 }
5654 }
5655 }
5656 foreach ($parts as $name => $type) {
5657 $this->debug("serializing part $name of type $type");
5658 // Track encoding style
5659 if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5660 $encodingStyle = $opData[$direction]['encodingStyle'];
5661 $enc_style = $encodingStyle;
5662 } else {
5663 $enc_style = false;
5664 }
5665 // NOTE: add error handling here
5666 // if serializeType returns false, then catch global error and fault
5667 if ($parametersArrayType == 'arraySimple') {
5668 $p = array_shift($parameters);
5669 $this->debug('calling serializeType w/indexed param');
5670 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5671 } elseif (isset($parameters[$name])) {
5672 $this->debug('calling serializeType w/named param');
5673 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5674 } else {
5675 // TODO: only send nillable
5676 $this->debug('calling serializeType w/null param');
5677 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5678 }
5679 }
5680 } else {
5681 $this->debug('no parameters passed.');
5682 }
5683 }
5684 $this->debug("serializeRPCParameters returning: $xml");
5685 return $xml;
5686 }
5687
5702 function serializeParameters($operation, $direction, $parameters)
5703 {
5704 $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5705 $this->appendDebug('parameters=' . $this->varDump($parameters));
5706
5707 if ($direction != 'input' && $direction != 'output') {
5708 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5709 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5710 return false;
5711 }
5712 if (!$opData = $this->getOperationData($operation)) {
5713 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
5714 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
5715 return false;
5716 }
5717 $this->debug('opData:');
5718 $this->appendDebug($this->varDump($opData));
5719
5720 // Get encoding style for output and set to current
5721 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5722 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5723 $encodingStyle = $opData['output']['encodingStyle'];
5724 $enc_style = $encodingStyle;
5725 }
5726
5727 // set input params
5728 $xml = '';
5729 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5730
5731 $use = $opData[$direction]['use'];
5732 $this->debug("use=$use");
5733 $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
5734 if (is_array($parameters)) {
5735 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5736 $this->debug('have ' . $parametersArrayType . ' parameters');
5737 foreach($opData[$direction]['parts'] as $name => $type) {
5738 $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
5739 // Track encoding style
5740 if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5741 $encodingStyle = $opData[$direction]['encodingStyle'];
5742 $enc_style = $encodingStyle;
5743 } else {
5744 $enc_style = false;
5745 }
5746 // NOTE: add error handling here
5747 // if serializeType returns false, then catch global error and fault
5748 if ($parametersArrayType == 'arraySimple') {
5749 $p = array_shift($parameters);
5750 $this->debug('calling serializeType w/indexed param');
5751 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5752 } elseif (isset($parameters[$name])) {
5753 $this->debug('calling serializeType w/named param');
5754 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5755 } else {
5756 // TODO: only send nillable
5757 $this->debug('calling serializeType w/null param');
5758 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5759 }
5760 }
5761 } else {
5762 $this->debug('no parameters passed.');
5763 }
5764 }
5765 $this->debug("serializeParameters returning: $xml");
5766 return $xml;
5767 }
5768
5781 function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
5782 {
5783 $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
5784 $this->appendDebug("value=" . $this->varDump($value));
5785 if($use == 'encoded' && $encodingStyle) {
5786 $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
5787 }
5788
5789 // if a soapval has been supplied, let its type override the WSDL
5790 if (is_object($value) && get_class($value) == 'soapval') {
5791 if ($value->type_ns) {
5792 $type = $value->type_ns . ':' . $value->type;
5793 $forceType = true;
5794 $this->debug("in serializeType: soapval overrides type to $type");
5795 } elseif ($value->type) {
5796 $type = $value->type;
5797 $forceType = true;
5798 $this->debug("in serializeType: soapval overrides type to $type");
5799 } else {
5800 $forceType = false;
5801 $this->debug("in serializeType: soapval does not override type");
5802 }
5803 $attrs = $value->attributes;
5804 $value = $value->value;
5805 $this->debug("in serializeType: soapval overrides value to $value");
5806 if ($attrs) {
5807 if (!is_array($value)) {
5808 $value['!'] = $value;
5809 }
5810 foreach ($attrs as $n => $v) {
5811 $value['!' . $n] = $v;
5812 }
5813 $this->debug("in serializeType: soapval provides attributes");
5814 }
5815 } else {
5816 $forceType = false;
5817 }
5818
5819 $xml = '';
5820 if (strpos($type, ':')) {
5821 $uqType = substr($type, strrpos($type, ':') + 1);
5822 $ns = substr($type, 0, strrpos($type, ':'));
5823 $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
5824 if ($this->getNamespaceFromPrefix($ns)) {
5825 $ns = $this->getNamespaceFromPrefix($ns);
5826 $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
5827 }
5828
5829 if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
5830 $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5831 if ($unqualified && $use == 'literal') {
5832 $elementNS = " xmlns=\"\"";
5833 } else {
5834 $elementNS = '';
5835 }
5836 if (is_null($value)) {
5837 if ($use == 'literal') {
5838 // TODO: depends on minOccurs
5839 $xml = "<$name$elementNS/>";
5840 } else {
5841 // TODO: depends on nillable, which should be checked before calling this method
5842 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5843 }
5844 $this->debug("in serializeType: returning: $xml");
5845 return $xml;
5846 }
5847 if ($uqType == 'Array') {
5848 // JBoss/Axis does this sometimes
5849 return $this->serialize_val($value, $name, false, false, false, false, $use);
5850 }
5851 if ($uqType == 'boolean') {
5852 if ((is_string($value) && $value == 'false') || (! $value)) {
5853 $value = 'false';
5854 } else {
5855 $value = 'true';
5856 }
5857 }
5858 if ($uqType == 'string' && gettype($value) == 'string') {
5859 $value = $this->expandEntities($value);
5860 }
5861 if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
5862 $value = sprintf("%.0lf", $value);
5863 }
5864 // it's a scalar
5865 // TODO: what about null/nil values?
5866 // check type isn't a custom type extending xmlschema namespace
5867 if (!$this->getTypeDef($uqType, $ns)) {
5868 if ($use == 'literal') {
5869 if ($forceType) {
5870 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
5871 } else {
5872 $xml = "<$name$elementNS>$value</$name>";
5873 }
5874 } else {
5875 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
5876 }
5877 $this->debug("in serializeType: returning: $xml");
5878 return $xml;
5879 }
5880 $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5881 } else if ($ns == 'http://xml.apache.org/xml-soap') {
5882 $this->debug('in serializeType: appears to be Apache SOAP type');
5883 if ($uqType == 'Map') {
5884 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5885 if (! $tt_prefix) {
5886 $this->debug('in serializeType: Add namespace for Apache SOAP type');
5887 $tt_prefix = 'ns' . rand(1000, 9999);
5888 $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
5889 // force this to be added to usedNamespaces
5890 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5891 }
5892 $contents = '';
5893 foreach($value as $k => $v) {
5894 $this->debug("serializing map element: key $k, value $v");
5895 $contents .= '<item>';
5896 $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
5897 $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
5898 $contents .= '</item>';
5899 }
5900 if ($use == 'literal') {
5901 if ($forceType) {
5902 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
5903 } else {
5904 $xml = "<$name>$contents</$name>";
5905 }
5906 } else {
5907 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
5908 }
5909 $this->debug("in serializeType: returning: $xml");
5910 return $xml;
5911 }
5912 $this->debug('in serializeType: Apache SOAP type, but only support Map');
5913 }
5914 } else {
5915 // TODO: should the type be compared to types in XSD, and the namespace
5916 // set to XSD if the type matches?
5917 $this->debug("in serializeType: No namespace for type $type");
5918 $ns = '';
5919 $uqType = $type;
5920 }
5921 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5922 $this->setError("$type ($uqType) is not a supported type.");
5923 $this->debug("in serializeType: $type ($uqType) is not a supported type.");
5924 return false;
5925 } else {
5926 $this->debug("in serializeType: found typeDef");
5927 $this->appendDebug('typeDef=' . $this->varDump($typeDef));
5928 if (substr($uqType, -1) == '^') {
5929 $uqType = substr($uqType, 0, -1);
5930 }
5931 }
5932 $phpType = $typeDef['phpType'];
5933 $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
5934 // if php type == struct, map value to the <all> element names
5935 if ($phpType == 'struct') {
5936 if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
5937 $elementName = $uqType;
5938 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5939 $elementNS = " xmlns=\"$ns\"";
5940 } else {
5941 $elementNS = " xmlns=\"\"";
5942 }
5943 } else {
5944 $elementName = $name;
5945 if ($unqualified) {
5946 $elementNS = " xmlns=\"\"";
5947 } else {
5948 $elementNS = '';
5949 }
5950 }
5951 if (is_null($value)) {
5952 if ($use == 'literal') {
5953 // TODO: depends on minOccurs
5954 $xml = "<$elementName$elementNS/>";
5955 } else {
5956 $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5957 }
5958 $this->debug("in serializeType: returning: $xml");
5959 return $xml;
5960 }
5961 if (is_object($value)) {
5962 $value = get_object_vars($value);
5963 }
5964 if (is_array($value)) {
5965 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5966 if ($use == 'literal') {
5967 if ($forceType) {
5968 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
5969 } else {
5970 $xml = "<$elementName$elementNS$elementAttrs>";
5971 }
5972 } else {
5973 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
5974 }
5975
5976 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5977 $xml .= "</$elementName>";
5978 } else {
5979 $this->debug("in serializeType: phpType is struct, but value is not an array");
5980 $this->setError("phpType is struct, but value is not an array: see debug output for details");
5981 $xml = '';
5982 }
5983 } elseif ($phpType == 'array') {
5984 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5985 $elementNS = " xmlns=\"$ns\"";
5986 } else {
5987 if ($unqualified) {
5988 $elementNS = " xmlns=\"\"";
5989 } else {
5990 $elementNS = '';
5991 }
5992 }
5993 if (is_null($value)) {
5994 if ($use == 'literal') {
5995 // TODO: depends on minOccurs
5996 $xml = "<$name$elementNS/>";
5997 } else {
5998 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
5999 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6000 ":Array\" " .
6001 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6002 ':arrayType="' .
6003 $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
6004 ':' .
6005 $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
6006 }
6007 $this->debug("in serializeType: returning: $xml");
6008 return $xml;
6009 }
6010 if (isset($typeDef['multidimensional'])) {
6011 $nv = array();
6012 foreach($value as $v) {
6013 $cols = ',' . sizeof($v);
6014 $nv = array_merge($nv, $v);
6015 }
6016 $value = $nv;
6017 } else {
6018 $cols = '';
6019 }
6020 if (is_array($value) && sizeof($value) >= 1) {
6021 $rows = sizeof($value);
6022 $contents = '';
6023 foreach($value as $k => $v) {
6024 $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
6025 //if (strpos($typeDef['arrayType'], ':') ) {
6026 if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
6027 $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
6028 } else {
6029 $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
6030 }
6031 }
6032 } else {
6033 $rows = 0;
6034 $contents = null;
6035 }
6036 // TODO: for now, an empty value will be serialized as a zero element
6037 // array. Revisit this when coding the handling of null/nil values.
6038 if ($use == 'literal') {
6039 $xml = "<$name$elementNS>"
6040 .$contents
6041 ."</$name>";
6042 } else {
6043 $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
6044 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
6045 .':arrayType="'
6046 .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
6047 .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
6048 .$contents
6049 ."</$name>";
6050 }
6051 } elseif ($phpType == 'scalar') {
6052 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6053 $elementNS = " xmlns=\"$ns\"";
6054 } else {
6055 if ($unqualified) {
6056 $elementNS = " xmlns=\"\"";
6057 } else {
6058 $elementNS = '';
6059 }
6060 }
6061 if ($use == 'literal') {
6062 if ($forceType) {
6063 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
6064 } else {
6065 $xml = "<$name$elementNS>$value</$name>";
6066 }
6067 } else {
6068 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
6069 }
6070 }
6071 $this->debug("in serializeType: returning: $xml");
6072 return $xml;
6073 }
6074
6085 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6086 $xml = '';
6087 if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
6088 $this->debug("serialize attributes for XML Schema type $ns:$uqType");
6089 if (is_array($value)) {
6090 $xvalue = $value;
6091 } elseif (is_object($value)) {
6092 $xvalue = get_object_vars($value);
6093 } else {
6094 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6095 $xvalue = array();
6096 }
6097 foreach ($typeDef['attrs'] as $aName => $attrs) {
6098 if (isset($xvalue['!' . $aName])) {
6099 $xname = '!' . $aName;
6100 $this->debug("value provided for attribute $aName with key $xname");
6101 } elseif (isset($xvalue[$aName])) {
6102 $xname = $aName;
6103 $this->debug("value provided for attribute $aName with key $xname");
6104 } elseif (isset($attrs['default'])) {
6105 $xname = '!' . $aName;
6106 $xvalue[$xname] = $attrs['default'];
6107 $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
6108 } else {
6109 $xname = '';
6110 $this->debug("no value provided for attribute $aName");
6111 }
6112 if ($xname) {
6113 $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
6114 }
6115 }
6116 } else {
6117 $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
6118 }
6119 if (isset($typeDef['extensionBase'])) {
6120 $ns = $this->getPrefix($typeDef['extensionBase']);
6121 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6122 if ($this->getNamespaceFromPrefix($ns)) {
6123 $ns = $this->getNamespaceFromPrefix($ns);
6124 }
6125 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6126 $this->debug("serialize attributes for extension base $ns:$uqType");
6127 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6128 } else {
6129 $this->debug("extension base $ns:$uqType is not a supported type");
6130 }
6131 }
6132 return $xml;
6133 }
6134
6147 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
6148 $xml = '';
6149 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
6150 $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6151 if (is_array($value)) {
6152 $xvalue = $value;
6153 } elseif (is_object($value)) {
6154 $xvalue = get_object_vars($value);
6155 } else {
6156 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6157 $xvalue = array();
6158 }
6159 // toggle whether all elements are present - ideally should validate against schema
6160 if (count($typeDef['elements']) != count($xvalue)){
6161 $optionals = true;
6162 }
6163 foreach ($typeDef['elements'] as $eName => $attrs) {
6164 if (!isset($xvalue[$eName])) {
6165 if (isset($attrs['default'])) {
6166 $xvalue[$eName] = $attrs['default'];
6167 $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
6168 }
6169 }
6170 // if user took advantage of a minOccurs=0, then only serialize named parameters
6171 if (isset($optionals)
6172 && (!isset($xvalue[$eName]))
6173 && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
6174 ){
6175 if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
6176 $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
6177 }
6178 // do nothing
6179 $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6180 } else {
6181 // get value
6182 if (isset($xvalue[$eName])) {
6183 $v = $xvalue[$eName];
6184 } else {
6185 $v = null;
6186 }
6187 if (isset($attrs['form'])) {
6188 $unqualified = ($attrs['form'] == 'unqualified');
6189 } else {
6190 $unqualified = false;
6191 }
6192 if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
6193 $vv = $v;
6194 foreach ($vv as $k => $v) {
6195 if (isset($attrs['type']) || isset($attrs['ref'])) {
6196 // serialize schema-defined type
6197 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6198 } else {
6199 // serialize generic type (can this ever really happen?)
6200 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6201 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6202 }
6203 }
6204 } else {
6205 if (isset($attrs['type']) || isset($attrs['ref'])) {
6206 // serialize schema-defined type
6207 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6208 } else {
6209 // serialize generic type (can this ever really happen?)
6210 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6211 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6212 }
6213 }
6214 }
6215 }
6216 } else {
6217 $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
6218 }
6219 if (isset($typeDef['extensionBase'])) {
6220 $ns = $this->getPrefix($typeDef['extensionBase']);
6221 $uqType = $this->getLocalPart($typeDef['extensionBase']);
6222 if ($this->getNamespaceFromPrefix($ns)) {
6223 $ns = $this->getNamespaceFromPrefix($ns);
6224 }
6225 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6226 $this->debug("serialize elements for extension base $ns:$uqType");
6227 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6228 } else {
6229 $this->debug("extension base $ns:$uqType is not a supported type");
6230 }
6231 }
6232 return $xml;
6233 }
6234
6249 function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
6250 if (count($elements) > 0) {
6251 $eElements = array();
6252 foreach($elements as $n => $e){
6253 // expand each element
6254 $ee = array();
6255 foreach ($e as $k => $v) {
6256 $k = strpos($k,':') ? $this->expandQname($k) : $k;
6257 $v = strpos($v,':') ? $this->expandQname($v) : $v;
6258 $ee[$k] = $v;
6259 }
6260 $eElements[$n] = $ee;
6261 }
6262 $elements = $eElements;
6263 }
6264
6265 if (count($attrs) > 0) {
6266 foreach($attrs as $n => $a){
6267 // expand each attribute
6268 foreach ($a as $k => $v) {
6269 $k = strpos($k,':') ? $this->expandQname($k) : $k;
6270 $v = strpos($v,':') ? $this->expandQname($v) : $v;
6271 $aa[$k] = $v;
6272 }
6273 $eAttrs[$n] = $aa;
6274 }
6275 $attrs = $eAttrs;
6276 }
6277
6278 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6279 $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
6280
6281 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6282 $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6283 }
6284
6296 function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
6297 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6298
6299 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6300 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6301 }
6302
6310 function addElement($attrs) {
6311 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6312 $this->schemas[$typens][0]->addElement($attrs);
6313 }
6314
6329 function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
6330 if ($use == 'encoded' && $encodingStyle == '') {
6331 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
6332 }
6333
6334 if ($style == 'document') {
6335 $elements = array();
6336 foreach ($in as $n => $t) {
6337 $elements[$n] = array('name' => $n, 'type' => $t);
6338 }
6339 $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
6340 $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
6341 $in = array('parameters' => 'tns:' . $name . '^');
6342
6343 $elements = array();
6344 foreach ($out as $n => $t) {
6345 $elements[$n] = array('name' => $n, 'type' => $t);
6346 }
6347 $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
6348 $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
6349 $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
6350 }
6351
6352 // get binding
6353 $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
6354 array(
6355 'name' => $name,
6356 'binding' => $this->serviceName . 'Binding',
6357 'endpoint' => $this->endpoint,
6358 'soapAction' => $soapaction,
6359 'style' => $style,
6360 'input' => array(
6361 'use' => $use,
6362 'namespace' => $namespace,
6363 'encodingStyle' => $encodingStyle,
6364 'message' => $name . 'Request',
6365 'parts' => $in),
6366 'output' => array(
6367 'use' => $use,
6368 'namespace' => $namespace,
6369 'encodingStyle' => $encodingStyle,
6370 'message' => $name . 'Response',
6371 'parts' => $out),
6372 'namespace' => $namespace,
6373 'transport' => 'http://schemas.xmlsoap.org/soap/http',
6374 'documentation' => $documentation);
6375 // add portTypes
6376 // add messages
6377 if($in)
6378 {
6379 foreach($in as $pName => $pType)
6380 {
6381 if(strpos($pType,':')) {
6382 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6383 }
6384 $this->messages[$name.'Request'][$pName] = $pType;
6385 }
6386 } else {
6387 $this->messages[$name.'Request']= '0';
6388 }
6389 if($out)
6390 {
6391 foreach($out as $pName => $pType)
6392 {
6393 if(strpos($pType,':')) {
6394 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6395 }
6396 $this->messages[$name.'Response'][$pName] = $pType;
6397 }
6398 } else {
6399 $this->messages[$name.'Response']= '0';
6400 }
6401 return true;
6402 }
6403}
6404?><?php
6405
6406
6407
6417class nusoap_parser extends nusoap_base {
6418
6419 var $xml = '';
6420 var $xml_encoding = '';
6421 var $method = '';
6422 var $root_struct = '';
6423 var $root_struct_name = '';
6424 var $root_struct_namespace = '';
6425 var $root_header = '';
6426 var $document = ''; // incoming SOAP body (text)
6427 // determines where in the message we are (envelope,header,body,method)
6428 var $status = '';
6429 var $position = 0;
6430 var $depth = 0;
6431 var $default_namespace = '';
6432 var $namespaces = array();
6433 var $message = array();
6434 var $parent = '';
6435 var $fault = false;
6436 var $fault_code = '';
6437 var $fault_str = '';
6438 var $fault_detail = '';
6439 var $depth_array = array();
6440 var $debug_flag = true;
6441 var $soapresponse = NULL; // parsed SOAP Body
6442 var $soapheader = NULL; // parsed SOAP Header
6443 var $responseHeaders = ''; // incoming SOAP headers (text)
6444 var $body_position = 0;
6445 // for multiref parsing:
6446 // array of id => pos
6447 var $ids = array();
6448 // array of id => hrefs => pos
6449 var $multirefs = array();
6450 // toggle for auto-decoding element content
6451 var $decode_utf8 = true;
6452
6462 function __construct($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
6463 parent::__construct();
6464 $this->xml = $xml;
6465 $this->xml_encoding = $encoding;
6466 $this->method = $method;
6467 $this->decode_utf8 = $decode_utf8;
6468
6469 // Check whether content has been read.
6470 if(!empty($xml)){
6471 // Check XML encoding
6472 $pos_xml = strpos($xml, '<?xml');
6473 if ($pos_xml !== FALSE) {
6474 $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
6475 if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
6476 $xml_encoding = $res[1];
6477 if (strtoupper($xml_encoding) != $encoding) {
6478 $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
6479 $this->debug($err);
6480 if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
6481 $this->setError($err);
6482 return;
6483 }
6484 // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
6485 } else {
6486 $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
6487 }
6488 } else {
6489 $this->debug('No encoding specified in XML declaration');
6490 }
6491 } else {
6492 $this->debug('No XML declaration');
6493 }
6494 $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
6495 // Create an XML parser - why not xml_parser_create_ns?
6496 $this->parser = xml_parser_create($this->xml_encoding);
6497 // Set the options for parsing the XML data.
6498 //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
6499 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6500 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6501 // Set the object for the parser.
6502 xml_set_object($this->parser, $this);
6503 // Set the element handlers for the parser.
6504 xml_set_element_handler($this->parser, 'start_element','end_element');
6505 xml_set_character_data_handler($this->parser,'character_data');
6506
6507 // Parse the XML file.
6508 if(!xml_parse($this->parser,$xml,true)){
6509 // Display an error message.
6510 $err = sprintf('XML error parsing SOAP payload on line %d: %s',
6511 xml_get_current_line_number($this->parser),
6512 xml_error_string(xml_get_error_code($this->parser)));
6513 $this->debug($err);
6514 $this->debug("XML payload:\n" . $xml);
6515 $this->setError($err);
6516 } else {
6517 $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
6518 // get final value
6519 $this->soapresponse = $this->message[$this->root_struct]['result'];
6520 // get header value
6521 if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
6522 $this->soapheader = $this->message[$this->root_header]['result'];
6523 }
6524 // resolve hrefs/ids
6525 if(sizeof($this->multirefs) > 0){
6526 foreach($this->multirefs as $id => $hrefs){
6527 $this->debug('resolving multirefs for id: '.$id);
6528 $idVal = $this->buildVal($this->ids[$id]);
6529 if (is_array($idVal) && isset($idVal['!id'])) {
6530 unset($idVal['!id']);
6531 }
6532 foreach($hrefs as $refPos => $ref){
6533 $this->debug('resolving href at pos '.$refPos);
6534 $this->multirefs[$id][$refPos] = $idVal;
6535 }
6536 }
6537 }
6538 }
6539 xml_parser_free($this->parser);
6540 } else {
6541 $this->debug('xml was empty, didn\'t parse!');
6542 $this->setError('xml was empty, didn\'t parse!');
6543 }
6544 }
6545
6554 function start_element($parser, $name, $attrs) {
6555 // position in a total number of elements, starting from 0
6556 // update class level pos
6557 $pos = $this->position++;
6558 // and set mine
6559 $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
6560 // depth = how many levels removed from root?
6561 // set mine as current global depth and increment global depth value
6562 $this->message[$pos]['depth'] = $this->depth++;
6563
6564 // else add self as child to whoever the current parent is
6565 if($pos != 0){
6566 $this->message[$this->parent]['children'] .= '|'.$pos;
6567 }
6568 // set my parent
6569 $this->message[$pos]['parent'] = $this->parent;
6570 // set self as current parent
6571 $this->parent = $pos;
6572 // set self as current value for this depth
6573 $this->depth_array[$this->depth] = $pos;
6574 // get element prefix
6575 if(strpos($name,':')){
6576 // get ns prefix
6577 $prefix = substr($name,0,strpos($name,':'));
6578 // get unqualified name
6579 $name = substr(strstr($name,':'),1);
6580 }
6581 // set status
6582 if($name == 'Envelope'){
6583 $this->status = 'envelope';
6584 } elseif($name == 'Header' && $this->status = 'envelope'){
6585 $this->root_header = $pos;
6586 $this->status = 'header';
6587 } elseif($name == 'Body' && $this->status = 'envelope'){
6588 $this->status = 'body';
6589 $this->body_position = $pos;
6590 // set method
6591 } elseif($this->status == 'body' && $pos == ($this->body_position+1)){
6592 $this->status = 'method';
6593 $this->root_struct_name = $name;
6594 $this->root_struct = $pos;
6595 $this->message[$pos]['type'] = 'struct';
6596 $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
6597 }
6598 // set my status
6599 $this->message[$pos]['status'] = $this->status;
6600 // set name
6601 $this->message[$pos]['name'] = htmlspecialchars($name);
6602 // set attrs
6603 $this->message[$pos]['attrs'] = $attrs;
6604
6605 // loop through atts, logging ns and type declarations
6606 $attstr = '';
6607 foreach($attrs as $key => $value){
6608 $key_prefix = $this->getPrefix($key);
6609 $key_localpart = $this->getLocalPart($key);
6610 // if ns declarations, add to class level array of valid namespaces
6611 if($key_prefix == 'xmlns'){
6612 if(preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6613 $this->XMLSchemaVersion = $value;
6614 $this->namespaces['xsd'] = $this->XMLSchemaVersion;
6615 $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
6616 }
6617 $this->namespaces[$key_localpart] = $value;
6618 // set method namespace
6619 if($name == $this->root_struct_name){
6620 $this->methodNamespace = $value;
6621 }
6622 // if it's a type declaration, set type
6623 } elseif($key_localpart == 'type'){
6624 if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
6625 // do nothing: already processed arrayType
6626 } else {
6627 $value_prefix = $this->getPrefix($value);
6628 $value_localpart = $this->getLocalPart($value);
6629 $this->message[$pos]['type'] = $value_localpart;
6630 $this->message[$pos]['typePrefix'] = $value_prefix;
6631 if(isset($this->namespaces[$value_prefix])){
6632 $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
6633 } else if(isset($attrs['xmlns:'.$value_prefix])) {
6634 $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
6635 }
6636 // should do something here with the namespace of specified type?
6637 }
6638 } elseif($key_localpart == 'arrayType'){
6639 $this->message[$pos]['type'] = 'array';
6640 /* do arrayType ereg here
6641 [1] arrayTypeValue ::= atype asize
6642 [2] atype ::= QName rank*
6643 [3] rank ::= '[' (',')* ']'
6644 [4] asize ::= '[' length~ ']'
6645 [5] length ::= nextDimension* Digit+
6646 [6] nextDimension ::= Digit+ ','
6647 */
6648 $expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6649 if(preg_match($expr,$value,$regs)){
6650 $this->message[$pos]['typePrefix'] = $regs[1];
6651 $this->message[$pos]['arrayTypePrefix'] = $regs[1];
6652 if (isset($this->namespaces[$regs[1]])) {
6653 $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6654 } else if (isset($attrs['xmlns:'.$regs[1]])) {
6655 $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
6656 }
6657 $this->message[$pos]['arrayType'] = $regs[2];
6658 $this->message[$pos]['arraySize'] = $regs[3];
6659 $this->message[$pos]['arrayCols'] = $regs[4];
6660 }
6661 // specifies nil value (or not)
6662 } elseif ($key_localpart == 'nil'){
6663 $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
6664 // some other attribute
6665 } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
6666 $this->message[$pos]['xattrs']['!' . $key] = $value;
6667 }
6668
6669 if ($key == 'xmlns') {
6670 $this->default_namespace = $value;
6671 }
6672 // log id
6673 if($key == 'id'){
6674 $this->ids[$value] = $pos;
6675 }
6676 // root
6677 if($key_localpart == 'root' && $value == 1){
6678 $this->status = 'method';
6679 $this->root_struct_name = $name;
6680 $this->root_struct = $pos;
6681 $this->debug("found root struct $this->root_struct_name, pos $pos");
6682 }
6683 // for doclit
6684 $attstr .= " $key=\"$value\"";
6685 }
6686 // get namespace - must be done after namespace atts are processed
6687 if(isset($prefix)){
6688 $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
6689 $this->default_namespace = $this->namespaces[$prefix];
6690 } else {
6691 $this->message[$pos]['namespace'] = $this->default_namespace;
6692 }
6693 if($this->status == 'header'){
6694 if ($this->root_header != $pos) {
6695 $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6696 }
6697 } elseif($this->root_struct_name != ''){
6698 $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6699 }
6700 }
6701
6709 function end_element($parser, $name) {
6710 // position of current element is equal to the last value left in depth_array for my depth
6711 $pos = $this->depth_array[$this->depth--];
6712
6713 // get element prefix
6714 if(strpos($name,':')){
6715 // get ns prefix
6716 $prefix = substr($name,0,strpos($name,':'));
6717 // get unqualified name
6718 $name = substr(strstr($name,':'),1);
6719 }
6720
6721 // build to native type
6722 if(isset($this->body_position) && $pos > $this->body_position){
6723 // deal w/ multirefs
6724 if(isset($this->message[$pos]['attrs']['href'])){
6725 // get id
6726 $id = substr($this->message[$pos]['attrs']['href'],1);
6727 // add placeholder to href array
6728 $this->multirefs[$id][$pos] = 'placeholder';
6729 // add set a reference to it as the result value
6730 $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
6731 // build complexType values
6732 } elseif($this->message[$pos]['children'] != ''){
6733 // if result has already been generated (struct/array)
6734 if(!isset($this->message[$pos]['result'])){
6735 $this->message[$pos]['result'] = $this->buildVal($pos);
6736 }
6737 // build complexType values of attributes and possibly simpleContent
6738 } elseif (isset($this->message[$pos]['xattrs'])) {
6739 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6740 $this->message[$pos]['xattrs']['!'] = null;
6741 } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6742 if (isset($this->message[$pos]['type'])) {
6743 $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'] : '');
6744 } else {
6745 $parent = $this->message[$pos]['parent'];
6746 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6747 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6748 } else {
6749 $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
6750 }
6751 }
6752 }
6753 $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
6754 // set value of simpleType (or nil complexType)
6755 } else {
6756 //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
6757 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6758 $this->message[$pos]['xattrs']['!'] = null;
6759 } elseif (isset($this->message[$pos]['type'])) {
6760 $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'] : '');
6761 } else {
6762 $parent = $this->message[$pos]['parent'];
6763 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6764 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6765 } else {
6766 $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
6767 }
6768 }
6769
6770 /* add value to parent's result, if parent is struct/array
6771 $parent = $this->message[$pos]['parent'];
6772 if($this->message[$parent]['type'] != 'map'){
6773 if(strtolower($this->message[$parent]['type']) == 'array'){
6774 $this->message[$parent]['result'][] = $this->message[$pos]['result'];
6775 } else {
6776 $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
6777 }
6778 }
6779 */
6780 }
6781 }
6782
6783 // for doclit
6784 if($this->status == 'header'){
6785 if ($this->root_header != $pos) {
6786 $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6787 }
6788 } elseif($pos >= $this->root_struct){
6789 $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6790 }
6791 // switch status
6792 if($pos == $this->root_struct){
6793 $this->status = 'body';
6794 $this->root_struct_namespace = $this->message[$pos]['namespace'];
6795 } elseif($name == 'Body'){
6796 $this->status = 'envelope';
6797 } elseif($name == 'Header'){
6798 $this->status = 'envelope';
6799 } elseif($name == 'Envelope'){
6800 //
6801 }
6802 // set parent back to my parent
6803 $this->parent = $this->message[$pos]['parent'];
6804 }
6805
6813 function character_data($parser, $data){
6814 $pos = $this->depth_array[$this->depth];
6815 if ($this->xml_encoding=='UTF-8'){
6816 // TODO: add an option to disable this for folks who want
6817 // raw UTF-8 that, e.g., might not map to iso-8859-1
6818 // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
6819 if($this->decode_utf8){
6820 $data = utf8_decode($data);
6821 }
6822 }
6823 $this->message[$pos]['cdata'] .= $data;
6824 // for doclit
6825 if($this->status == 'header'){
6826 $this->responseHeaders .= $data;
6827 } else {
6828 $this->document .= $data;
6829 }
6830 }
6831
6839 function get_response(){
6840 return $this->soapresponse;
6841 }
6842
6849 function get_soapbody(){
6850 return $this->soapresponse;
6851 }
6852
6859 function get_soapheader(){
6860 return $this->soapheader;
6861 }
6862
6869 function getHeaders(){
6871 }
6872
6882 function decodeSimple($value, $type, $typens) {
6883 // TODO: use the namespace!
6884 if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
6885 return (string) $value;
6886 }
6887 if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
6888 return (int) $value;
6889 }
6890 if ($type == 'float' || $type == 'double' || $type == 'decimal') {
6891 return (double) $value;
6892 }
6893 if ($type == 'boolean') {
6894 if (strtolower($value) == 'false' || strtolower($value) == 'f') {
6895 return false;
6896 }
6897 return (boolean) $value;
6898 }
6899 if ($type == 'base64' || $type == 'base64Binary') {
6900 $this->debug('Decode base64 value');
6901 return base64_decode($value);
6902 }
6903 // obscure numeric types
6904 if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
6905 || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
6906 || $type == 'unsignedInt'
6907 || $type == 'unsignedShort' || $type == 'unsignedByte') {
6908 return (int) $value;
6909 }
6910 // bogus: parser treats array with no elements as a simple type
6911 if ($type == 'array') {
6912 return array();
6913 }
6914 // everything else
6915 return (string) $value;
6916 }
6917
6926 function buildVal($pos){
6927 if(!isset($this->message[$pos]['type'])){
6928 $this->message[$pos]['type'] = '';
6929 }
6930 $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
6931 // if there are children...
6932 if($this->message[$pos]['children'] != ''){
6933 $this->debug('in buildVal, there are children');
6934 $children = explode('|',$this->message[$pos]['children']);
6935 array_shift($children); // knock off empty
6936 // md array
6937 if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
6938 $r=0; // rowcount
6939 $c=0; // colcount
6940 foreach($children as $child_pos){
6941 $this->debug("in buildVal, got an MD array element: $r, $c");
6942 $params[$r][] = $this->message[$child_pos]['result'];
6943 $c++;
6944 if($c == $this->message[$pos]['arrayCols']){
6945 $c = 0;
6946 $r++;
6947 }
6948 }
6949 // array
6950 } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
6951 $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
6952 foreach($children as $child_pos){
6953 $params[] = &$this->message[$child_pos]['result'];
6954 }
6955 // apache Map type: java hashtable
6956 } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
6957 $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
6958 foreach($children as $child_pos){
6959 $kv = explode("|",$this->message[$child_pos]['children']);
6960 $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
6961 }
6962 // generic compound type
6963 //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
6964 } else {
6965 // Apache Vector type: treat as an array
6966 $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
6967 if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
6968 $notstruct = 1;
6969 } else {
6970 $notstruct = 0;
6971 }
6972 //
6973 foreach($children as $child_pos){
6974 if($notstruct){
6975 $params[] = &$this->message[$child_pos]['result'];
6976 } else {
6977 if (isset($params[$this->message[$child_pos]['name']])) {
6978 // de-serialize repeated element name into an array
6979 if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
6980 $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
6981 }
6982 $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
6983 } else {
6984 $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
6985 }
6986 }
6987 }
6988 }
6989 if (isset($this->message[$pos]['xattrs'])) {
6990 $this->debug('in buildVal, handling attributes');
6991 foreach ($this->message[$pos]['xattrs'] as $n => $v) {
6992 $params[$n] = $v;
6993 }
6994 }
6995 // handle simpleContent
6996 if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6997 $this->debug('in buildVal, handling simpleContent');
6998 if (isset($this->message[$pos]['type'])) {
6999 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7000 } else {
7001 $parent = $this->message[$pos]['parent'];
7002 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7003 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7004 } else {
7005 $params['!'] = $this->message[$pos]['cdata'];
7006 }
7007 }
7008 }
7009 $ret = is_array($params) ? $params : array();
7010 $this->debug('in buildVal, return:');
7011 $this->appendDebug($this->varDump($ret));
7012 return $ret;
7013 } else {
7014 $this->debug('in buildVal, no children, building scalar');
7015 $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
7016 if (isset($this->message[$pos]['type'])) {
7017 $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7018 $this->debug("in buildVal, return: $ret");
7019 return $ret;
7020 }
7021 $parent = $this->message[$pos]['parent'];
7022 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7023 $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7024 $this->debug("in buildVal, return: $ret");
7025 return $ret;
7026 }
7027 $ret = $this->message[$pos]['cdata'];
7028 $this->debug("in buildVal, return: $ret");
7029 return $ret;
7030 }
7031 }
7032}
7033
7037class soap_parser extends nusoap_parser {
7038}
7039
7040?><?php
7041
7042
7043
7064class nusoap_client extends nusoap_base {
7065
7066 var $username = ''; // Username for HTTP authentication
7067 var $password = ''; // Password for HTTP authentication
7068 var $authtype = ''; // Type of HTTP authentication
7069 var $certRequest = array(); // Certificate for HTTP SSL authentication
7070 var $requestHeaders = false; // SOAP headers in request (text)
7071 var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
7072 var $responseHeader = NULL; // SOAP Header from response (parsed)
7073 var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
7074 var $endpoint;
7075 var $forceEndpoint = ''; // overrides WSDL endpoint
7076 var $proxyhost = '';
7077 var $proxyport = '';
7078 var $proxyusername = '';
7079 var $proxypassword = '';
7080 var $xml_encoding = ''; // character set encoding of incoming (response) messages
7081 var $http_encoding = false;
7082 var $timeout = 0; // HTTP connection timeout
7083 var $response_timeout = 30; // HTTP response timeout
7084 var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
7085 var $persistentConnection = false;
7086 var $defaultRpcParams = false; // This is no longer used
7087 var $request = ''; // HTTP request
7088 var $response = ''; // HTTP response
7089 var $responseData = ''; // SOAP payload of response
7090 var $cookies = array(); // Cookies from response or for request
7091 var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
7092 var $operations = array(); // WSDL operations, empty for WSDL initialization error
7093 var $curl_options = array(); // User-specified cURL options
7094 var $bindingType = ''; // WSDL operation binding type
7095 var $use_curl = false; // whether to always try to use cURL
7096
7097 /*
7098 * fault related variables
7099 */
7104 var $fault;
7109 var $faultcode;
7114 var $faultstring;
7119 var $faultdetail;
7120
7135 function __construct($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
7136 parent::__construct();
7137 $this->endpoint = $endpoint;
7138 $this->proxyhost = $proxyhost;
7139 $this->proxyport = $proxyport;
7140 $this->proxyusername = $proxyusername;
7141 $this->proxypassword = $proxypassword;
7142 $this->timeout = $timeout;
7143 $this->response_timeout = $response_timeout;
7144
7145 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7146 $this->appendDebug('endpoint=' . $this->varDump($endpoint));
7147
7148 // make values
7149 if($wsdl){
7150 if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
7151 $this->wsdl = $endpoint;
7152 $this->endpoint = $this->wsdl->wsdl;
7153 $this->wsdlFile = $this->endpoint;
7154 $this->debug('existing wsdl instance created from ' . $this->endpoint);
7155 $this->checkWSDL();
7156 } else {
7157 $this->wsdlFile = $this->endpoint;
7158 $this->wsdl = null;
7159 $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
7160 }
7161 $this->endpointType = 'wsdl';
7162 } else {
7163 $this->debug("instantiate SOAP with endpoint at $endpoint");
7164 $this->endpointType = 'soap';
7165 }
7166 }
7167
7193 function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
7194 $this->operation = $operation;
7195 $this->fault = false;
7196 $this->setError('');
7197 $this->request = '';
7198 $this->response = '';
7199 $this->responseData = '';
7200 $this->faultstring = '';
7201 $this->faultcode = '';
7202 $this->opData = array();
7203
7204 $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7205 $this->appendDebug('params=' . $this->varDump($params));
7206 $this->appendDebug('headers=' . $this->varDump($headers));
7207 if ($headers) {
7208 $this->requestHeaders = $headers;
7209 }
7210 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7211 $this->loadWSDL();
7212 if ($this->getError())
7213 return false;
7214 }
7215 // serialize parameters
7216 if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
7217 // use WSDL for operation
7218 $this->opData = $opData;
7219 $this->debug("found operation");
7220 $this->appendDebug('opData=' . $this->varDump($opData));
7221 if (isset($opData['soapAction'])) {
7222 $soapAction = $opData['soapAction'];
7223 }
7224 if (! $this->forceEndpoint) {
7225 $this->endpoint = $opData['endpoint'];
7226 } else {
7227 $this->endpoint = $this->forceEndpoint;
7228 }
7229 $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
7230 $style = $opData['style'];
7231 $use = $opData['input']['use'];
7232 // add ns to ns array
7233 if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
7234 $nsPrefix = 'ns' . rand(1000, 9999);
7235 $this->wsdl->namespaces[$nsPrefix] = $namespace;
7236 }
7237 $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
7238 // serialize payload
7239 if (is_string($params)) {
7240 $this->debug("serializing param string for WSDL operation $operation");
7241 $payload = $params;
7242 } elseif (is_array($params)) {
7243 $this->debug("serializing param array for WSDL operation $operation");
7244 $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
7245 } else {
7246 $this->debug('params must be array or string');
7247 $this->setError('params must be array or string');
7248 return false;
7249 }
7250 $usedNamespaces = $this->wsdl->usedNamespaces;
7251 if (isset($opData['input']['encodingStyle'])) {
7252 $encodingStyle = $opData['input']['encodingStyle'];
7253 } else {
7254 $encodingStyle = '';
7255 }
7256 $this->appendDebug($this->wsdl->getDebug());
7257 $this->wsdl->clearDebug();
7258 if ($errstr = $this->wsdl->getError()) {
7259 $this->debug('got wsdl error: '.$errstr);
7260 $this->setError('wsdl error: '.$errstr);
7261 return false;
7262 }
7263 } elseif($this->endpointType == 'wsdl') {
7264 // operation not in WSDL
7265 $this->appendDebug($this->wsdl->getDebug());
7266 $this->wsdl->clearDebug();
7267 $this->setError( 'operation '.$operation.' not present.');
7268 $this->debug("operation '$operation' not present.");
7269 return false;
7270 } else {
7271 // no WSDL
7272 //$this->namespaces['ns1'] = $namespace;
7273 $nsPrefix = 'ns' . rand(1000, 9999);
7274 // serialize
7275 $payload = '';
7276 if (is_string($params)) {
7277 $this->debug("serializing param string for operation $operation");
7278 $payload = $params;
7279 } elseif (is_array($params)) {
7280 $this->debug("serializing param array for operation $operation");
7281 foreach($params as $k => $v){
7282 $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
7283 }
7284 } else {
7285 $this->debug('params must be array or string');
7286 $this->setError('params must be array or string');
7287 return false;
7288 }
7289 $usedNamespaces = array();
7290 if ($use == 'encoded') {
7291 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
7292 } else {
7293 $encodingStyle = '';
7294 }
7295 }
7296 // wrap RPC calls with method element
7297 if ($style == 'rpc') {
7298 if ($use == 'literal') {
7299 $this->debug("wrapping RPC request with literal method element");
7300 if ($namespace) {
7301 // 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
7302 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7303 $payload .
7304 "</$nsPrefix:$operation>";
7305 } else {
7306 $payload = "<$operation>" . $payload . "</$operation>";
7307 }
7308 } else {
7309 $this->debug("wrapping RPC request with encoded method element");
7310 if ($namespace) {
7311 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7312 $payload .
7313 "</$nsPrefix:$operation>";
7314 } else {
7315 $payload = "<$operation>" .
7316 $payload .
7317 "</$operation>";
7318 }
7319 }
7320 }
7321 // serialize envelope
7322 $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
7323 $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7324 $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7325 // send
7326 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7327 if($errstr = $this->getError()){
7328 $this->debug('Error: '.$errstr);
7329 return false;
7330 } else {
7331 $this->return = $return;
7332 $this->debug('sent message successfully and got a(n) '.gettype($return));
7333 $this->appendDebug('return=' . $this->varDump($return));
7334
7335 // fault?
7336 if(is_array($return) && isset($return['faultcode'])){
7337 $this->debug('got fault');
7338 $this->setError($return['faultcode'].': '.$return['faultstring']);
7339 $this->fault = true;
7340 foreach($return as $k => $v){
7341 $this->$k = $v;
7342 $this->debug("$k = $v<br>");
7343 }
7344 return $return;
7345 } elseif ($style == 'document') {
7346 // NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
7347 // we are only going to return the first part here...sorry about that
7348 return $return;
7349 } else {
7350 // array of return values
7351 if(is_array($return)){
7352 // multiple 'out' parameters, which we return wrapped up
7353 // in the array
7354 if(sizeof($return) > 1){
7355 return $return;
7356 }
7357 // single 'out' parameter (normally the return value)
7358 $return = array_shift($return);
7359 $this->debug('return shifted value: ');
7360 $this->appendDebug($this->varDump($return));
7361 return $return;
7362 // nothing returned (ie, echoVoid)
7363 } else {
7364 return "";
7365 }
7366 }
7367 }
7368 }
7369
7375 function checkWSDL() {
7376 $this->appendDebug($this->wsdl->getDebug());
7377 $this->wsdl->clearDebug();
7378 $this->debug('checkWSDL');
7379 // catch errors
7380 if ($errstr = $this->wsdl->getError()) {
7381 $this->debug('got wsdl error: '.$errstr);
7382 $this->setError('wsdl error: '.$errstr);
7383 } elseif ($this->operations = $this->wsdl->getOperations('soap')) {
7384 $this->bindingType = 'soap';
7385 $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7386 } elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
7387 $this->bindingType = 'soap12';
7388 $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7389 $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
7390 } else {
7391 $this->debug('getOperations returned false');
7392 $this->setError('no operations defined in the WSDL document!');
7393 }
7394 }
7395
7401 function loadWSDL() {
7402 $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
7403 $this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7404 $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7405 $this->wsdl->fetchWSDL($this->wsdlFile);
7406 $this->checkWSDL();
7407 }
7408
7416 function getOperationData($operation){
7417 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7418 $this->loadWSDL();
7419 if ($this->getError())
7420 return false;
7421 }
7422 if(isset($this->operations[$operation])){
7423 return $this->operations[$operation];
7424 }
7425 $this->debug("No data for operation: $operation");
7426 }
7427
7442 function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
7443 $this->checkCookies();
7444 // detect transport
7445 switch(true){
7446 // http(s)
7447 case preg_match('/^http/',$this->endpoint):
7448 $this->debug('transporting via HTTP');
7449 if($this->persistentConnection == true && is_object($this->persistentConnection)){
7451 } else {
7452 $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
7453 if ($this->persistentConnection) {
7454 $http->usePersistentConnection();
7455 }
7456 }
7457 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7458 $http->setSOAPAction($soapaction);
7459 if($this->proxyhost && $this->proxyport){
7460 $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7461 }
7462 if($this->authtype != '') {
7463 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7464 }
7465 if($this->http_encoding != ''){
7466 $http->setEncoding($this->http_encoding);
7467 }
7468 $this->debug('sending message, length='.strlen($msg));
7469 if(preg_match('/^http:/',$this->endpoint)){
7470 //if(strpos($this->endpoint,'http:')){
7471 $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
7472 } elseif(preg_match('/^https/',$this->endpoint)){
7473 //} elseif(strpos($this->endpoint,'https:')){
7474 //if(phpversion() == '4.3.0-dev'){
7475 //$response = $http->send($msg,$timeout,$response_timeout);
7476 //$this->request = $http->outgoing_payload;
7477 //$this->response = $http->incoming_payload;
7478 //} else
7479 $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7480 } else {
7481 $this->setError('no http/s in endpoint url');
7482 }
7483 $this->request = $http->outgoing_payload;
7484 $this->response = $http->incoming_payload;
7485 $this->appendDebug($http->getDebug());
7486 $this->UpdateCookies($http->incoming_cookies);
7487
7488 // save transport object if using persistent connections
7489 if ($this->persistentConnection) {
7490 $http->clearDebug();
7491 if (!is_object($this->persistentConnection)) {
7492 $this->persistentConnection = $http;
7493 }
7494 }
7495
7496 if($err = $http->getError()){
7497 $this->setError('HTTP Error: '.$err);
7498 return false;
7499 } elseif($this->getError()){
7500 return false;
7501 } else {
7502 $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
7503 return $this->parseResponse($http->incoming_headers, $this->responseData);
7504 }
7505 break;
7506 default:
7507 $this->setError('no transport found, or selected transport is not yet supported!');
7508 return false;
7509 break;
7510 }
7511 }
7512
7521 function parseResponse($headers, $data) {
7522 $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
7523 $this->appendDebug($this->varDump($headers));
7524 if (!strstr($headers['content-type'], 'text/xml')) {
7525 $this->setError('Response not of type text/xml: ' . $headers['content-type']);
7526 return false;
7527 }
7528 if (strpos($headers['content-type'], '=')) {
7529 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
7530 $this->debug('Got response encoding: ' . $enc);
7531 if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7532 $this->xml_encoding = strtoupper($enc);
7533 } else {
7534 $this->xml_encoding = 'US-ASCII';
7535 }
7536 } else {
7537 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
7538 $this->xml_encoding = 'ISO-8859-1';
7539 }
7540 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
7541 $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7542 // add parser debug data to our debug
7543 $this->appendDebug($parser->getDebug());
7544 // if parse errors
7545 if($errstr = $parser->getError()){
7546 $this->setError( $errstr);
7547 // destroy the parser object
7548 unset($parser);
7549 return false;
7550 } else {
7551 // get SOAP headers
7552 $this->responseHeaders = $parser->getHeaders();
7553 // get SOAP headers
7554 $this->responseHeader = $parser->get_soapheader();
7555 // get decoded message
7556 $return = $parser->get_soapbody();
7557 // add document for doclit support
7558 $this->document = $parser->document;
7559 // destroy the parser object
7560 unset($parser);
7561 // return decode message
7562 return $return;
7563 }
7564 }
7565
7573 function setCurlOption($option, $value) {
7574 $this->debug("setCurlOption option=$option, value=");
7575 $this->appendDebug($this->varDump($value));
7576 $this->curl_options[$option] = $value;
7577 }
7578
7585 function setEndpoint($endpoint) {
7586 $this->debug("setEndpoint(\"$endpoint\")");
7587 $this->forceEndpoint = $endpoint;
7588 }
7589
7596 function setHeaders($headers){
7597 $this->debug("setHeaders headers=");
7598 $this->appendDebug($this->varDump($headers));
7599 $this->requestHeaders = $headers;
7600 }
7601
7608 function getHeaders(){
7610 }
7611
7618 function getHeader(){
7619 return $this->responseHeader;
7620 }
7621
7632 $this->proxyhost = $proxyhost;
7633 $this->proxyport = $proxyport;
7634 $this->proxyusername = $proxyusername;
7635 $this->proxypassword = $proxypassword;
7636 }
7637
7647 function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
7648 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
7649 $this->appendDebug($this->varDump($certRequest));
7650 $this->username = $username;
7651 $this->password = $password;
7652 $this->authtype = $authtype;
7653 $this->certRequest = $certRequest;
7654 }
7655
7662 function setHTTPEncoding($enc='gzip, deflate'){
7663 $this->debug("setHTTPEncoding(\"$enc\")");
7664 $this->http_encoding = $enc;
7665 }
7666
7673 function setUseCURL($use) {
7674 $this->debug("setUseCURL($use)");
7675 $this->use_curl = $use;
7676 }
7677
7683 function useHTTPPersistentConnection(){
7684 $this->debug("useHTTPPersistentConnection");
7685 $this->persistentConnection = true;
7686 }
7687
7699 function getDefaultRpcParams() {
7701 }
7702
7714 function setDefaultRpcParams($rpcParams) {
7715 $this->defaultRpcParams = $rpcParams;
7716 }
7717
7725 function getProxy() {
7726 $r = rand();
7727 $evalStr = $this->_getProxyClassCode($r);
7728 //$this->debug("proxy class: $evalStr");
7729 if ($this->getError()) {
7730 $this->debug("Error from _getProxyClassCode, so return NULL");
7731 return null;
7732 }
7733 // eval the class
7734 eval($evalStr);
7735 // instantiate proxy object
7736 eval("\$proxy = new nusoap_proxy_$r('');");
7737 // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
7738 $proxy->endpointType = 'wsdl';
7739 $proxy->wsdlFile = $this->wsdlFile;
7740 $proxy->wsdl = $this->wsdl;
7741 $proxy->operations = $this->operations;
7742 $proxy->defaultRpcParams = $this->defaultRpcParams;
7743 // transfer other state
7744 $proxy->soap_defencoding = $this->soap_defencoding;
7745 $proxy->username = $this->username;
7746 $proxy->password = $this->password;
7747 $proxy->authtype = $this->authtype;
7748 $proxy->certRequest = $this->certRequest;
7749 $proxy->requestHeaders = $this->requestHeaders;
7750 $proxy->endpoint = $this->endpoint;
7751 $proxy->forceEndpoint = $this->forceEndpoint;
7752 $proxy->proxyhost = $this->proxyhost;
7753 $proxy->proxyport = $this->proxyport;
7754 $proxy->proxyusername = $this->proxyusername;
7755 $proxy->proxypassword = $this->proxypassword;
7756 $proxy->http_encoding = $this->http_encoding;
7757 $proxy->timeout = $this->timeout;
7758 $proxy->response_timeout = $this->response_timeout;
7759 $proxy->persistentConnection = &$this->persistentConnection;
7760 $proxy->decode_utf8 = $this->decode_utf8;
7761 $proxy->curl_options = $this->curl_options;
7762 $proxy->bindingType = $this->bindingType;
7763 $proxy->use_curl = $this->use_curl;
7764 return $proxy;
7765 }
7766
7773 function _getProxyClassCode($r) {
7774 $this->debug("in getProxy endpointType=$this->endpointType");
7775 $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
7776 if ($this->endpointType != 'wsdl') {
7777 $evalStr = 'A proxy can only be created for a WSDL client';
7778 $this->setError($evalStr);
7779 $evalStr = "echo \"$evalStr\";";
7780 return $evalStr;
7781 }
7782 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7783 $this->loadWSDL();
7784 if ($this->getError()) {
7785 return "echo \"" . $this->getError() . "\";";
7786 }
7787 }
7788 $evalStr = '';
7789 foreach ($this->operations as $operation => $opData) {
7790 if ($operation != '') {
7791 // create param string and param comment string
7792 if (sizeof($opData['input']['parts']) > 0) {
7793 $paramStr = '';
7794 $paramArrayStr = '';
7795 $paramCommentStr = '';
7796 foreach ($opData['input']['parts'] as $name => $type) {
7797 $paramStr .= "\$$name, ";
7798 $paramArrayStr .= "'$name' => \$$name, ";
7799 $paramCommentStr .= "$type \$$name, ";
7800 }
7801 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7802 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7803 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7804 } else {
7805 $paramStr = '';
7806 $paramArrayStr = '';
7807 $paramCommentStr = 'void';
7808 }
7809 $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
7810 $evalStr .= "// $paramCommentStr
7811 function " . str_replace('.', '__', $operation) . "($paramStr) {
7812 \$params = array($paramArrayStr);
7813 return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
7814 }
7815 ";
7816 unset($paramStr);
7817 unset($paramCommentStr);
7818 }
7819 }
7820 $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
7821 '.$evalStr.'
7822}';
7823 return $evalStr;
7824 }
7825
7832 function getProxyClassCode() {
7833 $r = rand();
7834 return $this->_getProxyClassCode($r);
7835 }
7836
7844 function getHTTPBody($soapmsg) {
7845 return $soapmsg;
7846 }
7847
7856 function getHTTPContentType() {
7857 return 'text/xml';
7858 }
7859
7869 function getHTTPContentTypeCharset() {
7871 }
7872
7873 /*
7874 * whether or not parser should decode utf8 element content
7875 *
7876 * @return always returns true
7877 * @access public
7878 */
7879 function decodeUTF8($bool){
7880 $this->decode_utf8 = $bool;
7881 return true;
7882 }
7883
7892 function setCookie($name, $value) {
7893 if (strlen($name) == 0) {
7894 return false;
7895 }
7896 $this->cookies[] = array('name' => $name, 'value' => $value);
7897 return true;
7898 }
7899
7906 function getCookies() {
7907 return $this->cookies;
7908 }
7909
7916 function checkCookies() {
7917 if (sizeof($this->cookies) == 0) {
7918 return true;
7919 }
7920 $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
7921 $curr_cookies = $this->cookies;
7922 $this->cookies = array();
7923 foreach ($curr_cookies as $cookie) {
7924 if (! is_array($cookie)) {
7925 $this->debug('Remove cookie that is not an array');
7926 continue;
7927 }
7928 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
7929 if (strtotime($cookie['expires']) > time()) {
7930 $this->cookies[] = $cookie;
7931 } else {
7932 $this->debug('Remove expired cookie ' . $cookie['name']);
7933 }
7934 } else {
7935 $this->cookies[] = $cookie;
7936 }
7937 }
7938 $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
7939 return true;
7940 }
7941
7949 function UpdateCookies($cookies) {
7950 if (sizeof($this->cookies) == 0) {
7951 // no existing cookies: take whatever is new
7952 if (sizeof($cookies) > 0) {
7953 $this->debug('Setting new cookie(s)');
7954 $this->cookies = $cookies;
7955 }
7956 return true;
7957 }
7958 if (sizeof($cookies) == 0) {
7959 // no new cookies: keep what we've got
7960 return true;
7961 }
7962 // merge
7963 foreach ($cookies as $newCookie) {
7964 if (!is_array($newCookie)) {
7965 continue;
7966 }
7967 if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
7968 continue;
7969 }
7970 $newName = $newCookie['name'];
7971
7972 $found = false;
7973 for ($i = 0; $i < count($this->cookies); $i++) {
7974 $cookie = $this->cookies[$i];
7975 if (!is_array($cookie)) {
7976 continue;
7977 }
7978 if (!isset($cookie['name'])) {
7979 continue;
7980 }
7981 if ($newName != $cookie['name']) {
7982 continue;
7983 }
7984 $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
7985 $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
7986 if ($newDomain != $domain) {
7987 continue;
7988 }
7989 $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
7990 $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
7991 if ($newPath != $path) {
7992 continue;
7993 }
7994 $this->cookies[$i] = $newCookie;
7995 $found = true;
7996 $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
7997 break;
7998 }
7999 if (! $found) {
8000 $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
8001 $this->cookies[] = $newCookie;
8002 }
8003 }
8004 return true;
8005 }
8006}
8007
8008if (!extension_loaded('soap')) {
8012 class soapclient extends nusoap_client {
8013 }
8014}
$parser
Definition: BPMN2Parser.php:23
$n
Definition: RandomTest.php:85
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
if(! $in) print
$endpoint
if(!array_key_exists('domain', $_REQUEST)) $domain
Definition: resume.php:8
$_GET["client_id"]
An exception for terminatinating execution or to throw for unit testing.
parses an XML Schema, allows access to it's data, other utility methods no validation....
Definition: nusoap.php:734
nusoap_base
Definition: nusoap.php:61
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
Definition: nusoap.php:525
& getDebug()
gets the current debug data for this instance
Definition: nusoap.php: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
__construct()
constructor
Definition: nusoap.php:232
[nu]soapclient higher level class for easy usage.
Definition: nusoap.php:7064
setCurlOption($option, $value)
sets user-specified cURL options
Definition: nusoap.php:7573
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:7647
setHTTPProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='')
set proxy info here
Definition: nusoap.php:7631
getProxy()
dynamically creates an instance of a proxy class, allowing user to directly call methods from wsdl
Definition: nusoap.php:7725
send($msg, $soapaction='', $timeout=0, $response_timeout=30)
send the SOAP message
Definition: nusoap.php:7442
setUseCURL($use)
Set whether to try to use cURL connections if possible.
Definition: nusoap.php:7673
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:7193
getProxyClassCode()
dynamically creates proxy class code
Definition: nusoap.php:7832
checkCookies()
checks all Cookies and delete those which are expired
Definition: nusoap.php:7916
getHTTPContentType()
gets the HTTP content type for the current request.
Definition: nusoap.php:7856
setHTTPEncoding($enc='gzip, deflate')
use HTTP encoding
Definition: nusoap.php:7662
getHeader()
get the SOAP response Header (parsed)
Definition: nusoap.php:7618
decodeUTF8($bool)
Definition: nusoap.php:7879
useHTTPPersistentConnection()
use HTTP persistent connections if possible
Definition: nusoap.php:7683
setCookie($name, $value)
adds a new Cookie into $this->cookies array
Definition: nusoap.php:7892
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current request.
Definition: nusoap.php:7869
getOperationData($operation)
get available data pertaining to an operation
Definition: nusoap.php:7416
getDefaultRpcParams()
gets the default RPC parameter setting.
Definition: nusoap.php:7699
checkWSDL()
check WSDL passed as an instance or pulled from an endpoint
Definition: nusoap.php:7375
setHeaders($headers)
set the SOAP headers
Definition: nusoap.php:7596
loadWSDL()
instantiate wsdl object and parse wsdl file
Definition: nusoap.php:7401
getHTTPBody($soapmsg)
gets the HTTP body for the current request.
Definition: nusoap.php:7844
setDefaultRpcParams($rpcParams)
sets the default RPC parameter setting.
Definition: nusoap.php:7714
setEndpoint($endpoint)
sets the SOAP endpoint, which can override WSDL
Definition: nusoap.php:7585
UpdateCookies($cookies)
updates the current cookies with a new set
Definition: nusoap.php:7949
getHeaders()
get the SOAP response headers (namespace resolution incomplete)
Definition: nusoap.php:7608
_getProxyClassCode($r)
dynamically creates proxy class code
Definition: nusoap.php:7773
getCookies()
gets all Cookies
Definition: nusoap.php:7906
parseResponse($headers, $data)
processes SOAP message returned from server
Definition: nusoap.php:7521
Contains information for a SOAP fault.
Definition: nusoap.php:1004
serialize()
serialize a fault
Definition: nusoap.php:1052
nusoap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:6417
$root_struct_namespace
Definition: nusoap.php:6424
character_data($parser, $data)
element content handler
Definition: nusoap.php:6813
get_soapbody()
get the parsed SOAP Body (NULL if there was none)
Definition: nusoap.php:6849
end_element($parser, $name)
end-element handler
Definition: nusoap.php:6709
getHeaders()
get the unparsed SOAP Header
Definition: nusoap.php:6869
get_response()
get the parsed message (SOAP Body)
Definition: nusoap.php:6839
decodeSimple($value, $type, $typens)
decodes simple types into PHP variables
Definition: nusoap.php:6882
get_soapheader()
get the parsed SOAP Header (NULL if there was none)
Definition: nusoap.php:6859
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:6554
buildVal($pos)
builds response structures for compound values (arrays/structs) and scalars
Definition: nusoap.php:6926
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
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
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
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
$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:6085
$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:6310
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:5515
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:6147
$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
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
if($err=$client->getError()) $namespace
$style
Definition: example_012.php:70
$r
Definition: example_031.php:79
if(!array_key_exists('StateId', $_REQUEST)) $id
$req
Definition: getUserInfo.php:20
if($format !==null) $name
Definition: metadata.php:146
$xml
Definition: metadata.php:240
$debug
Definition: loganalyzer.php:16
$binding
$ret
Definition: parser.php:6
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
Definition: bootstrap.php:27
$type
$url
$http
Definition: raiseError.php:7
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
foreach($_POST as $key=> $value) $res
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
$params
Definition: disable.php:11
$cols
Definition: xhr_table.php:11
$rows
Definition: xhr_table.php:10

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.