00001 <?php
00002
00003
00004
00005
00013 class wsdl extends nusoap_base {
00014
00015 var $wsdl;
00016
00017 var $schemas = array();
00018 var $currentSchema;
00019 var $message = array();
00020 var $complexTypes = array();
00021 var $messages = array();
00022 var $currentMessage;
00023 var $currentOperation;
00024 var $portTypes = array();
00025 var $currentPortType;
00026 var $bindings = array();
00027 var $currentBinding;
00028 var $ports = array();
00029 var $currentPort;
00030 var $opData = array();
00031 var $status = '';
00032 var $documentation = false;
00033 var $endpoint = '';
00034
00035 var $import = array();
00036
00037 var $parser;
00038 var $position = 0;
00039 var $depth = 0;
00040 var $depth_array = array();
00041
00042 var $proxyhost = '';
00043 var $proxyport = '';
00044 var $proxyusername = '';
00045 var $proxypassword = '';
00046 var $timeout = 0;
00047 var $response_timeout = 30;
00048
00061 function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
00062 parent::nusoap_base();
00063 $this->wsdl = $wsdl;
00064 $this->proxyhost = $proxyhost;
00065 $this->proxyport = $proxyport;
00066 $this->proxyusername = $proxyusername;
00067 $this->proxypassword = $proxypassword;
00068 $this->timeout = $timeout;
00069 $this->response_timeout = $response_timeout;
00070
00071
00072 if ($wsdl != "") {
00073 $this->debug('initial wsdl URL: ' . $wsdl);
00074 $this->parseWSDL($wsdl);
00075 }
00076
00077
00078 $imported_urls = array();
00079 $imported = 1;
00080 while ($imported > 0) {
00081 $imported = 0;
00082
00083 foreach ($this->schemas as $ns => $list) {
00084 foreach ($list as $xs) {
00085 $wsdlparts = parse_url($this->wsdl);
00086 foreach ($xs->imports as $ns2 => $list2) {
00087 for ($ii = 0; $ii < count($list2); $ii++) {
00088 if (! $list2[$ii]['loaded']) {
00089 $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
00090 $url = $list2[$ii]['location'];
00091 if ($url != '') {
00092 $urlparts = parse_url($url);
00093 if (!isset($urlparts['host'])) {
00094 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
00095 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
00096 }
00097 if (! in_array($url, $imported_urls)) {
00098 $this->parseWSDL($url);
00099 $imported++;
00100 $imported_urls[] = $url;
00101 }
00102 } else {
00103 $this->debug("Unexpected scenario: empty URL for unloaded import");
00104 }
00105 }
00106 }
00107 }
00108 }
00109 }
00110
00111 $wsdlparts = parse_url($this->wsdl);
00112 foreach ($this->import as $ns => $list) {
00113 for ($ii = 0; $ii < count($list); $ii++) {
00114 if (! $list[$ii]['loaded']) {
00115 $this->import[$ns][$ii]['loaded'] = true;
00116 $url = $list[$ii]['location'];
00117 if ($url != '') {
00118 $urlparts = parse_url($url);
00119 if (!isset($urlparts['host'])) {
00120 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
00121 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
00122 }
00123 if (! in_array($url, $imported_urls)) {
00124 $this->parseWSDL($url);
00125 $imported++;
00126 $imported_urls[] = $url;
00127 }
00128 } else {
00129 $this->debug("Unexpected scenario: empty URL for unloaded import");
00130 }
00131 }
00132 }
00133 }
00134 }
00135
00136 foreach($this->bindings as $binding => $bindingData) {
00137 if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
00138 foreach($bindingData['operations'] as $operation => $data) {
00139 $this->debug('post-parse data gathering for ' . $operation);
00140 $this->bindings[$binding]['operations'][$operation]['input'] =
00141 isset($this->bindings[$binding]['operations'][$operation]['input']) ?
00142 array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
00143 $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
00144 $this->bindings[$binding]['operations'][$operation]['output'] =
00145 isset($this->bindings[$binding]['operations'][$operation]['output']) ?
00146 array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
00147 $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
00148 if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
00149 $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
00150 }
00151 if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
00152 $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
00153 }
00154 if (isset($bindingData['style'])) {
00155 $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
00156 }
00157 $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
00158 $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
00159 $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
00160 }
00161 }
00162 }
00163 }
00164
00171 function parseWSDL($wsdl = '')
00172 {
00173 if ($wsdl == '') {
00174 $this->debug('no wsdl passed to parseWSDL()!!');
00175 $this->setError('no wsdl passed to parseWSDL()!!');
00176 return false;
00177 }
00178
00179
00180 $wsdl_props = parse_url($wsdl);
00181
00182 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
00183 $this->debug('getting WSDL http(s) URL ' . $wsdl);
00184
00185 $tr = new soap_transport_http($wsdl);
00186 $tr->request_method = 'GET';
00187 $tr->useSOAPAction = false;
00188 if($this->proxyhost && $this->proxyport){
00189 $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
00190 }
00191 $tr->setEncoding('gzip, deflate');
00192 $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
00193
00194
00195 $this->appendDebug($tr->getDebug());
00196
00197 if($err = $tr->getError() ){
00198 $errstr = 'HTTP ERROR: '.$err;
00199 $this->debug($errstr);
00200 $this->setError($errstr);
00201 unset($tr);
00202 return false;
00203 }
00204 unset($tr);
00205 $this->debug("got WSDL URL");
00206 } else {
00207
00208 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
00209 $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
00210 } else {
00211 $path = $wsdl;
00212 }
00213 $this->debug('getting WSDL file ' . $path);
00214 if ($fp = @fopen($path, 'r')) {
00215 $wsdl_string = '';
00216 while ($data = fread($fp, 32768)) {
00217 $wsdl_string .= $data;
00218 }
00219 fclose($fp);
00220 } else {
00221 $errstr = "Bad path to WSDL file $path";
00222 $this->debug($errstr);
00223 $this->setError($errstr);
00224 return false;
00225 }
00226 }
00227 $this->debug('Parse WSDL');
00228
00229
00230 $this->parser = xml_parser_create();
00231
00232
00233 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
00234
00235 xml_set_object($this->parser, $this);
00236
00237 xml_set_element_handler($this->parser, 'start_element', 'end_element');
00238 xml_set_character_data_handler($this->parser, 'character_data');
00239
00240 if (!xml_parse($this->parser, $wsdl_string, true)) {
00241
00242 $errstr = sprintf(
00243 'XML error parsing WSDL from %s on line %d: %s',
00244 $wsdl,
00245 xml_get_current_line_number($this->parser),
00246 xml_error_string(xml_get_error_code($this->parser))
00247 );
00248 $this->debug($errstr);
00249 $this->debug("XML payload:\n" . $wsdl_string);
00250 $this->setError($errstr);
00251 return false;
00252 }
00253
00254 xml_parser_free($this->parser);
00255 $this->debug('Parsing WSDL done');
00256
00257 if($this->getError()){
00258 return false;
00259 }
00260 return true;
00261 }
00262
00271 function start_element($parser, $name, $attrs)
00272 {
00273 if ($this->status == 'schema') {
00274 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
00275 $this->appendDebug($this->currentSchema->getDebug());
00276 $this->currentSchema->clearDebug();
00277 } elseif (ereg('schema$', $name)) {
00278 $this->debug('Parsing WSDL schema');
00279
00280 $this->status = 'schema';
00281 $this->currentSchema = new xmlschema('', '', $this->namespaces);
00282 $this->currentSchema->schemaStartElement($parser, $name, $attrs);
00283 $this->appendDebug($this->currentSchema->getDebug());
00284 $this->currentSchema->clearDebug();
00285 } else {
00286
00287 $pos = $this->position++;
00288 $depth = $this->depth++;
00289
00290 $this->depth_array[$depth] = $pos;
00291 $this->message[$pos] = array('cdata' => '');
00292
00293 if (count($attrs) > 0) {
00294
00295 foreach($attrs as $k => $v) {
00296 if (ereg("^xmlns", $k)) {
00297 if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
00298 $this->namespaces[$ns_prefix] = $v;
00299 } else {
00300 $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
00301 }
00302 if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
00303 $this->XMLSchemaVersion = $v;
00304 $this->namespaces['xsi'] = $v . '-instance';
00305 }
00306 }
00307 }
00308
00309 foreach($attrs as $k => $v) {
00310 $k = strpos($k, ':') ? $this->expandQname($k) : $k;
00311 if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
00312 $v = strpos($v, ':') ? $this->expandQname($v) : $v;
00313 }
00314 $eAttrs[$k] = $v;
00315 }
00316 $attrs = $eAttrs;
00317 } else {
00318 $attrs = array();
00319 }
00320
00321 if (ereg(':', $name)) {
00322
00323 $prefix = substr($name, 0, strpos($name, ':'));
00324
00325 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : '';
00326
00327 $name = substr(strstr($name, ':'), 1);
00328 }
00329
00330
00331 switch ($this->status) {
00332 case 'message':
00333 if ($name == 'part') {
00334 if (isset($attrs['type'])) {
00335 $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
00336 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
00337 }
00338 if (isset($attrs['element'])) {
00339 $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
00340 $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
00341 }
00342 }
00343 break;
00344 case 'portType':
00345 switch ($name) {
00346 case 'operation':
00347 $this->currentPortOperation = $attrs['name'];
00348 $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
00349 if (isset($attrs['parameterOrder'])) {
00350 $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
00351 }
00352 break;
00353 case 'documentation':
00354 $this->documentation = true;
00355 break;
00356
00357 default:
00358 $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
00359 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
00360 break;
00361 }
00362 break;
00363 case 'binding':
00364 switch ($name) {
00365 case 'binding':
00366
00367 if (isset($attrs['style'])) {
00368 $this->bindings[$this->currentBinding]['prefix'] = $prefix;
00369 }
00370 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
00371 break;
00372 case 'header':
00373 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
00374 break;
00375 case 'operation':
00376 if (isset($attrs['soapAction'])) {
00377 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
00378 }
00379 if (isset($attrs['style'])) {
00380 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
00381 }
00382 if (isset($attrs['name'])) {
00383 $this->currentOperation = $attrs['name'];
00384 $this->debug("current binding operation: $this->currentOperation");
00385 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
00386 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
00387 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
00388 }
00389 break;
00390 case 'input':
00391 $this->opStatus = 'input';
00392 break;
00393 case 'output':
00394 $this->opStatus = 'output';
00395 break;
00396 case 'body':
00397 if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
00398 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
00399 } else {
00400 $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
00401 }
00402 break;
00403 }
00404 break;
00405 case 'service':
00406 switch ($name) {
00407 case 'port':
00408 $this->currentPort = $attrs['name'];
00409 $this->debug('current port: ' . $this->currentPort);
00410 $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
00411
00412 break;
00413 case 'address':
00414 $this->ports[$this->currentPort]['location'] = $attrs['location'];
00415 $this->ports[$this->currentPort]['bindingType'] = $namespace;
00416 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
00417 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
00418 break;
00419 }
00420 break;
00421 }
00422
00423 switch ($name) {
00424 case 'import':
00425 if (isset($attrs['location'])) {
00426 $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
00427 $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
00428 } else {
00429 $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
00430 if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
00431 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
00432 }
00433 $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
00434 }
00435 break;
00436
00437
00438
00439
00440 case 'message':
00441 $this->status = 'message';
00442 $this->messages[$attrs['name']] = array();
00443 $this->currentMessage = $attrs['name'];
00444 break;
00445 case 'portType':
00446 $this->status = 'portType';
00447 $this->portTypes[$attrs['name']] = array();
00448 $this->currentPortType = $attrs['name'];
00449 break;
00450 case "binding":
00451 if (isset($attrs['name'])) {
00452
00453 if (strpos($attrs['name'], ':')) {
00454 $this->currentBinding = $this->getLocalPart($attrs['name']);
00455 } else {
00456 $this->currentBinding = $attrs['name'];
00457 }
00458 $this->status = 'binding';
00459 $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
00460 $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
00461 }
00462 break;
00463 case 'service':
00464 $this->serviceName = $attrs['name'];
00465 $this->status = 'service';
00466 $this->debug('current service: ' . $this->serviceName);
00467 break;
00468 case 'definitions':
00469 foreach ($attrs as $name => $value) {
00470 $this->wsdl_info[$name] = $value;
00471 }
00472 break;
00473 }
00474 }
00475 }
00476
00484 function end_element($parser, $name){
00485
00486 if ( ereg('schema$', $name)) {
00487 $this->status = "";
00488 $this->appendDebug($this->currentSchema->getDebug());
00489 $this->currentSchema->clearDebug();
00490 $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
00491 $this->debug('Parsing WSDL schema done');
00492 }
00493 if ($this->status == 'schema') {
00494 $this->currentSchema->schemaEndElement($parser, $name);
00495 } else {
00496
00497 $this->depth--;
00498 }
00499
00500 if ($this->documentation) {
00501
00502
00503 $this->documentation = false;
00504 }
00505 }
00506
00514 function character_data($parser, $data)
00515 {
00516 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
00517 if (isset($this->message[$pos]['cdata'])) {
00518 $this->message[$pos]['cdata'] .= $data;
00519 }
00520 if ($this->documentation) {
00521 $this->documentation .= $data;
00522 }
00523 }
00524
00525 function getBindingData($binding)
00526 {
00527 if (is_array($this->bindings[$binding])) {
00528 return $this->bindings[$binding];
00529 }
00530 }
00531
00539 function getOperations($bindingType = 'soap')
00540 {
00541 $ops = array();
00542 if ($bindingType == 'soap') {
00543 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
00544 }
00545
00546 foreach($this->ports as $port => $portData) {
00547
00548 if ($portData['bindingType'] == $bindingType) {
00549
00550
00551
00552
00553 if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
00554 $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
00555 }
00556 }
00557 }
00558 return $ops;
00559 }
00560
00569 function getOperationData($operation, $bindingType = 'soap')
00570 {
00571 if ($bindingType == 'soap') {
00572 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
00573 }
00574
00575 foreach($this->ports as $port => $portData) {
00576
00577 if ($portData['bindingType'] == $bindingType) {
00578
00579
00580 foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
00581
00582 if ($operation == $bOperation) {
00583 $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
00584 return $opData;
00585 }
00586 }
00587 }
00588 }
00589 }
00590
00599 function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
00600 if ($bindingType == 'soap') {
00601 $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
00602 }
00603
00604 foreach($this->ports as $port => $portData) {
00605
00606 if ($portData['bindingType'] == $bindingType) {
00607
00608 foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
00609 if ($opData['soapAction'] == $soapAction) {
00610 return $opData;
00611 }
00612 }
00613 }
00614 }
00615 }
00616
00635 function getTypeDef($type, $ns) {
00636 $this->debug("in getTypeDef: type=$type, ns=$ns");
00637 if ((! $ns) && isset($this->namespaces['tns'])) {
00638 $ns = $this->namespaces['tns'];
00639 $this->debug("in getTypeDef: type namespace forced to $ns");
00640 }
00641 if (isset($this->schemas[$ns])) {
00642 $this->debug("in getTypeDef: have schema for namespace $ns");
00643 for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
00644 $xs = &$this->schemas[$ns][$i];
00645 $t = $xs->getTypeDef($type);
00646 $this->appendDebug($xs->getDebug());
00647 $xs->clearDebug();
00648 if ($t) {
00649 if (!isset($t['phpType'])) {
00650
00651 $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
00652 $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
00653 $etype = $this->getTypeDef($uqType, $ns);
00654 if ($etype) {
00655 $this->debug("found type for [element] $type:");
00656 $this->debug($this->varDump($etype));
00657 if (isset($etype['phpType'])) {
00658 $t['phpType'] = $etype['phpType'];
00659 }
00660 if (isset($etype['elements'])) {
00661 $t['elements'] = $etype['elements'];
00662 }
00663 if (isset($etype['attrs'])) {
00664 $t['attrs'] = $etype['attrs'];
00665 }
00666 }
00667 }
00668 return $t;
00669 }
00670 }
00671 } else {
00672 $this->debug("in getTypeDef: do not have schema for namespace $ns");
00673 }
00674 return false;
00675 }
00676
00682 function webDescription(){
00683 global $HTTP_SERVER_VARS;
00684
00685 if (isset($_SERVER)) {
00686 $PHP_SELF = $_SERVER['PHP_SELF'];
00687 } elseif (isset($HTTP_SERVER_VARS)) {
00688 $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
00689 } else {
00690 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
00691 }
00692
00693 $b = '
00694 <html><head><title>NuSOAP: '.$this->serviceName.'</title>
00695 <style type="text/css">
00696 body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
00697 p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
00698 pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
00699 ul { margin-top: 10px; margin-left: 20px; }
00700 li { list-style-type: none; margin-top: 10px; color: #000000; }
00701 .content{
00702 margin-left: 0px; padding-bottom: 2em; }
00703 .nav {
00704 padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
00705 margin-top: 10px; margin-left: 0px; color: #000000;
00706 background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
00707 .title {
00708 font-family: arial; font-size: 26px; color: #ffffff;
00709 background-color: #999999; width: 105%; margin-left: 0px;
00710 padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
00711 .hidden {
00712 position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
00713 font-family: arial; overflow: hidden; width: 600;
00714 padding: 20px; font-size: 10px; background-color: #999999;
00715 layer-background-color:#FFFFFF; }
00716 a,a:active { color: charcoal; font-weight: bold; }
00717 a:visited { color: #666666; font-weight: bold; }
00718 a:hover { color: cc3300; font-weight: bold; }
00719 </style>
00720 <script language="JavaScript" type="text/javascript">
00721 <!--
00722 // POP-UP CAPTIONS...
00723 function lib_bwcheck(){ //Browsercheck (needed)
00724 this.ver=navigator.appVersion
00725 this.agent=navigator.userAgent
00726 this.dom=document.getElementById?1:0
00727 this.opera5=this.agent.indexOf("Opera 5")>-1
00728 this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
00729 this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
00730 this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
00731 this.ie=this.ie4||this.ie5||this.ie6
00732 this.mac=this.agent.indexOf("Mac")>-1
00733 this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
00734 this.ns4=(document.layers && !this.dom)?1:0;
00735 this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
00736 return this
00737 }
00738 var bw = new lib_bwcheck()
00739 //Makes crossbrowser object.
00740 function makeObj(obj){
00741 this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
00742 if(!this.evnt) return false
00743 this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
00744 this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
00745 this.writeIt=b_writeIt;
00746 return this
00747 }
00748 // A unit of measure that will be added when setting the position of a layer.
00749 //var px = bw.ns4||window.opera?"":"px";
00750 function b_writeIt(text){
00751 if (bw.ns4){this.wref.write(text);this.wref.close()}
00752 else this.wref.innerHTML = text
00753 }
00754 //Shows the messages
00755 var oDesc;
00756 function popup(divid){
00757 if(oDesc = new makeObj(divid)){
00758 oDesc.css.visibility = "visible"
00759 }
00760 }
00761 function popout(){ // Hides message
00762 if(oDesc) oDesc.css.visibility = "hidden"
00763 }
00764 //-->
00765 </script>
00766 </head>
00767 <body>
00768 <div class=content>
00769 <br><br>
00770 <div class=title>'.$this->serviceName.'</div>
00771 <div class=nav>
00772 <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
00773 Click on an operation name to view it's details.</p>
00774 <ul>';
00775 foreach($this->getOperations() as $op => $data){
00776 $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
00777
00778 $b .= "<div id='$op' class='hidden'>
00779 <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
00780 foreach($data as $donnie => $marie){
00781 if($donnie == 'input' || $donnie == 'output'){
00782 $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
00783 foreach($marie as $captain => $tenille){
00784 if($captain == 'parts'){
00785 $b .= " $captain:<br>";
00786
00787 foreach($tenille as $joanie => $chachi){
00788 $b .= " $joanie: $chachi<br>";
00789 }
00790
00791 } else {
00792 $b .= " $captain: $tenille<br>";
00793 }
00794 }
00795 } else {
00796 $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
00797 }
00798 }
00799 $b .= '</div>';
00800 }
00801 $b .= '
00802 <ul>
00803 </div>
00804 </div></body></html>';
00805 return $b;
00806 }
00807
00815 function serialize($debug = 0)
00816 {
00817 $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
00818 $xml .= "\n<definitions";
00819 foreach($this->namespaces as $k => $v) {
00820 $xml .= " xmlns:$k=\"$v\"";
00821 }
00822
00823 if (isset($this->namespaces['wsdl'])) {
00824 $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
00825 }
00826 if (isset($this->namespaces['tns'])) {
00827 $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
00828 }
00829 $xml .= '>';
00830
00831 if (sizeof($this->import) > 0) {
00832 foreach($this->import as $ns => $list) {
00833 foreach ($list as $ii) {
00834 if ($ii['location'] != '') {
00835 $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
00836 } else {
00837 $xml .= '<import namespace="' . $ns . '" />';
00838 }
00839 }
00840 }
00841 }
00842
00843 if (count($this->schemas)>=1) {
00844 $xml .= "\n<types>";
00845 foreach ($this->schemas as $ns => $list) {
00846 foreach ($list as $xs) {
00847 $xml .= $xs->serializeSchema();
00848 }
00849 }
00850 $xml .= '</types>';
00851 }
00852
00853 if (count($this->messages) >= 1) {
00854 foreach($this->messages as $msgName => $msgParts) {
00855 $xml .= "\n<message name=\"" . $msgName . '">';
00856 if(is_array($msgParts)){
00857 foreach($msgParts as $partName => $partType) {
00858
00859 if (strpos($partType, ':')) {
00860 $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
00861 } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
00862
00863 $typePrefix = 'xsd';
00864 } else {
00865 foreach($this->typemap as $ns => $types) {
00866 if (isset($types[$partType])) {
00867 $typePrefix = $this->getPrefixFromNamespace($ns);
00868 }
00869 }
00870 if (!isset($typePrefix)) {
00871 die("$partType has no namespace!");
00872 }
00873 }
00874 $ns = $this->getNamespaceFromPrefix($typePrefix);
00875 $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
00876 if ($typeDef['typeClass'] == 'element') {
00877 $elementortype = 'element';
00878 } else {
00879 $elementortype = 'type';
00880 }
00881 $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
00882 }
00883 }
00884 $xml .= '</message>';
00885 }
00886 }
00887
00888 if (count($this->bindings) >= 1) {
00889 $binding_xml = '';
00890 $portType_xml = '';
00891 foreach($this->bindings as $bindingName => $attrs) {
00892 $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
00893 $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
00894 $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
00895 foreach($attrs['operations'] as $opName => $opParts) {
00896 $binding_xml .= '<operation name="' . $opName . '">';
00897 $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
00898 if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
00899 $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
00900 } else {
00901 $enc_style = '';
00902 }
00903 $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
00904 if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
00905 $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
00906 } else {
00907 $enc_style = '';
00908 }
00909 $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
00910 $binding_xml .= '</operation>';
00911 $portType_xml .= '<operation name="' . $opParts['name'] . '"';
00912 if (isset($opParts['parameterOrder'])) {
00913 $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
00914 }
00915 $portType_xml .= '>';
00916 if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
00917 $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
00918 }
00919 $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
00920 $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
00921 $portType_xml .= '</operation>';
00922 }
00923 $portType_xml .= '</portType>';
00924 $binding_xml .= '</binding>';
00925 }
00926 $xml .= $portType_xml . $binding_xml;
00927 }
00928
00929 $xml .= "\n<service name=\"" . $this->serviceName . '">';
00930 if (count($this->ports) >= 1) {
00931 foreach($this->ports as $pName => $attrs) {
00932 $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
00933 $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
00934 $xml .= '</port>';
00935 }
00936 }
00937 $xml .= '</service>';
00938 return $xml . "\n</definitions>";
00939 }
00940
00954 function serializeRPCParameters($operation, $direction, $parameters)
00955 {
00956 $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
00957 $this->appendDebug('parameters=' . $this->varDump($parameters));
00958
00959 if ($direction != 'input' && $direction != 'output') {
00960 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
00961 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
00962 return false;
00963 }
00964 if (!$opData = $this->getOperationData($operation)) {
00965 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
00966 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
00967 return false;
00968 }
00969 $this->debug('opData:');
00970 $this->appendDebug($this->varDump($opData));
00971
00972
00973 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
00974 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
00975 $encodingStyle = $opData['output']['encodingStyle'];
00976 $enc_style = $encodingStyle;
00977 }
00978
00979
00980 $xml = '';
00981 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
00982
00983 $use = $opData[$direction]['use'];
00984 $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
00985 if (is_array($parameters)) {
00986 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
00987 $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
00988 foreach($opData[$direction]['parts'] as $name => $type) {
00989 $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
00990
00991 if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
00992 $encodingStyle = $opData[$direction]['encodingStyle'];
00993 $enc_style = $encodingStyle;
00994 } else {
00995 $enc_style = false;
00996 }
00997
00998
00999 if ($parametersArrayType == 'arraySimple') {
01000 $p = array_shift($parameters);
01001 $this->debug('calling serializeType w/indexed param');
01002 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
01003 } elseif (isset($parameters[$name])) {
01004 $this->debug('calling serializeType w/named param');
01005 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
01006 } else {
01007
01008 $this->debug('calling serializeType w/null param');
01009 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
01010 }
01011 }
01012 } else {
01013 $this->debug('no parameters passed.');
01014 }
01015 }
01016 $this->debug("serializeRPCParameters returning: $xml");
01017 return $xml;
01018 }
01019
01033 function serializeParameters($operation, $direction, $parameters)
01034 {
01035 $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
01036 $this->appendDebug('parameters=' . $this->varDump($parameters));
01037
01038 if ($direction != 'input' && $direction != 'output') {
01039 $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
01040 $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
01041 return false;
01042 }
01043 if (!$opData = $this->getOperationData($operation)) {
01044 $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
01045 $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
01046 return false;
01047 }
01048 $this->debug('opData:');
01049 $this->appendDebug($this->varDump($opData));
01050
01051
01052 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
01053 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
01054 $encodingStyle = $opData['output']['encodingStyle'];
01055 $enc_style = $encodingStyle;
01056 }
01057
01058
01059 $xml = '';
01060 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
01061
01062 $use = $opData[$direction]['use'];
01063 $this->debug("use=$use");
01064 $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
01065 if (is_array($parameters)) {
01066 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
01067 $this->debug('have ' . $parametersArrayType . ' parameters');
01068 foreach($opData[$direction]['parts'] as $name => $type) {
01069 $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
01070
01071 if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
01072 $encodingStyle = $opData[$direction]['encodingStyle'];
01073 $enc_style = $encodingStyle;
01074 } else {
01075 $enc_style = false;
01076 }
01077
01078
01079 if ($parametersArrayType == 'arraySimple') {
01080 $p = array_shift($parameters);
01081 $this->debug('calling serializeType w/indexed param');
01082 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
01083 } elseif (isset($parameters[$name])) {
01084 $this->debug('calling serializeType w/named param');
01085 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
01086 } else {
01087
01088 $this->debug('calling serializeType w/null param');
01089 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
01090 }
01091 }
01092 } else {
01093 $this->debug('no parameters passed.');
01094 }
01095 }
01096 $this->debug("serializeParameters returning: $xml");
01097 return $xml;
01098 }
01099
01112 function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
01113 {
01114 $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
01115 $this->appendDebug("value=" . $this->varDump($value));
01116 if($use == 'encoded' && $encodingStyle) {
01117 $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
01118 }
01119
01120
01121 if (is_object($value) && get_class($value) == 'soapval') {
01122 if ($value->type_ns) {
01123 $type = $value->type_ns . ':' . $value->type;
01124 $forceType = true;
01125 $this->debug("in serializeType: soapval overrides type to $type");
01126 } elseif ($value->type) {
01127 $type = $value->type;
01128 $forceType = true;
01129 $this->debug("in serializeType: soapval overrides type to $type");
01130 } else {
01131 $forceType = false;
01132 $this->debug("in serializeType: soapval does not override type");
01133 }
01134 $attrs = $value->attributes;
01135 $value = $value->value;
01136 $this->debug("in serializeType: soapval overrides value to $value");
01137 if ($attrs) {
01138 if (!is_array($value)) {
01139 $value['!'] = $value;
01140 }
01141 foreach ($attrs as $n => $v) {
01142 $value['!' . $n] = $v;
01143 }
01144 $this->debug("in serializeType: soapval provides attributes");
01145 }
01146 } else {
01147 $forceType = false;
01148 }
01149
01150 $xml = '';
01151 if (strpos($type, ':')) {
01152 $uqType = substr($type, strrpos($type, ':') + 1);
01153 $ns = substr($type, 0, strrpos($type, ':'));
01154 $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
01155 if ($this->getNamespaceFromPrefix($ns)) {
01156 $ns = $this->getNamespaceFromPrefix($ns);
01157 $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
01158 }
01159
01160 if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
01161 $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
01162 if ($unqualified && $use == 'literal') {
01163 $elementNS = " xmlns=\"\"";
01164 } else {
01165 $elementNS = '';
01166 }
01167 if (is_null($value)) {
01168 if ($use == 'literal') {
01169
01170 $xml = "<$name$elementNS/>";
01171 } else {
01172
01173 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
01174 }
01175 $this->debug("in serializeType: returning: $xml");
01176 return $xml;
01177 }
01178 if ($uqType == 'boolean') {
01179 if ((is_string($value) && $value == 'false') || (! $value)) {
01180 $value = 'false';
01181 } else {
01182 $value = 'true';
01183 }
01184 }
01185 if ($uqType == 'string' && gettype($value) == 'string') {
01186 $value = $this->expandEntities($value);
01187 }
01188 if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
01189 $value = sprintf("%.0lf", $value);
01190 }
01191
01192
01193
01194 if (!$this->getTypeDef($uqType, $ns)) {
01195 if ($use == 'literal') {
01196 if ($forceType) {
01197 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
01198 } else {
01199 $xml = "<$name$elementNS>$value</$name>";
01200 }
01201 } else {
01202 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
01203 }
01204 $this->debug("in serializeType: returning: $xml");
01205 return $xml;
01206 }
01207 $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
01208 } else if ($ns == 'http://xml.apache.org/xml-soap') {
01209 $this->debug('in serializeType: appears to be Apache SOAP type');
01210 if ($uqType == 'Map') {
01211 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
01212 if (! $tt_prefix) {
01213 $this->debug('in serializeType: Add namespace for Apache SOAP type');
01214 $tt_prefix = 'ns' . rand(1000, 9999);
01215 $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
01216
01217 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
01218 }
01219 $contents = '';
01220 foreach($value as $k => $v) {
01221 $this->debug("serializing map element: key $k, value $v");
01222 $contents .= '<item>';
01223 $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
01224 $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
01225 $contents .= '</item>';
01226 }
01227 if ($use == 'literal') {
01228 if ($forceType) {
01229 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
01230 } else {
01231 $xml = "<$name>$contents</$name>";
01232 }
01233 } else {
01234 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
01235 }
01236 $this->debug("in serializeType: returning: $xml");
01237 return $xml;
01238 }
01239 $this->debug('in serializeType: Apache SOAP type, but only support Map');
01240 }
01241 } else {
01242
01243
01244 $this->debug("in serializeType: No namespace for type $type");
01245 $ns = '';
01246 $uqType = $type;
01247 }
01248 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
01249 $this->setError("$type ($uqType) is not a supported type.");
01250 $this->debug("in serializeType: $type ($uqType) is not a supported type.");
01251 return false;
01252 } else {
01253 $this->debug("in serializeType: found typeDef");
01254 $this->appendDebug('typeDef=' . $this->varDump($typeDef));
01255 }
01256 $phpType = $typeDef['phpType'];
01257 $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
01258
01259 if ($phpType == 'struct') {
01260 if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
01261 $elementName = $uqType;
01262 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
01263 $elementNS = " xmlns=\"$ns\"";
01264 } else {
01265 $elementNS = " xmlns=\"\"";
01266 }
01267 } else {
01268 $elementName = $name;
01269 if ($unqualified) {
01270 $elementNS = " xmlns=\"\"";
01271 } else {
01272 $elementNS = '';
01273 }
01274 }
01275 if (is_null($value)) {
01276 if ($use == 'literal') {
01277
01278 $xml = "<$elementName$elementNS/>";
01279 } else {
01280 $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
01281 }
01282 $this->debug("in serializeType: returning: $xml");
01283 return $xml;
01284 }
01285 if (is_object($value)) {
01286 $value = get_object_vars($value);
01287 }
01288 if (is_array($value)) {
01289 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
01290 if ($use == 'literal') {
01291 if ($forceType) {
01292 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
01293 } else {
01294 $xml = "<$elementName$elementNS$elementAttrs>";
01295 }
01296 } else {
01297 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
01298 }
01299
01300 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
01301 $xml .= "</$elementName>";
01302 } else {
01303 $this->debug("in serializeType: phpType is struct, but value is not an array");
01304 $this->setError("phpType is struct, but value is not an array: see debug output for details");
01305 $xml = '';
01306 }
01307 } elseif ($phpType == 'array') {
01308 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
01309 $elementNS = " xmlns=\"$ns\"";
01310 } else {
01311 if ($unqualified) {
01312 $elementNS = " xmlns=\"\"";
01313 } else {
01314 $elementNS = '';
01315 }
01316 }
01317 if (is_null($value)) {
01318 if ($use == 'literal') {
01319
01320 $xml = "<$name$elementNS/>";
01321 } else {
01322 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
01323 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
01324 ":Array\" " .
01325 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
01326 ':arrayType="' .
01327 $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
01328 ':' .
01329 $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
01330 }
01331 $this->debug("in serializeType: returning: $xml");
01332 return $xml;
01333 }
01334 if (isset($typeDef['multidimensional'])) {
01335 $nv = array();
01336 foreach($value as $v) {
01337 $cols = ',' . sizeof($v);
01338 $nv = array_merge($nv, $v);
01339 }
01340 $value = $nv;
01341 } else {
01342 $cols = '';
01343 }
01344 if (is_array($value) && sizeof($value) >= 1) {
01345 $rows = sizeof($value);
01346 $contents = '';
01347 foreach($value as $k => $v) {
01348 $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
01349
01350 if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
01351 $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
01352 } else {
01353 $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
01354 }
01355 }
01356 } else {
01357 $rows = 0;
01358 $contents = null;
01359 }
01360
01361
01362 if ($use == 'literal') {
01363 $xml = "<$name$elementNS>"
01364 .$contents
01365 ."</$name>";
01366 } else {
01367 $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
01368 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
01369 .':arrayType="'
01370 .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
01371 .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
01372 .$contents
01373 ."</$name>";
01374 }
01375 } elseif ($phpType == 'scalar') {
01376 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
01377 $elementNS = " xmlns=\"$ns\"";
01378 } else {
01379 if ($unqualified) {
01380 $elementNS = " xmlns=\"\"";
01381 } else {
01382 $elementNS = '';
01383 }
01384 }
01385 if ($use == 'literal') {
01386 if ($forceType) {
01387 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
01388 } else {
01389 $xml = "<$name$elementNS>$value</$name>";
01390 }
01391 } else {
01392 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
01393 }
01394 }
01395 $this->debug("in serializeType: returning: $xml");
01396 return $xml;
01397 }
01398
01409 function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
01410 $xml = '';
01411 if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
01412 $this->debug("serialize attributes for XML Schema type $ns:$uqType");
01413 if (is_array($value)) {
01414 $xvalue = $value;
01415 } elseif (is_object($value)) {
01416 $xvalue = get_object_vars($value);
01417 } else {
01418 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
01419 $xvalue = array();
01420 }
01421 foreach ($typeDef['attrs'] as $aName => $attrs) {
01422 if (isset($xvalue['!' . $aName])) {
01423 $xname = '!' . $aName;
01424 $this->debug("value provided for attribute $aName with key $xname");
01425 } elseif (isset($xvalue[$aName])) {
01426 $xname = $aName;
01427 $this->debug("value provided for attribute $aName with key $xname");
01428 } elseif (isset($attrs['default'])) {
01429 $xname = '!' . $aName;
01430 $xvalue[$xname] = $attrs['default'];
01431 $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
01432 } else {
01433 $xname = '';
01434 $this->debug("no value provided for attribute $aName");
01435 }
01436 if ($xname) {
01437 $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
01438 }
01439 }
01440 } else {
01441 $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
01442 }
01443 if (isset($typeDef['extensionBase'])) {
01444 $ns = $this->getPrefix($typeDef['extensionBase']);
01445 $uqType = $this->getLocalPart($typeDef['extensionBase']);
01446 if ($this->getNamespaceFromPrefix($ns)) {
01447 $ns = $this->getNamespaceFromPrefix($ns);
01448 }
01449 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
01450 $this->debug("serialize attributes for extension base $ns:$uqType");
01451 $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
01452 } else {
01453 $this->debug("extension base $ns:$uqType is not a supported type");
01454 }
01455 }
01456 return $xml;
01457 }
01458
01471 function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
01472 $xml = '';
01473 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
01474 $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
01475 if (is_array($value)) {
01476 $xvalue = $value;
01477 } elseif (is_object($value)) {
01478 $xvalue = get_object_vars($value);
01479 } else {
01480 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
01481 $xvalue = array();
01482 }
01483
01484 if (count($typeDef['elements']) != count($xvalue)){
01485 $optionals = true;
01486 }
01487 foreach ($typeDef['elements'] as $eName => $attrs) {
01488 if (!isset($xvalue[$eName])) {
01489 if (isset($attrs['default'])) {
01490 $xvalue[$eName] = $attrs['default'];
01491 $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
01492 }
01493 }
01494
01495 if (isset($optionals)
01496 && (!isset($xvalue[$eName]))
01497 && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
01498 ){
01499 if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
01500 $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
01501 }
01502
01503 $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
01504 } else {
01505
01506 if (isset($xvalue[$eName])) {
01507 $v = $xvalue[$eName];
01508 } else {
01509 $v = null;
01510 }
01511 if (isset($attrs['form'])) {
01512 $unqualified = ($attrs['form'] == 'unqualified');
01513 } else {
01514 $unqualified = false;
01515 }
01516 if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
01517 $vv = $v;
01518 foreach ($vv as $k => $v) {
01519 if (isset($attrs['type']) || isset($attrs['ref'])) {
01520
01521 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
01522 } else {
01523
01524 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
01525 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
01526 }
01527 }
01528 } else {
01529 if (isset($attrs['type']) || isset($attrs['ref'])) {
01530
01531 $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
01532 } else {
01533
01534 $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
01535 $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
01536 }
01537 }
01538 }
01539 }
01540 } else {
01541 $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
01542 }
01543 if (isset($typeDef['extensionBase'])) {
01544 $ns = $this->getPrefix($typeDef['extensionBase']);
01545 $uqType = $this->getLocalPart($typeDef['extensionBase']);
01546 if ($this->getNamespaceFromPrefix($ns)) {
01547 $ns = $this->getNamespaceFromPrefix($ns);
01548 }
01549 if ($typeDef = $this->getTypeDef($uqType, $ns)) {
01550 $this->debug("serialize elements for extension base $ns:$uqType");
01551 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
01552 } else {
01553 $this->debug("extension base $ns:$uqType is not a supported type");
01554 }
01555 }
01556 return $xml;
01557 }
01558
01573 function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
01574 if (count($elements) > 0) {
01575 foreach($elements as $n => $e){
01576
01577 foreach ($e as $k => $v) {
01578 $k = strpos($k,':') ? $this->expandQname($k) : $k;
01579 $v = strpos($v,':') ? $this->expandQname($v) : $v;
01580 $ee[$k] = $v;
01581 }
01582 $eElements[$n] = $ee;
01583 }
01584 $elements = $eElements;
01585 }
01586
01587 if (count($attrs) > 0) {
01588 foreach($attrs as $n => $a){
01589
01590 foreach ($a as $k => $v) {
01591 $k = strpos($k,':') ? $this->expandQname($k) : $k;
01592 $v = strpos($v,':') ? $this->expandQname($v) : $v;
01593 $aa[$k] = $v;
01594 }
01595 $eAttrs[$n] = $aa;
01596 }
01597 $attrs = $eAttrs;
01598 }
01599
01600 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
01601 $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
01602
01603 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
01604 $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
01605 }
01606
01618 function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
01619 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
01620
01621 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
01622 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
01623 }
01624
01632 function addElement($attrs) {
01633 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
01634 $this->schemas[$typens][0]->addElement($attrs);
01635 }
01636
01651 function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
01652 if ($use == 'encoded' && $encodingStyle == '') {
01653 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
01654 }
01655
01656 if ($style == 'document') {
01657 $elements = array();
01658 foreach ($in as $n => $t) {
01659 $elements[$n] = array('name' => $n, 'type' => $t);
01660 }
01661 $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
01662 $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
01663 $in = array('parameters' => 'tns:' . $name);
01664
01665 $elements = array();
01666 foreach ($out as $n => $t) {
01667 $elements[$n] = array('name' => $n, 'type' => $t);
01668 }
01669 $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
01670 $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
01671 $out = array('parameters' => 'tns:' . $name . 'Response');
01672 }
01673
01674
01675 $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
01676 array(
01677 'name' => $name,
01678 'binding' => $this->serviceName . 'Binding',
01679 'endpoint' => $this->endpoint,
01680 'soapAction' => $soapaction,
01681 'style' => $style,
01682 'input' => array(
01683 'use' => $use,
01684 'namespace' => $namespace,
01685 'encodingStyle' => $encodingStyle,
01686 'message' => $name . 'Request',
01687 'parts' => $in),
01688 'output' => array(
01689 'use' => $use,
01690 'namespace' => $namespace,
01691 'encodingStyle' => $encodingStyle,
01692 'message' => $name . 'Response',
01693 'parts' => $out),
01694 'namespace' => $namespace,
01695 'transport' => 'http://schemas.xmlsoap.org/soap/http',
01696 'documentation' => $documentation);
01697
01698
01699 if($in)
01700 {
01701 foreach($in as $pName => $pType)
01702 {
01703 if(strpos($pType,':')) {
01704 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
01705 }
01706 $this->messages[$name.'Request'][$pName] = $pType;
01707 }
01708 } else {
01709 $this->messages[$name.'Request']= '0';
01710 }
01711 if($out)
01712 {
01713 foreach($out as $pName => $pType)
01714 {
01715 if(strpos($pType,':')) {
01716 $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
01717 }
01718 $this->messages[$name.'Response'][$pName] = $pType;
01719 }
01720 } else {
01721 $this->messages[$name.'Response']= '0';
01722 }
01723 return true;
01724 }
01725 }
01726
01727 ?>