| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 5 6 NuSOAP - Web Services Toolkit for PHP 7 8 Copyright (c) 2002 NuSphere Corporation 9 10 This library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 2.1 of the License, or (at your option) any later version. 14 15 This library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this library; if not, write to the Free Software 22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 24 If you have any questions or comments, please email: 25 26 Dietrich Ayala 27 dietrich@ganx4.com 28 http://dietrich.ganx4.com/nusoap 29 30 NuSphere Corporation 31 http://www.nusphere.com 32 33 */ 34 35 /* load classes 36 37 // necessary classes 38 require_once('class.soap_client.php'); 39 require_once('class.soap_val.php'); 40 require_once('class.soap_parser.php'); 41 require_once('class.soap_fault.php'); 42 43 // transport classes 44 require_once('class.soap_transport_http.php'); 45 46 // optional add-on classes 47 require_once('class.xmlschema.php'); 48 require_once('class.wsdl.php'); 49 50 // server class 51 require_once('class.soap_server.php');*/ 52 53 // class variable emulation 54 // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html 55 $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; 56 57 /** 58 * 59 * nusoap_base 60 * 61 * @author Dietrich Ayala <dietrich@ganx4.com> 62 * @version $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 63 * @access public 64 */ 65 class nusoap_base { 66 /** 67 * Identification for HTTP headers. 68 * 69 * @var string 70 * @access private 71 */ 72 var $title = 'NuSOAP'; 73 /** 74 * Version for HTTP headers. 75 * 76 * @var string 77 * @access private 78 */ 79 var $version = '0.7.2'; 80 /** 81 * CVS revision for HTTP headers. 82 * 83 * @var string 84 * @access private 85 */ 86 var $revision = '$Revision: 1.2 $'; 87 /** 88 * Current error string (manipulated by getError/setError) 89 * 90 * @var string 91 * @access private 92 */ 93 var $error_str = ''; 94 /** 95 * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) 96 * 97 * @var string 98 * @access private 99 */ 100 var $debug_str = ''; 101 /** 102 * toggles automatic encoding of special characters as entities 103 * (should always be true, I think) 104 * 105 * @var boolean 106 * @access private 107 */ 108 var $charencoding = true; 109 /** 110 * the debug level for this instance 111 * 112 * @var integer 113 * @access private 114 */ 115 var $debugLevel; 116 117 /** 118 * set schema version 119 * 120 * @var string 121 * @access public 122 */ 123 var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; 124 125 /** 126 * charset encoding for outgoing messages 127 * 128 * @var string 129 * @access public 130 */ 131 var $soap_defencoding = 'ISO-8859-1'; 132 //var $soap_defencoding = 'UTF-8'; 133 134 /** 135 * namespaces in an array of prefix => uri 136 * 137 * this is "seeded" by a set of constants, but it may be altered by code 138 * 139 * @var array 140 * @access public 141 */ 142 var $namespaces = array( 143 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', 144 'xsd' => 'http://www.w3.org/2001/XMLSchema', 145 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 146 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' 147 ); 148 149 /** 150 * namespaces used in the current context, e.g. during serialization 151 * 152 * @var array 153 * @access private 154 */ 155 var $usedNamespaces = array(); 156 157 /** 158 * XML Schema types in an array of uri => (array of xml type => php type) 159 * is this legacy yet? 160 * no, this is used by the xmlschema class to verify type => namespace mappings. 161 * @var array 162 * @access public 163 */ 164 var $typemap = array( 165 'http://www.w3.org/2001/XMLSchema' => array( 166 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', 167 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', 168 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', 169 // abstract "any" types 170 'anyType'=>'string','anySimpleType'=>'string', 171 // derived datatypes 172 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', 173 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', 174 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', 175 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), 176 'http://www.w3.org/2000/10/XMLSchema' => array( 177 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', 178 'float'=>'double','dateTime'=>'string', 179 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), 180 'http://www.w3.org/1999/XMLSchema' => array( 181 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', 182 'float'=>'double','dateTime'=>'string', 183 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), 184 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), 185 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), 186 'http://xml.apache.org/xml-soap' => array('Map') 187 ); 188 189 /** 190 * XML entities to convert 191 * 192 * @var array 193 * @access public 194 * @deprecated 195 * @see expandEntities 196 */ 197 var $xmlEntities = array('quot' => '"','amp' => '&', 198 'lt' => '<','gt' => '>','apos' => "'"); 199 200 /** 201 * constructor 202 * 203 * @access public 204 */ 205 function nusoap_base() { 206 $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; 207 } 208 209 /** 210 * gets the global debug level, which applies to future instances 211 * 212 * @return integer Debug level 0-9, where 0 turns off 213 * @access public 214 */ 215 function getGlobalDebugLevel() { 216 return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; 217 } 218 219 /** 220 * sets the global debug level, which applies to future instances 221 * 222 * @param int $level Debug level 0-9, where 0 turns off 223 * @access public 224 */ 225 function setGlobalDebugLevel($level) { 226 $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; 227 } 228 229 /** 230 * gets the debug level for this instance 231 * 232 * @return int Debug level 0-9, where 0 turns off 233 * @access public 234 */ 235 function getDebugLevel() { 236 return $this->debugLevel; 237 } 238 239 /** 240 * sets the debug level for this instance 241 * 242 * @param int $level Debug level 0-9, where 0 turns off 243 * @access public 244 */ 245 function setDebugLevel($level) { 246 $this->debugLevel = $level; 247 } 248 249 /** 250 * adds debug data to the instance debug string with formatting 251 * 252 * @param string $string debug data 253 * @access private 254 */ 255 function debug($string){ 256 if ($this->debugLevel > 0) { 257 $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); 258 } 259 } 260 261 /** 262 * adds debug data to the instance debug string without formatting 263 * 264 * @param string $string debug data 265 * @access public 266 */ 267 function appendDebug($string){ 268 if ($this->debugLevel > 0) { 269 // it would be nice to use a memory stream here to use 270 // memory more efficiently 271 $this->debug_str .= $string; 272 } 273 } 274 275 /** 276 * clears the current debug data for this instance 277 * 278 * @access public 279 */ 280 function clearDebug() { 281 // it would be nice to use a memory stream here to use 282 // memory more efficiently 283 $this->debug_str = ''; 284 } 285 286 /** 287 * gets the current debug data for this instance 288 * 289 * @return debug data 290 * @access public 291 */ 292 function &getDebug() { 293 // it would be nice to use a memory stream here to use 294 // memory more efficiently 295 return $this->debug_str; 296 } 297 298 /** 299 * gets the current debug data for this instance as an XML comment 300 * this may change the contents of the debug data 301 * 302 * @return debug data as an XML comment 303 * @access public 304 */ 305 function &getDebugAsXMLComment() { 306 // it would be nice to use a memory stream here to use 307 // memory more efficiently 308 while (strpos($this->debug_str, '--')) { 309 $this->debug_str = str_replace('--', '- -', $this->debug_str); 310 } 311 return "<!--\n" . $this->debug_str . "\n-->"; 312 } 313 314 /** 315 * expands entities, e.g. changes '<' to '<'. 316 * 317 * @param string $val The string in which to expand entities. 318 * @access private 319 */ 320 function expandEntities($val) { 321 if ($this->charencoding) { 322 $val = str_replace('&', '&', $val); 323 $val = str_replace("'", ''', $val); 324 $val = str_replace('"', '"', $val); 325 $val = str_replace('<', '<', $val); 326 $val = str_replace('>', '>', $val); 327 } 328 return $val; 329 } 330 331 /** 332 * returns error string if present 333 * 334 * @return mixed error string or false 335 * @access public 336 */ 337 function getError(){ 338 if($this->error_str != ''){ 339 return $this->error_str; 340 } 341 return false; 342 } 343 344 /** 345 * sets error string 346 * 347 * @return boolean $string error string 348 * @access private 349 */ 350 function setError($str){ 351 $this->error_str = $str; 352 } 353 354 /** 355 * detect if array is a simple array or a struct (associative array) 356 * 357 * @param mixed $val The PHP array 358 * @return string (arraySimple|arrayStruct) 359 * @access private 360 */ 361 function isArraySimpleOrStruct($val) { 362 $keyList = array_keys($val); 363 foreach ($keyList as $keyListValue) { 364 if (!is_int($keyListValue)) { 365 return 'arrayStruct'; 366 } 367 } 368 return 'arraySimple'; 369 } 370 371 /** 372 * serializes PHP values in accordance w/ section 5. Type information is 373 * not serialized if $use == 'literal'. 374 * 375 * @param mixed $val The value to serialize 376 * @param string $name The name (local part) of the XML element 377 * @param string $type The XML schema type (local part) for the element 378 * @param string $name_ns The namespace for the name of the XML element 379 * @param string $type_ns The namespace for the type of the element 380 * @param array $attributes The attributes to serialize as name=>value pairs 381 * @param string $use The WSDL "use" (encoded|literal) 382 * @return string The serialized element, possibly with child elements 383 * @access public 384 */ 385 function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ 386 $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); 387 $this->appendDebug('value=' . $this->varDump($val)); 388 $this->appendDebug('attributes=' . $this->varDump($attributes)); 389 390 if(is_object($val) && get_class($val) == 'soapval'){ 391 return $val->serialize($use); 392 } 393 // force valid name if necessary 394 if (is_numeric($name)) { 395 $name = '__numeric_' . $name; 396 } elseif (! $name) { 397 $name = 'noname'; 398 } 399 // if name has ns, add ns prefix to name 400 $xmlns = ''; 401 if($name_ns){ 402 $prefix = 'nu'.rand(1000,9999); 403 $name = $prefix.':'.$name; 404 $xmlns .= " xmlns:$prefix=\"$name_ns\""; 405 } 406 // if type is prefixed, create type prefix 407 if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ 408 // need to fix this. shouldn't default to xsd if no ns specified 409 // w/o checking against typemap 410 $type_prefix = 'xsd'; 411 } elseif($type_ns){ 412 $type_prefix = 'ns'.rand(1000,9999); 413 $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; 414 } 415 // serialize attributes if present 416 $atts = ''; 417 if($attributes){ 418 foreach($attributes as $k => $v){ 419 $atts .= " $k=\"".$this->expandEntities($v).'"'; 420 } 421 } 422 // serialize null value 423 if (is_null($val)) { 424 if ($use == 'literal') { 425 // TODO: depends on minOccurs 426 return "<$name$xmlns $atts/>"; 427 } else { 428 if (isset($type) && isset($type_prefix)) { 429 $type_str = " xsi:type=\"$type_prefix:$type\""; 430 } else { 431 $type_str = ''; 432 } 433 return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; 434 } 435 } 436 // serialize if an xsd built-in primitive type 437 if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ 438 if (is_bool($val)) { 439 if ($type == 'boolean') { 440 $val = $val ? 'true' : 'false'; 441 } elseif (! $val) { 442 $val = 0; 443 } 444 } else if (is_string($val)) { 445 $val = $this->expandEntities($val); 446 } 447 if ($use == 'literal') { 448 return "<$name$xmlns $atts>$val</$name>"; 449 } else { 450 return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>"; 451 } 452 } 453 // detect type and serialize 454 $xml = ''; 455 switch(true) { 456 case (is_bool($val) || $type == 'boolean'): 457 if ($type == 'boolean') { 458 $val = $val ? 'true' : 'false'; 459 } elseif (! $val) { 460 $val = 0; 461 } 462 if ($use == 'literal') { 463 $xml .= "<$name$xmlns $atts>$val</$name>"; 464 } else { 465 $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>"; 466 } 467 break; 468 case (is_int($val) || is_long($val) || $type == 'int'): 469 if ($use == 'literal') { 470 $xml .= "<$name$xmlns $atts>$val</$name>"; 471 } else { 472 $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>"; 473 } 474 break; 475 case (is_float($val)|| is_double($val) || $type == 'float'): 476 if ($use == 'literal') { 477 $xml .= "<$name$xmlns $atts>$val</$name>"; 478 } else { 479 $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>"; 480 } 481 break; 482 case (is_string($val) || $type == 'string'): 483 $val = $this->expandEntities($val); 484 if ($use == 'literal') { 485 $xml .= "<$name$xmlns $atts>$val</$name>"; 486 } else { 487 $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>"; 488 } 489 break; 490 case is_object($val): 491 if (! $name) { 492 $name = get_class($val); 493 $this->debug("In serialize_val, used class name $name as element name"); 494 } else { 495 $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); 496 } 497 foreach(get_object_vars($val) as $k => $v){ 498 $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); 499 } 500 $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>'; 501 break; 502 break; 503 case (is_array($val) || $type): 504 // detect if struct or array 505 $valueType = $this->isArraySimpleOrStruct($val); 506 if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ 507 $i = 0; 508 if(is_array($val) && count($val)> 0){ 509 foreach($val as $v){ 510 if(is_object($v) && get_class($v) == 'soapval'){ 511 $tt_ns = $v->type_ns; 512 $tt = $v->type; 513 } elseif (is_array($v)) { 514 $tt = $this->isArraySimpleOrStruct($v); 515 } else { 516 $tt = gettype($v); 517 } 518 $array_types[$tt] = 1; 519 // TODO: for literal, the name should be $name 520 $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); 521 ++$i; 522 } 523 if(count($array_types) > 1){ 524 $array_typename = 'xsd:anyType'; 525 } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { 526 if ($tt == 'integer') { 527 $tt = 'int'; 528 } 529 $array_typename = 'xsd:'.$tt; 530 } elseif(isset($tt) && $tt == 'arraySimple'){ 531 $array_typename = 'SOAP-ENC:Array'; 532 } elseif(isset($tt) && $tt == 'arrayStruct'){ 533 $array_typename = 'unnamed_struct_use_soapval'; 534 } else { 535 // if type is prefixed, create type prefix 536 if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ 537 $array_typename = 'xsd:' . $tt; 538 } elseif ($tt_ns) { 539 $tt_prefix = 'ns' . rand(1000, 9999); 540 $array_typename = "$tt_prefix:$tt"; 541 $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; 542 } else { 543 $array_typename = $tt; 544 } 545 } 546 $array_type = $i; 547 if ($use == 'literal') { 548 $type_str = ''; 549 } else if (isset($type) && isset($type_prefix)) { 550 $type_str = " xsi:type=\"$type_prefix:$type\""; 551 } else { 552 $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; 553 } 554 // empty array 555 } else { 556 if ($use == 'literal') { 557 $type_str = ''; 558 } else if (isset($type) && isset($type_prefix)) { 559 $type_str = " xsi:type=\"$type_prefix:$type\""; 560 } else { 561 $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; 562 } 563 } 564 // TODO: for array in literal, there is no wrapper here 565 $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>"; 566 } else { 567 // got a struct 568 if(isset($type) && isset($type_prefix)){ 569 $type_str = " xsi:type=\"$type_prefix:$type\""; 570 } else { 571 $type_str = ''; 572 } 573 if ($use == 'literal') { 574 $xml .= "<$name$xmlns $atts>"; 575 } else { 576 $xml .= "<$name$xmlns$type_str$atts>"; 577 } 578 foreach($val as $k => $v){ 579 // Apache Map 580 if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { 581 $xml .= '<item>'; 582 $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); 583 $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); 584 $xml .= '</item>'; 585 } else { 586 $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); 587 } 588 } 589 $xml .= "</$name>"; 590 } 591 break; 592 default: 593 $xml .= 'not detected, got '.gettype($val).' for '.$val; 594 break; 595 } 596 return $xml; 597 } 598 599 /** 600 * serializes a message 601 * 602 * @param string $body the XML of the SOAP body 603 * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers 604 * @param array $namespaces optional the namespaces used in generating the body and headers 605 * @param string $style optional (rpc|document) 606 * @param string $use optional (encoded|literal) 607 * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) 608 * @return string the message 609 * @access public 610 */ 611 function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ 612 // TODO: add an option to automatically run utf8_encode on $body and $headers 613 // if $this->soap_defencoding is UTF-8. Not doing this automatically allows 614 // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 615 616 $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); 617 $this->debug("headers:"); 618 $this->appendDebug($this->varDump($headers)); 619 $this->debug("namespaces:"); 620 $this->appendDebug($this->varDump($namespaces)); 621 622 // serialize namespaces 623 $ns_string = ''; 624 foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ 625 $ns_string .= " xmlns:$k=\"$v\""; 626 } 627 if($encodingStyle) { 628 $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; 629 } 630 631 // serialize headers 632 if($headers){ 633 if (is_array($headers)) { 634 $xml = ''; 635 foreach ($headers as $header) { 636 $xml .= $this->serialize_val($header, false, false, false, false, false, $use); 637 } 638 $headers = $xml; 639 $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); 640 } 641 $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>"; 642 } 643 // serialize envelope 644 return 645 '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">". 646 '<SOAP-ENV:Envelope'.$ns_string.">". 647 $headers. 648 "<SOAP-ENV:Body>". 649 $body. 650 "</SOAP-ENV:Body>". 651 "</SOAP-ENV:Envelope>"; 652 } 653 654 /** 655 * formats a string to be inserted into an HTML stream 656 * 657 * @param string $str The string to format 658 * @return string The formatted string 659 * @access public 660 * @deprecated 661 */ 662 function formatDump($str){ 663 $str = htmlspecialchars($str); 664 return nl2br($str); 665 } 666 667 /** 668 * contracts (changes namespace to prefix) a qualified name 669 * 670 * @param string $qname qname 671 * @return string contracted qname 672 * @access private 673 */ 674 function contractQname($qname){ 675 // get element namespace 676 //$this->xdebug("Contract $qname"); 677 if (strrpos($qname, ':')) { 678 // get unqualified name 679 $name = substr($qname, strrpos($qname, ':') + 1); 680 // get ns 681 $ns = substr($qname, 0, strrpos($qname, ':')); 682 $p = $this->getPrefixFromNamespace($ns); 683 if ($p) { 684 return $p . ':' . $name; 685 } 686 return $qname; 687 } else { 688 return $qname; 689 } 690 } 691 692 /** 693 * expands (changes prefix to namespace) a qualified name 694 * 695 * @param string $string qname 696 * @return string expanded qname 697 * @access private 698 */ 699 function expandQname($qname){ 700 // get element prefix 701 if(strpos($qname,':') && !ereg('^http://',$qname)){ 702 // get unqualified name 703 $name = substr(strstr($qname,':'),1); 704 // get ns prefix 705 $prefix = substr($qname,0,strpos($qname,':')); 706 if(isset($this->namespaces[$prefix])){ 707 return $this->namespaces[$prefix].':'.$name; 708 } else { 709 return $qname; 710 } 711 } else { 712 return $qname; 713 } 714 } 715 716 /** 717 * returns the local part of a prefixed string 718 * returns the original string, if not prefixed 719 * 720 * @param string $str The prefixed string 721 * @return string The local part 722 * @access public 723 */ 724 function getLocalPart($str){ 725 if($sstr = strrchr($str,':')){ 726 // get unqualified name 727 return substr( $sstr, 1 ); 728 } else { 729 return $str; 730 } 731 } 732 733 /** 734 * returns the prefix part of a prefixed string 735 * returns false, if not prefixed 736 * 737 * @param string $str The prefixed string 738 * @return mixed The prefix or false if there is no prefix 739 * @access public 740 */ 741 function getPrefix($str){ 742 if($pos = strrpos($str,':')){ 743 // get prefix 744 return substr($str,0,$pos); 745 } 746 return false; 747 } 748 749 /** 750 * pass it a prefix, it returns a namespace 751 * 752 * @param string $prefix The prefix 753 * @return mixed The namespace, false if no namespace has the specified prefix 754 * @access public 755 */ 756 function getNamespaceFromPrefix($prefix){ 757 if (isset($this->namespaces[$prefix])) { 758 return $this->namespaces[$prefix]; 759 } 760 //$this->setError("No namespace registered for prefix '$prefix'"); 761 return false; 762 } 763 764 /** 765 * returns the prefix for a given namespace (or prefix) 766 * or false if no prefixes registered for the given namespace 767 * 768 * @param string $ns The namespace 769 * @return mixed The prefix, false if the namespace has no prefixes 770 * @access public 771 */ 772 function getPrefixFromNamespace($ns) { 773 foreach ($this->namespaces as $p => $n) { 774 if ($ns == $n || $ns == $p) { 775 $this->usedNamespaces[$p] = $n; 776 return $p; 777 } 778 } 779 return false; 780 } 781 782 /** 783 * returns the time in ODBC canonical form with microseconds 784 * 785 * @return string The time in ODBC canonical form with microseconds 786 * @access public 787 */ 788 function getmicrotime() { 789 if (function_exists('gettimeofday')) { 790 $tod = gettimeofday(); 791 $sec = $tod['sec']; 792 $usec = $tod['usec']; 793 } else { 794 $sec = time(); 795 $usec = 0; 796 } 797 return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); 798 } 799 800 /** 801 * Returns a string with the output of var_dump 802 * 803 * @param mixed $data The variable to var_dump 804 * @return string The output of var_dump 805 * @access public 806 */ 807 function varDump($data) { 808 ob_start(); 809 var_dump($data); 810 $ret_val = ob_get_contents(); 811 ob_end_clean(); 812 return $ret_val; 813 } 814 } 815 816 // XML Schema Datatype Helper Functions 817 818 //xsd:dateTime helpers 819 820 /** 821 * convert unix timestamp to ISO 8601 compliant date string 822 * 823 * @param string $timestamp Unix time stamp 824 * @access public 825 */ 826 function timestamp_to_iso8601($timestamp,$utc=true){ 827 $datestr = date('Y-m-d\TH:i:sO',$timestamp); 828 if($utc){ 829 $eregStr = 830 '([0-9]{4})-'. // centuries & years CCYY- 831 '([0-9]{2})-'. // months MM- 832 '([0-9]{2})'. // days DD 833 'T'. // separator T 834 '([0-9]{2}):'. // hours hh: 835 '([0-9]{2}):'. // minutes mm: 836 '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... 837 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's 838 839 if(ereg($eregStr,$datestr,$regs)){ 840 return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); 841 } 842 return false; 843 } else { 844 return $datestr; 845 } 846 } 847 848 /** 849 * convert ISO 8601 compliant date string to unix timestamp 850 * 851 * @param string $datestr ISO 8601 compliant date string 852 * @access public 853 */ 854 function iso8601_to_timestamp($datestr){ 855 $eregStr = 856 '([0-9]{4})-'. // centuries & years CCYY- 857 '([0-9]{2})-'. // months MM- 858 '([0-9]{2})'. // days DD 859 'T'. // separator T 860 '([0-9]{2}):'. // hours hh: 861 '([0-9]{2}):'. // minutes mm: 862 '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... 863 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's 864 if(ereg($eregStr,$datestr,$regs)){ 865 // not utc 866 if($regs[8] != 'Z'){ 867 $op = substr($regs[8],0,1); 868 $h = substr($regs[8],1,2); 869 $m = substr($regs[8],strlen($regs[8])-2,2); 870 if($op == '-'){ 871 $regs[4] = $regs[4] + $h; 872 $regs[5] = $regs[5] + $m; 873 } elseif($op == '+'){ 874 $regs[4] = $regs[4] - $h; 875 $regs[5] = $regs[5] - $m; 876 } 877 } 878 return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); 879 } else { 880 return false; 881 } 882 } 883 884 /** 885 * sleeps some number of microseconds 886 * 887 * @param string $usec the number of microseconds to sleep 888 * @access public 889 * @deprecated 890 */ 891 function usleepWindows($usec) 892 { 893 $start = gettimeofday(); 894 895 do 896 { 897 $stop = gettimeofday(); 898 $timePassed = 1000000 * ($stop['sec'] - $start['sec']) 899 + $stop['usec'] - $start['usec']; 900 } 901 while ($timePassed < $usec); 902 } 903 904 ?><?php 905 906 907 908 /** 909 * Contains information for a SOAP fault. 910 * Mainly used for returning faults from deployed functions 911 * in a server instance. 912 * @author Dietrich Ayala <dietrich@ganx4.com> 913 * @version $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 914 * @access public 915 */ 916 class soap_fault extends nusoap_base { 917 /** 918 * The fault code (client|server) 919 * @var string 920 * @access private 921 */ 922 var $faultcode; 923 /** 924 * The fault actor 925 * @var string 926 * @access private 927 */ 928 var $faultactor; 929 /** 930 * The fault string, a description of the fault 931 * @var string 932 * @access private 933 */ 934 var $faultstring; 935 /** 936 * The fault detail, typically a string or array of string 937 * @var mixed 938 * @access private 939 */ 940 var $faultdetail; 941 942 /** 943 * constructor 944 * 945 * @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server) 946 * @param string $faultactor only used when msg routed between multiple actors 947 * @param string $faultstring human readable error message 948 * @param mixed $faultdetail detail, typically a string or array of string 949 */ 950 function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ 951 parent::nusoap_base(); 952 $this->faultcode = $faultcode; 953 $this->faultactor = $faultactor; 954 $this->faultstring = $faultstring; 955 $this->faultdetail = $faultdetail; 956 } 957 958 /** 959 * serialize a fault 960 * 961 * @return string The serialization of the fault instance. 962 * @access public 963 */ 964 function serialize(){ 965 $ns_string = ''; 966 foreach($this->namespaces as $k => $v){ 967 $ns_string .= "\n xmlns:$k=\"$v\""; 968 } 969 $return_msg = 970 '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'. 971 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n". 972 '<SOAP-ENV:Body>'. 973 '<SOAP-ENV:Fault>'. 974 $this->serialize_val($this->faultcode, 'faultcode'). 975 $this->serialize_val($this->faultactor, 'faultactor'). 976 $this->serialize_val($this->faultstring, 'faultstring'). 977 $this->serialize_val($this->faultdetail, 'detail'). 978 '</SOAP-ENV:Fault>'. 979 '</SOAP-ENV:Body>'. 980 '</SOAP-ENV:Envelope>'; 981 return $return_msg; 982 } 983 } 984 985 986 987 ?><?php 988 989 990 991 /** 992 * parses an XML Schema, allows access to it's data, other utility methods 993 * no validation... yet. 994 * very experimental and limited. As is discussed on XML-DEV, I'm one of the people 995 * that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty 996 * tutorials I refer to :) 997 * 998 * @author Dietrich Ayala <dietrich@ganx4.com> 999 * @version $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 1000 * @access public 1001 */ 1002 class XMLSchema extends nusoap_base { 1003 1004 // files 1005 var $schema = ''; 1006 var $xml = ''; 1007 // namespaces 1008 var $enclosingNamespaces; 1009 // schema info 1010 var $schemaInfo = array(); 1011 var $schemaTargetNamespace = ''; 1012 // types, elements, attributes defined by the schema 1013 var $attributes = array(); 1014 var $complexTypes = array(); 1015 var $complexTypeStack = array(); 1016 var $currentComplexType = null; 1017 var $elements = array(); 1018 var $elementStack = array(); 1019 var $currentElement = null; 1020 var $simpleTypes = array(); 1021 var $simpleTypeStack = array(); 1022 var $currentSimpleType = null; 1023 // imports 1024 var $imports = array(); 1025 // parser vars 1026 var $parser; 1027 var $position = 0; 1028 var $depth = 0; 1029 var $depth_array = array(); 1030 var $message = array(); 1031 var $defaultNamespace = array(); 1032 1033 /** 1034 * constructor 1035 * 1036 * @param string $schema schema document URI 1037 * @param string $xml xml document URI 1038 * @param string $namespaces namespaces defined in enclosing XML 1039 * @access public 1040 */ 1041 function XMLSchema($schema='',$xml='',$namespaces=array()){ 1042 parent::nusoap_base(); 1043 $this->debug('xmlschema class instantiated, inside constructor'); 1044 // files 1045 $this->schema = $schema; 1046 $this->xml = $xml; 1047 1048 // namespaces 1049 $this->enclosingNamespaces = $namespaces; 1050 $this->namespaces = array_merge($this->namespaces, $namespaces); 1051 1052 // parse schema file 1053 if($schema != ''){ 1054 $this->debug('initial schema file: '.$schema); 1055 $this->parseFile($schema, 'schema'); 1056 } 1057 1058 // parse xml file 1059 if($xml != ''){ 1060 $this->debug('initial xml file: '.$xml); 1061 $this->parseFile($xml, 'xml'); 1062 } 1063 1064 } 1065 1066 /** 1067 * parse an XML file 1068 * 1069 * @param string $xml, path/URL to XML file 1070 * @param string $type, (schema | xml) 1071 * @return boolean 1072 * @access public 1073 */ 1074 function parseFile($xml,$type){ 1075 // parse xml file 1076 if($xml != ""){ 1077 $xmlStr = @join("",@file($xml)); 1078 if($xmlStr == ""){ 1079 $msg = 'Error reading XML from '.$xml; 1080 $this->setError($msg); 1081 $this->debug($msg); 1082 return false; 1083 } else { 1084 $this->debug("parsing $xml"); 1085 $this->parseString($xmlStr,$type); 1086 $this->debug("done parsing $xml"); 1087 return true; 1088 } 1089 } 1090 return false; 1091 } 1092 1093 /** 1094 * parse an XML string 1095 * 1096 * @param string $xml path or URL 1097 * @param string $type, (schema|xml) 1098 * @access private 1099 */ 1100 function parseString($xml,$type){ 1101 // parse xml string 1102 if($xml != ""){ 1103 1104 // Create an XML parser. 1105 $this->parser = xml_parser_create(); 1106 // Set the options for parsing the XML data. 1107 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 1108 1109 // Set the object for the parser. 1110 xml_set_object($this->parser, $this); 1111 1112 // Set the element handlers for the parser. 1113 if($type == "schema"){ 1114 xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); 1115 xml_set_character_data_handler($this->parser,'schemaCharacterData'); 1116 } elseif($type == "xml"){ 1117 xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); 1118 xml_set_character_data_handler($this->parser,'xmlCharacterData'); 1119 } 1120 1121 // Parse the XML file. 1122 if(!xml_parse($this->parser,$xml,true)){ 1123 // Display an error message. 1124 $errstr = sprintf('XML error parsing XML schema on line %d: %s', 1125 xml_get_current_line_number($this->parser), 1126 xml_error_string(xml_get_error_code($this->parser)) 1127 ); 1128 $this->debug($errstr); 1129 $this->debug("XML payload:\n" . $xml); 1130 $this->setError($errstr); 1131 } 1132 1133 xml_parser_free($this->parser); 1134 } else{ 1135 $this->debug('no xml passed to parseString()!!'); 1136 $this->setError('no xml passed to parseString()!!'); 1137 } 1138 } 1139 1140 /** 1141 * start-element handler 1142 * 1143 * @param string $parser XML parser object 1144 * @param string $name element name 1145 * @param string $attrs associative array of attributes 1146 * @access private 1147 */ 1148 function schemaStartElement($parser, $name, $attrs) { 1149 1150 // position in the total number of elements, starting from 0 1151 $pos = $this->position++; 1152 $depth = $this->depth++; 1153 // set self as current value for this depth 1154 $this->depth_array[$depth] = $pos; 1155 $this->message[$pos] = array('cdata' => ''); 1156 if ($depth > 0) { 1157 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; 1158 } else { 1159 $this->defaultNamespace[$pos] = false; 1160 } 1161 1162 // get element prefix 1163 if($prefix = $this->getPrefix($name)){ 1164 // get unqualified name 1165 $name = $this->getLocalPart($name); 1166 } else { 1167 $prefix = ''; 1168 } 1169 1170 // loop thru attributes, expanding, and registering namespace declarations 1171 if(count($attrs) > 0){ 1172 foreach($attrs as $k => $v){ 1173 // if ns declarations, add to class level array of valid namespaces 1174 if(ereg("^xmlns",$k)){ 1175 //$this->xdebug("$k: $v"); 1176 //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); 1177 if($ns_prefix = substr(strrchr($k,':'),1)){ 1178 //$this->xdebug("Add namespace[$ns_prefix] = $v"); 1179 $this->namespaces[$ns_prefix] = $v; 1180 } else { 1181 $this->defaultNamespace[$pos] = $v; 1182 if (! $this->getPrefixFromNamespace($v)) { 1183 $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; 1184 } 1185 } 1186 if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ 1187 $this->XMLSchemaVersion = $v; 1188 $this->namespaces['xsi'] = $v.'-instance'; 1189 } 1190 } 1191 } 1192 foreach($attrs as $k => $v){ 1193 // expand each attribute 1194 $k = strpos($k,':') ? $this->expandQname($k) : $k; 1195 $v = strpos($v,':') ? $this->expandQname($v) : $v; 1196 $eAttrs[$k] = $v; 1197 } 1198 $attrs = $eAttrs; 1199 } else { 1200 $attrs = array(); 1201 } 1202 // find status, register data 1203 switch($name){ 1204 case 'all': // (optional) compositor content for a complexType 1205 case 'choice': 1206 case 'group': 1207 case 'sequence': 1208 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); 1209 $this->complexTypes[$this->currentComplexType]['compositor'] = $name; 1210 //if($name == 'all' || $name == 'sequence'){ 1211 // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; 1212 //} 1213 break; 1214 case 'attribute': // complexType attribute 1215 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); 1216 $this->xdebug("parsing attribute:"); 1217 $this->appendDebug($this->varDump($attrs)); 1218 if (!isset($attrs['form'])) { 1219 $attrs['form'] = $this->schemaInfo['attributeFormDefault']; 1220 } 1221 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { 1222 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; 1223 if (!strpos($v, ':')) { 1224 // no namespace in arrayType attribute value... 1225 if ($this->defaultNamespace[$pos]) { 1226 // ...so use the default 1227 $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; 1228 } 1229 } 1230 } 1231 if(isset($attrs['name'])){ 1232 $this->attributes[$attrs['name']] = $attrs; 1233 $aname = $attrs['name']; 1234 } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ 1235 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { 1236 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; 1237 } else { 1238 $aname = ''; 1239 } 1240 } elseif(isset($attrs['ref'])){ 1241 $aname = $attrs['ref']; 1242 $this->attributes[$attrs['ref']] = $attrs; 1243 } 1244 1245 if($this->currentComplexType){ // This should *always* be 1246 $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; 1247 } 1248 // arrayType attribute 1249 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ 1250 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; 1251 $prefix = $this->getPrefix($aname); 1252 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ 1253 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; 1254 } else { 1255 $v = ''; 1256 } 1257 if(strpos($v,'[,]')){ 1258 $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; 1259 } 1260 $v = substr($v,0,strpos($v,'[')); // clip the [] 1261 if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ 1262 $v = $this->XMLSchemaVersion.':'.$v; 1263 } 1264 $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; 1265 } 1266 break; 1267 case 'complexContent': // (optional) content for a complexType 1268 break; 1269 case 'complexType': 1270 array_push($this->complexTypeStack, $this->currentComplexType); 1271 if(isset($attrs['name'])){ 1272 $this->xdebug('processing named complexType '.$attrs['name']); 1273 //$this->currentElement = false; 1274 $this->currentComplexType = $attrs['name']; 1275 $this->complexTypes[$this->currentComplexType] = $attrs; 1276 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; 1277 // This is for constructs like 1278 // <complexType name="ListOfString" base="soap:Array"> 1279 // <sequence> 1280 // <element name="string" type="xsd:string" 1281 // minOccurs="0" maxOccurs="unbounded" /> 1282 // </sequence> 1283 // </complexType> 1284 if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ 1285 $this->xdebug('complexType is unusual array'); 1286 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; 1287 } else { 1288 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; 1289 } 1290 }else{ 1291 $this->xdebug('processing unnamed complexType for element '.$this->currentElement); 1292 $this->currentComplexType = $this->currentElement . '_ContainedType'; 1293 //$this->currentElement = false; 1294 $this->complexTypes[$this->currentComplexType] = $attrs; 1295 $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; 1296 // This is for constructs like 1297 // <complexType name="ListOfString" base="soap:Array"> 1298 // <sequence> 1299 // <element name="string" type="xsd:string" 1300 // minOccurs="0" maxOccurs="unbounded" /> 1301 // </sequence> 1302 // </complexType> 1303 if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ 1304 $this->xdebug('complexType is unusual array'); 1305 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; 1306 } else { 1307 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; 1308 } 1309 } 1310 break; 1311 case 'element': 1312 array_push($this->elementStack, $this->currentElement); 1313 // elements defined as part of a complex type should 1314 // not really be added to $this->elements, but for some 1315 // reason, they are 1316 if (!isset($attrs['form'])) { 1317 $attrs['form'] = $this->schemaInfo['elementFormDefault']; 1318 } 1319 if(isset($attrs['type'])){ 1320 $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); 1321 if (! $this->getPrefix($attrs['type'])) { 1322 if ($this->defaultNamespace[$pos]) { 1323 $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; 1324 $this->xdebug('used default namespace to make type ' . $attrs['type']); 1325 } 1326 } 1327 // This is for constructs like 1328 // <complexType name="ListOfString" base="soap:Array"> 1329 // <sequence> 1330 // <element name="string" type="xsd:string" 1331 // minOccurs="0" maxOccurs="unbounded" /> 1332 // </sequence> 1333 // </complexType> 1334 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { 1335 $this->xdebug('arrayType for unusual array is ' . $attrs['type']); 1336 $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; 1337 } 1338 $this->currentElement = $attrs['name']; 1339 $this->elements[ $attrs['name'] ] = $attrs; 1340 $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; 1341 $ename = $attrs['name']; 1342 } elseif(isset($attrs['ref'])){ 1343 $this->xdebug("processing element as ref to ".$attrs['ref']); 1344 $this->currentElement = "ref to ".$attrs['ref']; 1345 $ename = $this->getLocalPart($attrs['ref']); 1346 } else { 1347 $this->xdebug("processing untyped element ".$attrs['name']); 1348 $this->currentElement = $attrs['name']; 1349 $this->elements[ $attrs['name'] ] = $attrs; 1350 $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; 1351 $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; 1352 $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; 1353 $ename = $attrs['name']; 1354 } 1355 if(isset($ename) && $this->currentComplexType){ 1356 $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; 1357 } 1358 break; 1359 case 'enumeration': // restriction value list member 1360 $this->xdebug('enumeration ' . $attrs['value']); 1361 if ($this->currentSimpleType) { 1362 $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; 1363 } elseif ($this->currentComplexType) { 1364 $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; 1365 } 1366 break; 1367 case 'extension': // simpleContent or complexContent type extension 1368 $this->xdebug('extension ' . $attrs['base']); 1369 if ($this->currentComplexType) { 1370 $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; 1371 } 1372 break; 1373 case 'import': 1374 if (isset($attrs['schemaLocation'])) { 1375 //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); 1376 $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); 1377 } else { 1378 //$this->xdebug('import namespace ' . $attrs['namespace']); 1379 $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); 1380 if (! $this->getPrefixFromNamespace($attrs['namespace'])) { 1381 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; 1382 } 1383 } 1384 break; 1385 case 'list': // simpleType value list 1386 break; 1387 case 'restriction': // simpleType, simpleContent or complexContent value restriction 1388 $this->xdebug('restriction ' . $attrs['base']); 1389 if($this->currentSimpleType){ 1390 $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; 1391 } elseif($this->currentComplexType){ 1392 $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; 1393 if(strstr($attrs['base'],':') == ':Array'){ 1394 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; 1395 } 1396 } 1397 break; 1398 case 'schema': 1399 $this->schemaInfo = $attrs; 1400 $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); 1401 if (isset($attrs['targetNamespace'])) { 1402 $this->schemaTargetNamespace = $attrs['targetNamespace']; 1403 } 1404 if (!isset($attrs['elementFormDefault'])) { 1405 $this->schemaInfo['elementFormDefault'] = 'unqualified'; 1406 } 1407 if (!isset($attrs['attributeFormDefault'])) { 1408 $this->schemaInfo['attributeFormDefault'] = 'unqualified'; 1409 } 1410 break; 1411 case 'simpleContent': // (optional) content for a complexType 1412 break; 1413 case 'simpleType': 1414 array_push($this->simpleTypeStack, $this->currentSimpleType); 1415 if(isset($attrs['name'])){ 1416 $this->xdebug("processing simpleType for name " . $attrs['name']); 1417 $this->currentSimpleType = $attrs['name']; 1418 $this->simpleTypes[ $attrs['name'] ] = $attrs; 1419 $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; 1420 $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; 1421 } else { 1422 $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); 1423 $this->currentSimpleType = $this->currentElement . '_ContainedType'; 1424 //$this->currentElement = false; 1425 $this->simpleTypes[$this->currentSimpleType] = $attrs; 1426 $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; 1427 } 1428 break; 1429 case 'union': // simpleType type list 1430 break; 1431 default: 1432 //$this->xdebug("do not have anything to do for element $name"); 1433 } 1434 } 1435 1436 /** 1437 * end-element handler 1438 * 1439 * @param string $parser XML parser object 1440 * @param string $name element name 1441 * @access private 1442 */ 1443 function schemaEndElement($parser, $name) { 1444 // bring depth down a notch 1445 $this->depth--; 1446 // position of current element is equal to the last value left in depth_array for my depth 1447 if(isset($this->depth_array[$this->depth])){ 1448 $pos = $this->depth_array[$this->depth]; 1449 } 1450 // get element prefix 1451 if ($prefix = $this->getPrefix($name)){ 1452 // get unqualified name 1453 $name = $this->getLocalPart($name); 1454 } else { 1455 $prefix = ''; 1456 } 1457 // move on... 1458 if($name == 'complexType'){ 1459 $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); 1460 $this->currentComplexType = array_pop($this->complexTypeStack); 1461 //$this->currentElement = false; 1462 } 1463 if($name == 'element'){ 1464 $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); 1465 $this->currentElement = array_pop($this->elementStack); 1466 } 1467 if($name == 'simpleType'){ 1468 $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); 1469 $this->currentSimpleType = array_pop($this->simpleTypeStack); 1470 } 1471 } 1472 1473 /** 1474 * element content handler 1475 * 1476 * @param string $parser XML parser object 1477 * @param string $data element content 1478 * @access private 1479 */ 1480 function schemaCharacterData($parser, $data){ 1481 $pos = $this->depth_array[$this->depth - 1]; 1482 $this->message[$pos]['cdata'] .= $data; 1483 } 1484 1485 /** 1486 * serialize the schema 1487 * 1488 * @access public 1489 */ 1490 function serializeSchema(){ 1491 1492 $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); 1493 $xml = ''; 1494 // imports 1495 if (sizeof($this->imports) > 0) { 1496 foreach($this->imports as $ns => $list) { 1497 foreach ($list as $ii) { 1498 if ($ii['location'] != '') { 1499 $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; 1500 } else { 1501 $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; 1502 } 1503 } 1504 } 1505 } 1506 // complex types 1507 foreach($this->complexTypes as $typeName => $attrs){ 1508 $contentStr = ''; 1509 // serialize child elements 1510 if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ 1511 foreach($attrs['elements'] as $element => $eParts){ 1512 if(isset($eParts['ref'])){ 1513 $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; 1514 } else { 1515 $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; 1516 foreach ($eParts as $aName => $aValue) { 1517 // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable 1518 if ($aName != 'name' && $aName != 'type') { 1519 $contentStr .= " $aName=\"$aValue\""; 1520 } 1521 } 1522 $contentStr .= "/>\n"; 1523 } 1524 } 1525 // compositor wraps elements 1526 if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { 1527 $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n"; 1528 } 1529 } 1530 // attributes 1531 if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ 1532 foreach($attrs['attrs'] as $attr => $aParts){ 1533 $contentStr .= " <$schemaPrefix:attribute"; 1534 foreach ($aParts as $a => $v) { 1535 if ($a == 'ref' || $a == 'type') { 1536 $contentStr .= " $a=\"".$this->contractQName($v).'"'; 1537 } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { 1538 $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; 1539 $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; 1540 } else { 1541 $contentStr .= " $a=\"$v\""; 1542 } 1543 } 1544 $contentStr .= "/>\n"; 1545 } 1546 } 1547 // if restriction 1548 if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ 1549 $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n"; 1550 // complex or simple content 1551 if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ 1552 $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n"; 1553 } 1554 } 1555 // finalize complex type 1556 if($contentStr != ''){ 1557 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n"; 1558 } else { 1559 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; 1560 } 1561 $xml .= $contentStr; 1562 } 1563 // simple types 1564 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ 1565 foreach($this->simpleTypes as $typeName => $eParts){ 1566 $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; 1567 if (isset($eParts['enumeration'])) { 1568 foreach ($eParts['enumeration'] as $e) { 1569 $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; 1570 } 1571 } 1572 $xml .= " </$schemaPrefix:simpleType>"; 1573 } 1574 } 1575 // elements 1576 if(isset($this->elements) && count($this->elements) > 0){ 1577 foreach($this->elements as $element => $eParts){ 1578 $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; 1579 } 1580 } 1581 // attributes 1582 if(isset($this->attributes) && count($this->attributes) > 0){ 1583 foreach($this->attributes as $attr => $aParts){ 1584 $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; 1585 } 1586 } 1587 // finish 'er up 1588 $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; 1589 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { 1590 $el .= " xmlns:$nsp=\"$ns\""; 1591 } 1592 $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n"; 1593 return $xml; 1594 } 1595 1596 /** 1597 * adds debug data to the clas level debug string 1598 * 1599 * @param string $string debug data 1600 * @access private 1601 */ 1602 function xdebug($string){ 1603 $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); 1604 } 1605 1606 /** 1607 * get the PHP type of a user defined type in the schema 1608 * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays 1609 * returns false if no type exists, or not w/ the given namespace 1610 * else returns a string that is either a native php type, or 'struct' 1611 * 1612 * @param string $type, name of defined type 1613 * @param string $ns, namespace of type 1614 * @return mixed 1615 * @access public 1616 * @deprecated 1617 */ 1618 function getPHPType($type,$ns){ 1619 if(isset($this->typemap[$ns][$type])){ 1620 //print "found type '$type' and ns $ns in typemap<br>"; 1621 return $this->typemap[$ns][$type]; 1622 } elseif(isset($this->complexTypes[$type])){ 1623 //print "getting type '$type' and ns $ns from complexTypes array<br>"; 1624 return $this->complexTypes[$type]['phpType']; 1625 } 1626 return false; 1627 } 1628 1629 /** 1630 * returns an associative array of information about a given type 1631 * returns false if no type exists by the given name 1632 * 1633 * For a complexType typeDef = array( 1634 * 'restrictionBase' => '', 1635 * 'phpType' => '', 1636 * 'compositor' => '(sequence|all)', 1637 * 'elements' => array(), // refs to elements array 1638 * 'attrs' => array() // refs to attributes array 1639 * ... and so on (see addComplexType) 1640 * ) 1641 * 1642 * For simpleType or element, the array has different keys. 1643 * 1644 * @param string 1645 * @return mixed 1646 * @access public 1647 * @see addComplexType 1648 * @see addSimpleType 1649 * @see addElement 1650 */ 1651 function getTypeDef($type){ 1652 //$this->debug("in getTypeDef for type $type"); 1653 if(isset($this->complexTypes[$type])){ 1654 $this->xdebug("in getTypeDef, found complexType $type"); 1655 return $this->complexTypes[$type]; 1656 } elseif(isset($this->simpleTypes[$type])){ 1657 $this->xdebug("in getTypeDef, found simpleType $type"); 1658 if (!isset($this->simpleTypes[$type]['phpType'])) { 1659 // get info for type to tack onto the simple type 1660 // TODO: can this ever really apply (i.e. what is a simpleType really?) 1661 $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); 1662 $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); 1663 $etype = $this->getTypeDef($uqType); 1664 if ($etype) { 1665 $this->xdebug("in getTypeDef, found type for simpleType $type:"); 1666 $this->xdebug($this->varDump($etype)); 1667 if (isset($etype['phpType'])) { 1668 $this->simpleTypes[$type]['phpType'] = $etype['phpType']; 1669 } 1670 if (isset($etype['elements'])) { 1671 $this->simpleTypes[$type]['elements'] = $etype['elements']; 1672 } 1673 } 1674 } 1675 return $this->simpleTypes[$type]; 1676 } elseif(isset($this->elements[$type])){ 1677 $this->xdebug("in getTypeDef, found element $type"); 1678 if (!isset($this->elements[$type]['phpType'])) { 1679 // get info for type to tack onto the element 1680 $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); 1681 $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); 1682 $etype = $this->getTypeDef($uqType); 1683 if ($etype) { 1684 $this->xdebug("in getTypeDef, found type for element $type:"); 1685 $this->xdebug($this->varDump($etype)); 1686 if (isset($etype['phpType'])) { 1687 $this->elements[$type]['phpType'] = $etype['phpType']; 1688 } 1689 if (isset($etype['elements'])) { 1690 $this->elements[$type]['elements'] = $etype['elements']; 1691 } 1692 } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { 1693 $this->xdebug("in getTypeDef, element $type is an XSD type"); 1694 $this->elements[$type]['phpType'] = 'scalar'; 1695 } 1696 } 1697 return $this->elements[$type]; 1698 } elseif(isset($this->attributes[$type])){ 1699 $this->xdebug("in getTypeDef, found attribute $type"); 1700 return $this->attributes[$type]; 1701 } elseif (ereg('_ContainedType$', $type)) { 1702 $this->xdebug("in getTypeDef, have an untyped element $type"); 1703 $typeDef['typeClass'] = 'simpleType'; 1704 $typeDef['phpType'] = 'scalar'; 1705 $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; 1706 return $typeDef; 1707 } 1708 $this->xdebug("in getTypeDef, did not find $type"); 1709 return false; 1710 } 1711 1712 /** 1713 * returns a sample serialization of a given type, or false if no type by the given name 1714 * 1715 * @param string $type, name of type 1716 * @return mixed 1717 * @access public 1718 * @deprecated 1719 */ 1720 function serializeTypeDef($type){ 1721 //print "in sTD() for type $type<br>"; 1722 if($typeDef = $this->getTypeDef($type)){ 1723 $str .= '<'.$type; 1724 if(is_array($typeDef['attrs'])){ 1725 foreach($attrs as $attName => $data){ 1726 $str .= " $attName=\"{type = ".$data['type']."}\""; 1727 } 1728 } 1729 $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; 1730 if(count($typeDef['elements']) > 0){ 1731 $str .= ">"; 1732 foreach($typeDef['elements'] as $element => $eData){ 1733 $str .= $this->serializeTypeDef($element); 1734 } 1735 $str .= "</$type>"; 1736 } elseif($typeDef['typeClass'] == 'element') { 1737 $str .= "></$type>"; 1738 } else { 1739 $str .= "/>"; 1740 } 1741 return $str; 1742 } 1743 return false; 1744 } 1745 1746 /** 1747 * returns HTML form elements that allow a user 1748 * to enter values for creating an instance of the given type. 1749 * 1750 * @param string $name, name for type instance 1751 * @param string $type, name of type 1752 * @return string 1753 * @access public 1754 * @deprecated 1755 */ 1756 function typeToForm($name,$type){ 1757 // get typedef 1758 if($typeDef = $this->getTypeDef($type)){ 1759 // if struct 1760 if($typeDef['phpType'] == 'struct'){ 1761 $buffer .= '<table>'; 1762 foreach($typeDef['elements'] as $child => $childDef){ 1763 $buffer .= " 1764 <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td> 1765 <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>"; 1766 } 1767 $buffer .= '</table>'; 1768 // if array 1769 } elseif($typeDef['phpType'] == 'array'){ 1770 $buffer .= '<table>'; 1771 for($i=0;$i < 3; $i++){ 1772 $buffer .= " 1773 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td> 1774 <td><input type='text' name='parameters[".$name."][]'></td></tr>"; 1775 } 1776 $buffer .= '</table>'; 1777 // if scalar 1778 } else { 1779 $buffer .= "<input type='text' name='parameters[$name]'>"; 1780 } 1781 } else { 1782 $buffer .= "<input type='text' name='parameters[$name]'>"; 1783 } 1784 return $buffer; 1785 } 1786 1787 /** 1788 * adds a complex type to the schema 1789 * 1790 * example: array 1791 * 1792 * addType( 1793 * 'ArrayOfstring', 1794 * 'complexType', 1795 * 'array', 1796 * '', 1797 * 'SOAP-ENC:Array', 1798 * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), 1799 * 'xsd:string' 1800 * ); 1801 * 1802 * example: PHP associative array ( SOAP Struct ) 1803 * 1804 * addType( 1805 * 'SOAPStruct', 1806 * 'complexType', 1807 * 'struct', 1808 * 'all', 1809 * array('myVar'=> array('name'=>'myVar','type'=>'string') 1810 * ); 1811 * 1812 * @param name 1813 * @param typeClass (complexType|simpleType|attribute) 1814 * @param phpType: currently supported are array and struct (php assoc array) 1815 * @param compositor (all|sequence|choice) 1816 * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) 1817 * @param elements = array ( name = array(name=>'',type=>'') ) 1818 * @param attrs = array( 1819 * array( 1820 * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", 1821 * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" 1822 * ) 1823 * ) 1824 * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) 1825 * @access public 1826 * @see getTypeDef 1827 */ 1828 function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ 1829 $this->complexTypes[$name] = array( 1830 'name' => $name, 1831 'typeClass' => $typeClass, 1832 'phpType' => $phpType, 1833 'compositor'=> $compositor, 1834 'restrictionBase' => $restrictionBase, 1835 'elements' => $elements, 1836 'attrs' => $attrs, 1837 'arrayType' => $arrayType 1838 ); 1839 1840 $this->xdebug("addComplexType $name:"); 1841 $this->appendDebug($this->varDump($this->complexTypes[$name])); 1842 } 1843 1844 /** 1845 * adds a simple type to the schema 1846 * 1847 * @param string $name 1848 * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) 1849 * @param string $typeClass (should always be simpleType) 1850 * @param string $phpType (should always be scalar) 1851 * @param array $enumeration array of values 1852 * @access public 1853 * @see xmlschema 1854 * @see getTypeDef 1855 */ 1856 function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { 1857 $this->simpleTypes[$name] = array( 1858 'name' => $name, 1859 'typeClass' => $typeClass, 1860 'phpType' => $phpType, 1861 'type' => $restrictionBase, 1862 'enumeration' => $enumeration 1863 ); 1864 1865 $this->xdebug("addSimpleType $name:"); 1866 $this->appendDebug($this->varDump($this->simpleTypes[$name])); 1867 } 1868 1869 /** 1870 * adds an element to the schema 1871 * 1872 * @param array $attrs attributes that must include name and type 1873 * @see xmlschema 1874 * @access public 1875 */ 1876 function addElement($attrs) { 1877 if (! $this->getPrefix($attrs['type'])) { 1878 $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; 1879 } 1880 $this->elements[ $attrs['name'] ] = $attrs; 1881 $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; 1882 1883 $this->xdebug("addElement " . $attrs['name']); 1884 $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); 1885 } 1886 } 1887 1888 1889 1890 ?><?php 1891 1892 1893 1894 /** 1895 * For creating serializable abstractions of native PHP types. This class 1896 * allows element name/namespace, XSD type, and XML attributes to be 1897 * associated with a value. This is extremely useful when WSDL is not 1898 * used, but is also useful when WSDL is used with polymorphic types, including 1899 * xsd:anyType and user-defined types. 1900 * 1901 * @author Dietrich Ayala <dietrich@ganx4.com> 1902 * @version $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 1903 * @access public 1904 */ 1905 class soapval extends nusoap_base { 1906 /** 1907 * The XML element name 1908 * 1909 * @var string 1910 * @access private 1911 */ 1912 var $name; 1913 /** 1914 * The XML type name (string or false) 1915 * 1916 * @var mixed 1917 * @access private 1918 */ 1919 var $type; 1920 /** 1921 * The PHP value 1922 * 1923 * @var mixed 1924 * @access private 1925 */ 1926 var $value; 1927 /** 1928 * The XML element namespace (string or false) 1929 * 1930 * @var mixed 1931 * @access private 1932 */ 1933 var $element_ns; 1934 /** 1935 * The XML type namespace (string or false) 1936 * 1937 * @var mixed 1938 * @access private 1939 */ 1940 var $type_ns; 1941 /** 1942 * The XML element attributes (array or false) 1943 * 1944 * @var mixed 1945 * @access private 1946 */ 1947 var $attributes; 1948 1949 /** 1950 * constructor 1951 * 1952 * @param string $name optional name 1953 * @param mixed $type optional type name 1954 * @param mixed $value optional value 1955 * @param mixed $element_ns optional namespace of value 1956 * @param mixed $type_ns optional namespace of type 1957 * @param mixed $attributes associative array of attributes to add to element serialization 1958 * @access public 1959 */ 1960 function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { 1961 parent::nusoap_base(); 1962 $this->name = $name; 1963 $this->type = $type; 1964 $this->value = $value; 1965 $this->element_ns = $element_ns; 1966 $this->type_ns = $type_ns; 1967 $this->attributes = $attributes; 1968 } 1969 1970 /** 1971 * return serialized value 1972 * 1973 * @param string $use The WSDL use value (encoded|literal) 1974 * @return string XML data 1975 * @access public 1976 */ 1977 function serialize($use='encoded') { 1978 return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); 1979 } 1980 1981 /** 1982 * decodes a soapval object into a PHP native type 1983 * 1984 * @return mixed 1985 * @access public 1986 */ 1987 function decode(){ 1988 return $this->value; 1989 } 1990 } 1991 1992 1993 1994 ?><?php 1995 1996 1997 1998 /** 1999 * transport class for sending/receiving data via HTTP and HTTPS 2000 * NOTE: PHP must be compiled with the CURL extension for HTTPS support 2001 * 2002 * @author Dietrich Ayala <dietrich@ganx4.com> 2003 * @version $Id: nusoap.php,v 1.2 2007/01/03 14:44:42 moodler Exp $ 2004 * @access public 2005 */ 2006 class soap_transport_http extends nusoap_base { 2007 2008 var $url = ''; 2009 var $uri = ''; 2010 var $digest_uri = ''; 2011 var $scheme = ''; 2012 var $host = ''; 2013 var $port = ''; 2014 var $path = ''; 2015 var $request_method = 'POST'; 2016 var $protocol_version = '1.0'; 2017 var $encoding = ''; 2018 var $outgoing_headers = array(); 2019 var $incoming_headers = array(); 2020 var $incoming_cookies = array(); 2021 var $outgoing_payload = ''; 2022 var $incoming_payload = ''; 2023 var $useSOAPAction = true; 2024 var $persistentConnection = false; 2025 var $ch = false; // cURL handle 2026 var $username = ''; 2027 var $password = ''; 2028 var $authtype = ''; 2029 var $digestRequest = array(); 2030 var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) 2031 // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' 2032 // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' 2033 // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' 2034 // passphrase: SSL key password/passphrase 2035 // verifypeer: default is 1 2036 // verifyhost: default is 1 2037 2038 /** 2039 * constructor 2040 */ 2041 function soap_transport_http($url){ 2042 parent::nusoap_base(); 2043 $this->setURL($url); 2044 ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); 2045 $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; 2046 $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); 2047 } 2048 2049 function setURL($url) { 2050 $this->url = $url; 2051 2052 $u = parse_url($url); 2053 foreach($u as $k => $v){ 2054 $this->debug("$k = $v"); 2055 $this->$k = $v; 2056 } 2057 2058