PageRenderTime 71ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/administrator/components/com_virtuemart/classes/nusoap/nusoap.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 7993 lines | 6477 code | 205 blank | 1311 comment | 768 complexity | 42eea740f488ce7181aa724e56831550 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
  4. NuSOAP - Web Services Toolkit for PHP
  5. Copyright (c) 2002 NuSphere Corporation
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. The NuSOAP project home is:
  18. http://sourceforge.net/projects/nusoap/
  19. The primary support for NuSOAP is the mailing list:
  20. nusoap-general@lists.sourceforge.net
  21. If you have any questions or comments, please email:
  22. Dietrich Ayala
  23. dietrich@ganx4.com
  24. http://dietrich.ganx4.com/nusoap
  25. NuSphere Corporation
  26. http://www.nusphere.com
  27. */
  28. /*
  29. * Some of the standards implmented in whole or part by NuSOAP:
  30. *
  31. * SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
  32. * WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
  33. * SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
  34. * XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
  35. * Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
  36. * XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
  37. * RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
  38. * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
  39. * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
  40. */
  41. /* load classes
  42. // necessary classes
  43. require_once('class.soapclient.php');
  44. require_once('class.soap_val.php');
  45. require_once('class.soap_parser.php');
  46. require_once('class.soap_fault.php');
  47. // transport classes
  48. require_once('class.soap_transport_http.php');
  49. // optional add-on classes
  50. require_once('class.xmlschema.php');
  51. require_once('class.wsdl.php');
  52. // server class
  53. require_once('class.soap_server.php');*/
  54. // class variable emulation
  55. // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
  56. $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
  57. /**
  58. *
  59. * nusoap_base
  60. *
  61. * @author Dietrich Ayala <dietrich@ganx4.com>
  62. * @author Scott Nichol <snichol@users.sourceforge.net>
  63. * @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
  64. * @access public
  65. */
  66. class nusoap_base {
  67. /**
  68. * Identification for HTTP headers.
  69. *
  70. * @var string
  71. * @access private
  72. */
  73. var $title = 'NuSOAP';
  74. /**
  75. * Version for HTTP headers.
  76. *
  77. * @var string
  78. * @access private
  79. */
  80. var $version = '0.7.3';
  81. /**
  82. * CVS revision for HTTP headers.
  83. *
  84. * @var string
  85. * @access private
  86. */
  87. var $revision = '$Revision: 1.114 $';
  88. /**
  89. * Current error string (manipulated by getError/setError)
  90. *
  91. * @var string
  92. * @access private
  93. */
  94. var $error_str = '';
  95. /**
  96. * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
  97. *
  98. * @var string
  99. * @access private
  100. */
  101. var $debug_str = '';
  102. /**
  103. * toggles automatic encoding of special characters as entities
  104. * (should always be true, I think)
  105. *
  106. * @var boolean
  107. * @access private
  108. */
  109. var $charencoding = true;
  110. /**
  111. * the debug level for this instance
  112. *
  113. * @var integer
  114. * @access private
  115. */
  116. var $debugLevel;
  117. /**
  118. * set schema version
  119. *
  120. * @var string
  121. * @access public
  122. */
  123. var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
  124. /**
  125. * charset encoding for outgoing messages
  126. *
  127. * @var string
  128. * @access public
  129. */
  130. var $soap_defencoding = 'ISO-8859-1';
  131. //var $soap_defencoding = 'UTF-8';
  132. /**
  133. * namespaces in an array of prefix => uri
  134. *
  135. * this is "seeded" by a set of constants, but it may be altered by code
  136. *
  137. * @var array
  138. * @access public
  139. */
  140. var $namespaces = array(
  141. 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
  142. 'xsd' => 'http://www.w3.org/2001/XMLSchema',
  143. 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  144. 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
  145. );
  146. /**
  147. * namespaces used in the current context, e.g. during serialization
  148. *
  149. * @var array
  150. * @access private
  151. */
  152. var $usedNamespaces = array();
  153. /**
  154. * XML Schema types in an array of uri => (array of xml type => php type)
  155. * is this legacy yet?
  156. * no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
  157. * @var array
  158. * @access public
  159. */
  160. var $typemap = array(
  161. 'http://www.w3.org/2001/XMLSchema' => array(
  162. 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
  163. 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
  164. 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
  165. // abstract "any" types
  166. 'anyType'=>'string','anySimpleType'=>'string',
  167. // derived datatypes
  168. 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
  169. 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
  170. 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
  171. 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
  172. 'http://www.w3.org/2000/10/XMLSchema' => array(
  173. 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
  174. 'float'=>'double','dateTime'=>'string',
  175. 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
  176. 'http://www.w3.org/1999/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://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
  181. 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
  182. 'http://xml.apache.org/xml-soap' => array('Map')
  183. );
  184. /**
  185. * XML entities to convert
  186. *
  187. * @var array
  188. * @access public
  189. * @deprecated
  190. * @see expandEntities
  191. */
  192. var $xmlEntities = array('quot' => '"','amp' => '&',
  193. 'lt' => '<','gt' => '>','apos' => "'");
  194. /**
  195. * constructor
  196. *
  197. * @access public
  198. */
  199. function nusoap_base() {
  200. $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
  201. }
  202. /**
  203. * gets the global debug level, which applies to future instances
  204. *
  205. * @return integer Debug level 0-9, where 0 turns off
  206. * @access public
  207. */
  208. function getGlobalDebugLevel() {
  209. return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
  210. }
  211. /**
  212. * sets the global debug level, which applies to future instances
  213. *
  214. * @param int $level Debug level 0-9, where 0 turns off
  215. * @access public
  216. */
  217. function setGlobalDebugLevel($level) {
  218. $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
  219. }
  220. /**
  221. * gets the debug level for this instance
  222. *
  223. * @return int Debug level 0-9, where 0 turns off
  224. * @access public
  225. */
  226. function getDebugLevel() {
  227. return $this->debugLevel;
  228. }
  229. /**
  230. * sets the debug level for this instance
  231. *
  232. * @param int $level Debug level 0-9, where 0 turns off
  233. * @access public
  234. */
  235. function setDebugLevel($level) {
  236. $this->debugLevel = $level;
  237. }
  238. /**
  239. * adds debug data to the instance debug string with formatting
  240. *
  241. * @param string $string debug data
  242. * @access private
  243. */
  244. function debug($string){
  245. if ($this->debugLevel > 0) {
  246. $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
  247. }
  248. }
  249. /**
  250. * adds debug data to the instance debug string without formatting
  251. *
  252. * @param string $string debug data
  253. * @access public
  254. */
  255. function appendDebug($string){
  256. if ($this->debugLevel > 0) {
  257. // it would be nice to use a memory stream here to use
  258. // memory more efficiently
  259. $this->debug_str .= $string;
  260. }
  261. }
  262. /**
  263. * clears the current debug data for this instance
  264. *
  265. * @access public
  266. */
  267. function clearDebug() {
  268. // it would be nice to use a memory stream here to use
  269. // memory more efficiently
  270. $this->debug_str = '';
  271. }
  272. /**
  273. * gets the current debug data for this instance
  274. *
  275. * @return debug data
  276. * @access public
  277. */
  278. function &getDebug() {
  279. // it would be nice to use a memory stream here to use
  280. // memory more efficiently
  281. return $this->debug_str;
  282. }
  283. /**
  284. * gets the current debug data for this instance as an XML comment
  285. * this may change the contents of the debug data
  286. *
  287. * @return debug data as an XML comment
  288. * @access public
  289. */
  290. function &getDebugAsXMLComment() {
  291. // it would be nice to use a memory stream here to use
  292. // memory more efficiently
  293. while (strpos($this->debug_str, '--')) {
  294. $this->debug_str = str_replace('--', '- -', $this->debug_str);
  295. }
  296. $ret = "<!--\n" . $this->debug_str . "\n-->";
  297. return $ret;
  298. }
  299. /**
  300. * expands entities, e.g. changes '<' to '&lt;'.
  301. *
  302. * @param string $val The string in which to expand entities.
  303. * @access private
  304. */
  305. function expandEntities($val) {
  306. if ($this->charencoding) {
  307. $val = str_replace('&', '&amp;', $val);
  308. $val = str_replace("'", '&apos;', $val);
  309. $val = str_replace('"', '&quot;', $val);
  310. $val = str_replace('<', '&lt;', $val);
  311. $val = str_replace('>', '&gt;', $val);
  312. }
  313. return $val;
  314. }
  315. /**
  316. * returns error string if present
  317. *
  318. * @return mixed error string or false
  319. * @access public
  320. */
  321. function getError(){
  322. if($this->error_str != ''){
  323. return $this->error_str;
  324. }
  325. return false;
  326. }
  327. /**
  328. * sets error string
  329. *
  330. * @return boolean $string error string
  331. * @access private
  332. */
  333. function setError($str){
  334. $this->error_str = $str;
  335. }
  336. /**
  337. * detect if array is a simple array or a struct (associative array)
  338. *
  339. * @param mixed $val The PHP array
  340. * @return string (arraySimple|arrayStruct)
  341. * @access private
  342. */
  343. function isArraySimpleOrStruct($val) {
  344. $keyList = array_keys($val);
  345. foreach ($keyList as $keyListValue) {
  346. if (!is_int($keyListValue)) {
  347. return 'arrayStruct';
  348. }
  349. }
  350. return 'arraySimple';
  351. }
  352. /**
  353. * serializes PHP values in accordance w/ section 5. Type information is
  354. * not serialized if $use == 'literal'.
  355. *
  356. * @param mixed $val The value to serialize
  357. * @param string $name The name (local part) of the XML element
  358. * @param string $type The XML schema type (local part) for the element
  359. * @param string $name_ns The namespace for the name of the XML element
  360. * @param string $type_ns The namespace for the type of the element
  361. * @param array $attributes The attributes to serialize as name=>value pairs
  362. * @param string $use The WSDL "use" (encoded|literal)
  363. * @param boolean $soapval Whether this is called from soapval.
  364. * @return string The serialized element, possibly with child elements
  365. * @access public
  366. */
  367. function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
  368. $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
  369. $this->appendDebug('value=' . $this->varDump($val));
  370. $this->appendDebug('attributes=' . $this->varDump($attributes));
  371. if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
  372. $this->debug("serialize_val: serialize soapval");
  373. $xml = $val->serialize($use);
  374. $this->appendDebug($val->getDebug());
  375. $val->clearDebug();
  376. $this->debug("serialize_val of soapval returning $xml");
  377. return $xml;
  378. }
  379. // force valid name if necessary
  380. if (is_numeric($name)) {
  381. $name = '__numeric_' . $name;
  382. } elseif (! $name) {
  383. $name = 'noname';
  384. }
  385. // if name has ns, add ns prefix to name
  386. $xmlns = '';
  387. if($name_ns){
  388. $prefix = 'nu'.rand(1000,9999);
  389. $name = $prefix.':'.$name;
  390. $xmlns .= " xmlns:$prefix=\"$name_ns\"";
  391. }
  392. // if type is prefixed, create type prefix
  393. if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
  394. // need to fix this. shouldn't default to xsd if no ns specified
  395. // w/o checking against typemap
  396. $type_prefix = 'xsd';
  397. } elseif($type_ns){
  398. $type_prefix = 'ns'.rand(1000,9999);
  399. $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
  400. }
  401. // serialize attributes if present
  402. $atts = '';
  403. if($attributes){
  404. foreach($attributes as $k => $v){
  405. $atts .= " $k=\"".$this->expandEntities($v).'"';
  406. }
  407. }
  408. // serialize null value
  409. if (is_null($val)) {
  410. $this->debug("serialize_val: serialize null");
  411. if ($use == 'literal') {
  412. // TODO: depends on minOccurs
  413. $xml = "<$name$xmlns$atts/>";
  414. $this->debug("serialize_val returning $xml");
  415. return $xml;
  416. } else {
  417. if (isset($type) && isset($type_prefix)) {
  418. $type_str = " xsi:type=\"$type_prefix:$type\"";
  419. } else {
  420. $type_str = '';
  421. }
  422. $xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
  423. $this->debug("serialize_val returning $xml");
  424. return $xml;
  425. }
  426. }
  427. // serialize if an xsd built-in primitive type
  428. if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
  429. $this->debug("serialize_val: serialize xsd built-in primitive type");
  430. if (is_bool($val)) {
  431. if ($type == 'boolean') {
  432. $val = $val ? 'true' : 'false';
  433. } elseif (! $val) {
  434. $val = 0;
  435. }
  436. } else if (is_string($val)) {
  437. $val = $this->expandEntities($val);
  438. }
  439. if ($use == 'literal') {
  440. $xml = "<$name$xmlns$atts>$val</$name>";
  441. $this->debug("serialize_val returning $xml");
  442. return $xml;
  443. } else {
  444. $xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
  445. $this->debug("serialize_val returning $xml");
  446. return $xml;
  447. }
  448. }
  449. // detect type and serialize
  450. $xml = '';
  451. switch(true) {
  452. case (is_bool($val) || $type == 'boolean'):
  453. $this->debug("serialize_val: serialize boolean");
  454. if ($type == 'boolean') {
  455. $val = $val ? 'true' : 'false';
  456. } elseif (! $val) {
  457. $val = 0;
  458. }
  459. if ($use == 'literal') {
  460. $xml .= "<$name$xmlns$atts>$val</$name>";
  461. } else {
  462. $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
  463. }
  464. break;
  465. case (is_int($val) || is_long($val) || $type == 'int'):
  466. $this->debug("serialize_val: serialize int");
  467. if ($use == 'literal') {
  468. $xml .= "<$name$xmlns$atts>$val</$name>";
  469. } else {
  470. $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
  471. }
  472. break;
  473. case (is_float($val)|| is_double($val) || $type == 'float'):
  474. $this->debug("serialize_val: serialize float");
  475. if ($use == 'literal') {
  476. $xml .= "<$name$xmlns$atts>$val</$name>";
  477. } else {
  478. $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
  479. }
  480. break;
  481. case (is_string($val) || $type == 'string'):
  482. $this->debug("serialize_val: serialize 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. $this->debug("serialize_val: serialize object");
  492. if (get_class($val) == 'soapval') {
  493. $this->debug("serialize_val: serialize soapval object");
  494. $pXml = $val->serialize($use);
  495. $this->appendDebug($val->getDebug());
  496. $val->clearDebug();
  497. } else {
  498. if (! $name) {
  499. $name = get_class($val);
  500. $this->debug("In serialize_val, used class name $name as element name");
  501. } else {
  502. $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
  503. }
  504. foreach(get_object_vars($val) as $k => $v){
  505. $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
  506. }
  507. }
  508. if(isset($type) && isset($type_prefix)){
  509. $type_str = " xsi:type=\"$type_prefix:$type\"";
  510. } else {
  511. $type_str = '';
  512. }
  513. if ($use == 'literal') {
  514. $xml .= "<$name$xmlns$atts>$pXml</$name>";
  515. } else {
  516. $xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
  517. }
  518. break;
  519. break;
  520. case (is_array($val) || $type):
  521. // detect if struct or array
  522. $valueType = $this->isArraySimpleOrStruct($val);
  523. if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
  524. $this->debug("serialize_val: serialize array");
  525. $i = 0;
  526. if(is_array($val) && count($val)> 0){
  527. foreach($val as $v){
  528. if(is_object($v) && get_class($v) == 'soapval'){
  529. $tt_ns = $v->type_ns;
  530. $tt = $v->type;
  531. } elseif (is_array($v)) {
  532. $tt = $this->isArraySimpleOrStruct($v);
  533. } else {
  534. $tt = gettype($v);
  535. }
  536. $array_types[$tt] = 1;
  537. // TODO: for literal, the name should be $name
  538. $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
  539. ++$i;
  540. }
  541. if(count($array_types) > 1){
  542. $array_typename = 'xsd:anyType';
  543. } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
  544. if ($tt == 'integer') {
  545. $tt = 'int';
  546. }
  547. $array_typename = 'xsd:'.$tt;
  548. } elseif(isset($tt) && $tt == 'arraySimple'){
  549. $array_typename = 'SOAP-ENC:Array';
  550. } elseif(isset($tt) && $tt == 'arrayStruct'){
  551. $array_typename = 'unnamed_struct_use_soapval';
  552. } else {
  553. // if type is prefixed, create type prefix
  554. if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
  555. $array_typename = 'xsd:' . $tt;
  556. } elseif ($tt_ns) {
  557. $tt_prefix = 'ns' . rand(1000, 9999);
  558. $array_typename = "$tt_prefix:$tt";
  559. $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
  560. } else {
  561. $array_typename = $tt;
  562. }
  563. }
  564. $array_type = $i;
  565. if ($use == 'literal') {
  566. $type_str = '';
  567. } else if (isset($type) && isset($type_prefix)) {
  568. $type_str = " xsi:type=\"$type_prefix:$type\"";
  569. } else {
  570. $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
  571. }
  572. // empty array
  573. } else {
  574. if ($use == 'literal') {
  575. $type_str = '';
  576. } else if (isset($type) && isset($type_prefix)) {
  577. $type_str = " xsi:type=\"$type_prefix:$type\"";
  578. } else {
  579. $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
  580. }
  581. }
  582. // TODO: for array in literal, there is no wrapper here
  583. $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
  584. } else {
  585. // got a struct
  586. $this->debug("serialize_val: serialize struct");
  587. if(isset($type) && isset($type_prefix)){
  588. $type_str = " xsi:type=\"$type_prefix:$type\"";
  589. } else {
  590. $type_str = '';
  591. }
  592. if ($use == 'literal') {
  593. $xml .= "<$name$xmlns$atts>";
  594. } else {
  595. $xml .= "<$name$xmlns$type_str$atts>";
  596. }
  597. foreach($val as $k => $v){
  598. // Apache Map
  599. if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
  600. $xml .= '<item>';
  601. $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
  602. $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
  603. $xml .= '</item>';
  604. } else {
  605. $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
  606. }
  607. }
  608. $xml .= "</$name>";
  609. }
  610. break;
  611. default:
  612. $this->debug("serialize_val: serialize unknown");
  613. $xml .= 'not detected, got '.gettype($val).' for '.$val;
  614. break;
  615. }
  616. $this->debug("serialize_val returning $xml");
  617. return $xml;
  618. }
  619. /**
  620. * serializes a message
  621. *
  622. * @param string $body the XML of the SOAP body
  623. * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
  624. * @param array $namespaces optional the namespaces used in generating the body and headers
  625. * @param string $style optional (rpc|document)
  626. * @param string $use optional (encoded|literal)
  627. * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
  628. * @return string the message
  629. * @access public
  630. */
  631. function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
  632. // TODO: add an option to automatically run utf8_encode on $body and $headers
  633. // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
  634. // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
  635. $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
  636. $this->debug("headers:");
  637. $this->appendDebug($this->varDump($headers));
  638. $this->debug("namespaces:");
  639. $this->appendDebug($this->varDump($namespaces));
  640. // serialize namespaces
  641. $ns_string = '';
  642. foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
  643. $ns_string .= " xmlns:$k=\"$v\"";
  644. }
  645. if($encodingStyle) {
  646. $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
  647. }
  648. // serialize headers
  649. if($headers){
  650. if (is_array($headers)) {
  651. $xml = '';
  652. foreach ($headers as $k => $v) {
  653. if (is_object($v) && get_class($v) == 'soapval') {
  654. $xml .= $this->serialize_val($v, false, false, false, false, false, $use);
  655. } else {
  656. $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
  657. }
  658. }
  659. $headers = $xml;
  660. $this->debug("In serializeEnvelope, serialized array of headers to $headers");
  661. }
  662. $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
  663. }
  664. // serialize envelope
  665. return
  666. '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
  667. '<SOAP-ENV:Envelope'.$ns_string.">".
  668. $headers.
  669. "<SOAP-ENV:Body>".
  670. $body.
  671. "</SOAP-ENV:Body>".
  672. "</SOAP-ENV:Envelope>";
  673. }
  674. /**
  675. * formats a string to be inserted into an HTML stream
  676. *
  677. * @param string $str The string to format
  678. * @return string The formatted string
  679. * @access public
  680. * @deprecated
  681. */
  682. function formatDump($str){
  683. $str = htmlspecialchars($str);
  684. return nl2br($str);
  685. }
  686. /**
  687. * contracts (changes namespace to prefix) a qualified name
  688. *
  689. * @param string $qname qname
  690. * @return string contracted qname
  691. * @access private
  692. */
  693. function contractQname($qname){
  694. // get element namespace
  695. //$this->xdebug("Contract $qname");
  696. if (strrpos($qname, ':')) {
  697. // get unqualified name
  698. $name = substr($qname, strrpos($qname, ':') + 1);
  699. // get ns
  700. $ns = substr($qname, 0, strrpos($qname, ':'));
  701. $p = $this->getPrefixFromNamespace($ns);
  702. if ($p) {
  703. return $p . ':' . $name;
  704. }
  705. return $qname;
  706. } else {
  707. return $qname;
  708. }
  709. }
  710. /**
  711. * expands (changes prefix to namespace) a qualified name
  712. *
  713. * @param string $qname qname
  714. * @return string expanded qname
  715. * @access private
  716. */
  717. function expandQname($qname){
  718. // get element prefix
  719. if(strpos($qname,':') && !ereg('^http://',$qname)){
  720. // get unqualified name
  721. $name = substr(strstr($qname,':'),1);
  722. // get ns prefix
  723. $prefix = substr($qname,0,strpos($qname,':'));
  724. if(isset($this->namespaces[$prefix])){
  725. return $this->namespaces[$prefix].':'.$name;
  726. } else {
  727. return $qname;
  728. }
  729. } else {
  730. return $qname;
  731. }
  732. }
  733. /**
  734. * returns the local part of a prefixed string
  735. * returns the original string, if not prefixed
  736. *
  737. * @param string $str The prefixed string
  738. * @return string The local part
  739. * @access public
  740. */
  741. function getLocalPart($str){
  742. if($sstr = strrchr($str,':')){
  743. // get unqualified name
  744. return substr( $sstr, 1 );
  745. } else {
  746. return $str;
  747. }
  748. }
  749. /**
  750. * returns the prefix part of a prefixed string
  751. * returns false, if not prefixed
  752. *
  753. * @param string $str The prefixed string
  754. * @return mixed The prefix or false if there is no prefix
  755. * @access public
  756. */
  757. function getPrefix($str){
  758. if($pos = strrpos($str,':')){
  759. // get prefix
  760. return substr($str,0,$pos);
  761. }
  762. return false;
  763. }
  764. /**
  765. * pass it a prefix, it returns a namespace
  766. *
  767. * @param string $prefix The prefix
  768. * @return mixed The namespace, false if no namespace has the specified prefix
  769. * @access public
  770. */
  771. function getNamespaceFromPrefix($prefix){
  772. if (isset($this->namespaces[$prefix])) {
  773. return $this->namespaces[$prefix];
  774. }
  775. //$this->setError("No namespace registered for prefix '$prefix'");
  776. return false;
  777. }
  778. /**
  779. * returns the prefix for a given namespace (or prefix)
  780. * or false if no prefixes registered for the given namespace
  781. *
  782. * @param string $ns The namespace
  783. * @return mixed The prefix, false if the namespace has no prefixes
  784. * @access public
  785. */
  786. function getPrefixFromNamespace($ns) {
  787. foreach ($this->namespaces as $p => $n) {
  788. if ($ns == $n || $ns == $p) {
  789. $this->usedNamespaces[$p] = $n;
  790. return $p;
  791. }
  792. }
  793. return false;
  794. }
  795. /**
  796. * returns the time in ODBC canonical form with microseconds
  797. *
  798. * @return string The time in ODBC canonical form with microseconds
  799. * @access public
  800. */
  801. function getmicrotime() {
  802. if (function_exists('gettimeofday')) {
  803. $tod = gettimeofday();
  804. $sec = $tod['sec'];
  805. $usec = $tod['usec'];
  806. } else {
  807. $sec = time();
  808. $usec = 0;
  809. }
  810. return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
  811. }
  812. /**
  813. * Returns a string with the output of var_dump
  814. *
  815. * @param mixed $data The variable to var_dump
  816. * @return string The output of var_dump
  817. * @access public
  818. */
  819. function varDump($data) {
  820. ob_start();
  821. var_dump($data);
  822. $ret_val = ob_get_contents();
  823. ob_end_clean();
  824. return $ret_val;
  825. }
  826. /**
  827. * represents the object as a string
  828. *
  829. * @return string
  830. * @access public
  831. */
  832. function __toString() {
  833. return $this->varDump($this);
  834. }
  835. }
  836. // XML Schema Datatype Helper Functions
  837. //xsd:dateTime helpers
  838. /**
  839. * convert unix timestamp to ISO 8601 compliant date string
  840. *
  841. * @param string $timestamp Unix time stamp
  842. * @param boolean $utc Whether the time stamp is UTC or local
  843. * @access public
  844. */
  845. function timestamp_to_iso8601($timestamp,$utc=true){
  846. $datestr = date('Y-m-d\TH:i:sO',$timestamp);
  847. if($utc){
  848. $eregStr =
  849. '([0-9]{4})-'. // centuries & years CCYY-
  850. '([0-9]{2})-'. // months MM-
  851. '([0-9]{2})'. // days DD
  852. 'T'. // separator T
  853. '([0-9]{2}):'. // hours hh:
  854. '([0-9]{2}):'. // minutes mm:
  855. '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
  856. '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
  857. if(ereg($eregStr,$datestr,$regs)){
  858. return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
  859. }
  860. return false;
  861. } else {
  862. return $datestr;
  863. }
  864. }
  865. /**
  866. * convert ISO 8601 compliant date string to unix timestamp
  867. *
  868. * @param string $datestr ISO 8601 compliant date string
  869. * @access public
  870. */
  871. function iso8601_to_timestamp($datestr){
  872. $eregStr =
  873. '([0-9]{4})-'. // centuries & years CCYY-
  874. '([0-9]{2})-'. // months MM-
  875. '([0-9]{2})'. // days DD
  876. 'T'. // separator T
  877. '([0-9]{2}):'. // hours hh:
  878. '([0-9]{2}):'. // minutes mm:
  879. '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
  880. '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
  881. if(ereg($eregStr,$datestr,$regs)){
  882. // not utc
  883. if($regs[8] != 'Z'){
  884. $op = substr($regs[8],0,1);
  885. $h = substr($regs[8],1,2);
  886. $m = substr($regs[8],strlen($regs[8])-2,2);
  887. if($op == '-'){
  888. $regs[4] = $regs[4] + $h;
  889. $regs[5] = $regs[5] + $m;
  890. } elseif($op == '+'){
  891. $regs[4] = $regs[4] - $h;
  892. $regs[5] = $regs[5] - $m;
  893. }
  894. }
  895. return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
  896. // return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
  897. } else {
  898. return false;
  899. }
  900. }
  901. /**
  902. * sleeps some number of microseconds
  903. *
  904. * @param string $usec the number of microseconds to sleep
  905. * @access public
  906. * @deprecated
  907. */
  908. function usleepWindows($usec)
  909. {
  910. $start = gettimeofday();
  911. do
  912. {
  913. $stop = gettimeofday();
  914. $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
  915. + $stop['usec'] - $start['usec'];
  916. }
  917. while ($timePassed < $usec);
  918. }
  919. ?><?php
  920. /**
  921. * Contains information for a SOAP fault.
  922. * Mainly used for returning faults from deployed functions
  923. * in a server instance.
  924. * @author Dietrich Ayala <dietrich@ganx4.com>
  925. * @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
  926. * @access public
  927. */
  928. class nusoap_fault extends nusoap_base {
  929. /**
  930. * The fault code (client|server)
  931. * @var string
  932. * @access private
  933. */
  934. var $faultcode;
  935. /**
  936. * The fault actor
  937. * @var string
  938. * @access private
  939. */
  940. var $faultactor;
  941. /**
  942. * The fault string, a description of the fault
  943. * @var string
  944. * @access private
  945. */
  946. var $faultstring;
  947. /**
  948. * The fault detail, typically a string or array of string
  949. * @var mixed
  950. * @access private
  951. */
  952. var $faultdetail;
  953. /**
  954. * constructor
  955. *
  956. * @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server)
  957. * @param string $faultactor only used when msg routed between multiple actors
  958. * @param string $faultstring human readable error message
  959. * @param mixed $faultdetail detail, typically a string or array of string
  960. */
  961. function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
  962. parent::nusoap_base();
  963. $this->faultcode = $faultcode;
  964. $this->faultactor = $faultactor;
  965. $this->faultstring = $faultstring;
  966. $this->faultdetail = $faultdetail;
  967. }
  968. /**
  969. * serialize a fault
  970. *
  971. * @return string The serialization of the fault instance.
  972. * @access public
  973. */
  974. function serialize(){
  975. $ns_string = '';
  976. foreach($this->namespaces as $k => $v){
  977. $ns_string .= "\n xmlns:$k=\"$v\"";
  978. }
  979. $return_msg =
  980. '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
  981. '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
  982. '<SOAP-ENV:Body>'.
  983. '<SOAP-ENV:Fault>'.
  984. $this->serialize_val($this->faultcode, 'faultcode').
  985. $this->serialize_val($this->faultactor, 'faultactor').
  986. $this->serialize_val($this->faultstring, 'faultstring').
  987. $this->serialize_val($this->faultdetail, 'detail').
  988. '</SOAP-ENV:Fault>'.
  989. '</SOAP-ENV:Body>'.
  990. '</SOAP-ENV:Envelope>';
  991. return $return_msg;
  992. }
  993. }
  994. /**
  995. * Backward compatibility
  996. */
  997. class soap_fault extends nusoap_fault {
  998. }
  999. ?><?php
  1000. /**
  1001. * parses an XML Schema, allows access to it's data, other utility methods.
  1002. * imperfect, no validation... yet, but quite functional.
  1003. *
  1004. * @author Dietrich Ayala <dietrich@ganx4.com>
  1005. * @author Scott Nichol <snichol@users.sourceforge.net>
  1006. * @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
  1007. * @access public
  1008. */
  1009. class nusoap_xmlschema extends nusoap_base {
  1010. // files
  1011. var $schema = '';
  1012. var $xml = '';
  1013. // namespaces
  1014. var $enclosingNamespaces;
  1015. // schema info
  1016. var $schemaInfo = array();
  1017. var $schemaTargetNamespace = '';
  1018. // types, elements, attributes defined by the schema
  1019. var $attributes = array();
  1020. var $complexTypes = array();
  1021. var $complexTypeStack = array();
  1022. var $currentComplexType = null;
  1023. var $elements = array();
  1024. var $elementStack = array();
  1025. var $currentElement = null;
  1026. var $simpleTypes = array();
  1027. var $simpleTypeStack = array();
  1028. var $currentSimpleType = null;
  1029. // imports
  1030. var $imports = array();
  1031. // parser vars
  1032. var $parser;
  1033. var $position = 0;
  1034. var $depth = 0;
  1035. var $depth_array = array();
  1036. var $message = array();
  1037. var $defaultNamespace = array();
  1038. /**
  1039. * constructor
  1040. *
  1041. * @param string $schema schema document URI
  1042. * @param string $xml xml document URI
  1043. * @param string $namespaces namespaces defined in enclosing XML
  1044. * @access public
  1045. */
  1046. function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
  1047. parent::nusoap_base();
  1048. $this->debug('nusoap_xmlschema class instantiated, inside constructor');
  1049. // files
  1050. $this->schema = $schema;
  1051. $this->xml = $xml;
  1052. // namespaces
  1053. $this->enclosingNamespaces = $namespaces;
  1054. $this->namespaces = array_merge($this->namespaces, $namespaces);
  1055. // parse schema file
  1056. if($schema != ''){
  1057. $this->debug('initial schema file: '.$schema);
  1058. $this->parseFile($schema, 'schema');
  1059. }
  1060. // parse xml file
  1061. if($xml != ''){
  1062. $this->debug('initial xml file: '.$xml);
  1063. $this->parseFile($xml, 'xml');
  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. * parse an XML string
  1094. *
  1095. * @param string $xml path or URL
  1096. * @param string $type (schema|xml)
  1097. * @access private
  1098. */
  1099. function parseString($xml,$type){
  1100. // parse xml string
  1101. if($xml != ""){
  1102. // Create an XML parser.
  1103. $this->parser = xml_parser_create();
  1104. // Set the options for parsing the XML data.
  1105. xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
  1106. // Set the object for the parser.
  1107. xml_set_object($this->parser, $this);
  1108. // Set the element handlers for the parser.
  1109. if($type == "schema"){
  1110. xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
  1111. xml_set_character_data_handler($this->parser,'schemaCharacterData');
  1112. } elseif($type == "xml"){
  1113. xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
  1114. xml_set_character_data_handler($this->parser,'xmlCharacterData');
  1115. }
  1116. // Parse the XML file.
  1117. if(!xml_parse($this->parser,$xml,true)){
  1118. // Display an error message.
  1119. $errstr = sprintf('XML error parsing XML schema on line %d: %s',
  1120. xml_get_current_line_number($this->parser),
  1121. xml_error_string(xml_get_error_code($this->parser))
  1122. );
  1123. $this->debug($errstr);
  1124. $this->debug("XML payload:\n" . $xml);
  1125. $this->setError($errstr);
  1126. }
  1127. xml_parser_free($this->parser);
  1128. } else{
  1129. $this->debug('no xml passed to parseString()!!');
  1130. $this->setError('no xml passed to parseString()!!');
  1131. }
  1132. }
  1133. /**
  1134. * gets a type name for an unnamed type
  1135. *
  1136. * @param string Element name
  1137. * @return string A type name for an unnamed type
  1138. * @access private
  1139. */
  1140. function CreateTypeName($ename) {
  1141. $scope = '';
  1142. for ($i = 0; $i < count($this->complexTypeStack); $i++) {
  1143. $scope .= $this->complexTypeStack[$i] . '_';
  1144. }
  1145. return $scope . $ename . '_ContainedType';
  1146. }
  1147. /**
  1148. * start-element handler
  1149. *
  1150. * @param string $parser XML parser object
  1151. * @param string $name element name
  1152. * @param string $attrs associative array of attributes
  1153. * @access private
  1154. */
  1155. function schemaStartElement($parser, $name, $attrs) {
  1156. // position in the total number of elements, starting from 0
  1157. $pos = $this->position++;
  1158. $depth = $this->depth++;
  1159. // set self as current value for this depth
  1160. $this->depth_array[$depth] = $pos;
  1161. $this->message[$pos] = array('cdata' => '');
  1162. if ($depth > 0) {
  1163. $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
  1164. } else {
  1165. $this->defaultNamespace[$pos] = false;
  1166. }
  1167. // get element prefix
  1168. if($prefix = $this->getPrefix($name)){
  1169. // get unqualified name
  1170. $name = $this->getLocalPart($name);
  1171. } else {
  1172. $prefix = '';
  1173. }
  1174. // loop thru attributes, expanding, and registering namespace declarations
  1175. if(count($attrs) > 0){
  1176. foreach($attrs as $k => $v){
  1177. // if ns declarations, add to class level array of valid namespaces
  1178. if(ereg("^xmlns",$k)){
  1179. //$this->xdebug("$k: $v");
  1180. //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
  1181. if($ns_prefix = substr(strrchr($k,':'),1)){
  1182. //$this->xdebug("Add namespace[$ns_prefix] = $v");
  1183. $this->namespaces[$ns_prefix] = $v;
  1184. } else {
  1185. $this->defaultNamespace[$pos] = $v;
  1186. if (! $this->getPrefixFromNamespace($v)) {
  1187. $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
  1188. }
  1189. }
  1190. if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
  1191. $this->XMLSchemaVersion = $v;
  1192. $this->namespaces['xsi'] = $v.'-instance';
  1193. }
  1194. }
  1195. }
  1196. foreach($attrs as $k => $v){
  1197. // expand each attribute
  1198. $k = strpos($k,':') ? $this->expandQname($k) : $k;
  1199. $v = strpos($v,':') ? $this->expandQname($v) : $v;
  1200. $eAttrs[$k] = $v;
  1201. }
  1202. $attrs = $eAttrs;
  1203. } else {
  1204. $attrs = array();
  1205. }
  1206. // find status, register data
  1207. switch($name){
  1208. case 'all': // (optional) compositor content for a complexType
  1209. case 'choice':
  1210. case 'group':
  1211. case 'sequence':
  1212. //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
  1213. $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
  1214. //if($name == 'all' || $name == 'sequence'){
  1215. // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
  1216. //}
  1217. break;
  1218. case 'attribute': // complexType attribute
  1219. //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
  1220. $this->xdebug("parsing attribute:");
  1221. $this->appendDebug($this->varDump($attrs));
  1222. if (!isset($attrs['form'])) {
  1223. $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
  1224. }
  1225. if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
  1226. $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
  1227. if (!strpos($v, ':')) {
  1228. // no namespace in arrayType attribute value...
  1229. if ($this->defaultNamespace[$pos]) {
  1230. // ...so use the default
  1231. $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
  1232. }
  1233. }
  1234. }
  1235. if(isset($attrs['name'])){
  1236. $this->attributes[$attrs['name']] = $attrs;
  1237. $aname = $attrs['name'];
  1238. } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
  1239. if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
  1240. $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
  1241. } else {
  1242. $aname = '';
  1243. }
  1244. } elseif(isset($attrs['ref'])){
  1245. $aname = $attrs['ref'];
  1246. $this->attributes[$attrs['ref']] = $attrs;
  1247. }
  1248. if($this->currentComplexType){ // This should *always* be
  1249. $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
  1250. }
  1251. // arrayType attribute
  1252. if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
  1253. $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
  1254. $prefix = $this->getPrefix($aname);
  1255. if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
  1256. $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
  1257. } else {
  1258. $v = '';
  1259. }
  1260. if(strpos($v,'[,]')){
  1261. $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
  1262. }
  1263. $v = substr($v,0,strpos($v,'[')); // clip the []
  1264. if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
  1265. $v = $this->XMLSchemaVersion.':'.$v;
  1266. }
  1267. $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
  1268. }
  1269. break;
  1270. case 'complexContent': // (optional) content for a complexType
  1271. break;
  1272. case 'complexType':
  1273. array_push($this->complexTypeStack, $this->currentComplexType);
  1274. if(isset($attrs['name'])){
  1275. // TODO: what is the scope of named complexTypes that appear
  1276. // nested within other c complexTypes?
  1277. $this->xdebug('processing named complexType '.$attrs['name']);
  1278. //$this->currentElement = false;
  1279. $this->currentComplexType = $attrs['name'];
  1280. $this->complexTypes[$this->currentComplexType] = $attrs;
  1281. $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
  1282. // This is for constructs like
  1283. // <complexType name="ListOfString" base="soap:Array">
  1284. // <sequence>
  1285. // <element name="string" type="xsd:string"
  1286. // minOccurs="0" maxOccurs="unbounded" />
  1287. // </sequence>
  1288. // </complexType>
  1289. if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
  1290. $this->xdebug('complexType is unusual array');
  1291. $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
  1292. } else {
  1293. $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
  1294. }
  1295. } else {
  1296. $name = $this->CreateTypeName($this->currentElement);
  1297. $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
  1298. $this->currentComplexType = $name;
  1299. //$this->currentElement = false;
  1300. $this->complexTypes[$this->currentComplexType] = $attrs;
  1301. $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
  1302. // This is for constructs like
  1303. // <complexType name="ListOfString" base="soap:Array">
  1304. // <sequence>
  1305. // <element name="string" type="xsd:string"
  1306. // minOccurs="0" maxOccurs="unbounded" />
  1307. // </sequence>
  1308. // </complexType>
  1309. if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
  1310. $this->xdebug('complexType is unusual array');
  1311. $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
  1312. } else {
  1313. $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
  1314. }
  1315. }
  1316. break;
  1317. case 'element':
  1318. array_push($this->elementStack, $this->currentElement);
  1319. if (!isset($attrs['form'])) {
  1320. $attrs['form'] = $this->schemaInfo['elementFormDefault'];
  1321. }
  1322. if(isset($attrs['type'])){
  1323. $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
  1324. if (! $this->getPrefix($attrs['type'])) {
  1325. if ($this->defaultNamespace[$pos]) {
  1326. $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
  1327. $this->xdebug('used default namespace to make type ' . $attrs['type']);
  1328. }
  1329. }
  1330. // This is for constructs like
  1331. // <complexType name="ListOfString" base="soap:Array">
  1332. // <sequence>
  1333. // <element name="string" type="xsd:string"
  1334. // minOccurs="0" maxOccurs="unbounded" />
  1335. // </sequence>
  1336. // </complexType>
  1337. if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
  1338. $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
  1339. $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
  1340. }
  1341. $this->currentElement = $attrs['name'];
  1342. $ename = $attrs['name'];
  1343. } elseif(isset($attrs['ref'])){
  1344. $this->xdebug("processing element as ref to ".$attrs['ref']);
  1345. $this->currentElement = "ref to ".$attrs['ref'];
  1346. $ename = $this->getLocalPart($attrs['ref']);
  1347. } else {
  1348. $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
  1349. $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
  1350. $this->currentElement = $attrs['name'];
  1351. $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
  1352. $ename = $attrs['name'];
  1353. }
  1354. if (isset($ename) && $this->currentComplexType) {
  1355. $this->xdebug("add element $ename to complexType $this->currentComplexType");
  1356. $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
  1357. } elseif (!isset($attrs['ref'])) {
  1358. $this->xdebug("add element $ename to elements array");
  1359. $this->elements[ $attrs['name'] ] = $attrs;
  1360. $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
  1361. }
  1362. break;
  1363. case 'enumeration': // restriction value list member
  1364. $this->xdebug('enumeration ' . $attrs['value']);
  1365. if ($this->currentSimpleType) {
  1366. $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
  1367. } elseif ($this->currentComplexType) {
  1368. $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
  1369. }
  1370. break;
  1371. case 'extension': // simpleContent or complexContent type extension
  1372. $this->xdebug('extension ' . $attrs['base']);
  1373. if ($this->currentComplexType) {
  1374. $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
  1375. }
  1376. break;
  1377. case 'import':
  1378. if (isset($attrs['schemaLocation'])) {
  1379. //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
  1380. $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
  1381. } else {
  1382. //$this->xdebug('import namespace ' . $attrs['namespace']);
  1383. $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
  1384. if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
  1385. $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
  1386. }
  1387. }
  1388. break;
  1389. case 'list': // simpleType value list
  1390. break;
  1391. case 'restriction': // simpleType, simpleContent or complexContent value restriction
  1392. $this->xdebug('restriction ' . $attrs['base']);
  1393. if($this->currentSimpleType){
  1394. $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
  1395. } elseif($this->currentComplexType){
  1396. $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
  1397. if(strstr($attrs['base'],':') == ':Array'){
  1398. $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
  1399. }
  1400. }
  1401. break;
  1402. case 'schema':
  1403. $this->schemaInfo = $attrs;
  1404. $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
  1405. if (isset($attrs['targetNamespace'])) {
  1406. $this->schemaTargetNamespace = $attrs['targetNamespace'];
  1407. }
  1408. if (!isset($attrs['elementFormDefault'])) {
  1409. $this->schemaInfo['elementFormDefault'] = 'unqualified';
  1410. }
  1411. if (!isset($attrs['attributeFormDefault'])) {
  1412. $this->schemaInfo['attributeFormDefault'] = 'unqualified';
  1413. }
  1414. break;
  1415. case 'simpleContent': // (optional) content for a complexType
  1416. break;
  1417. case 'simpleType':
  1418. array_push($this->simpleTypeStack, $this->currentSimpleType);
  1419. if(isset($attrs['name'])){
  1420. $this->xdebug("processing simpleType for name " . $attrs['name']);
  1421. $this->currentSimpleType = $attrs['name'];
  1422. $this->simpleTypes[ $attrs['name'] ] = $attrs;
  1423. $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
  1424. $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
  1425. } else {
  1426. $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
  1427. $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
  1428. $this->currentSimpleType = $name;
  1429. //$this->currentElement = false;
  1430. $this->simpleTypes[$this->currentSimpleType] = $attrs;
  1431. $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
  1432. }
  1433. break;
  1434. case 'union': // simpleType type list
  1435. break;
  1436. default:
  1437. //$this->xdebug("do not have anything to do for element $name");
  1438. }
  1439. }
  1440. /**
  1441. * end-element handler
  1442. *
  1443. * @param string $parser XML parser object
  1444. * @param string $name element name
  1445. * @access private
  1446. */
  1447. function schemaEndElement($parser, $name) {
  1448. // bring depth down a notch
  1449. $this->depth--;
  1450. // position of current element is equal to the last value left in depth_array for my depth
  1451. if(isset($this->depth_array[$this->depth])){
  1452. $pos = $this->depth_array[$this->depth];
  1453. }
  1454. // get element prefix
  1455. if ($prefix = $this->getPrefix($name)){
  1456. // get unqualified name
  1457. $name = $this->getLocalPart($name);
  1458. } else {
  1459. $prefix = '';
  1460. }
  1461. // move on...
  1462. if($name == 'complexType'){
  1463. $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
  1464. $this->currentComplexType = array_pop($this->complexTypeStack);
  1465. //$this->currentElement = false;
  1466. }
  1467. if($name == 'element'){
  1468. $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
  1469. $this->currentElement = array_pop($this->elementStack);
  1470. }
  1471. if($name == 'simpleType'){
  1472. $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
  1473. $this->currentSimpleType = array_pop($this->simpleType

Large files files are truncated, but you can click here to view the full file