ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.xmlschema.php
Go to the documentation of this file.
1 <?php
2 
3 
4 
5 
17 class XMLSchema extends nusoap_base {
18 
19  // files
20  var $schema = '';
21  var $xml = '';
22  // namespaces
24  // schema info
25  var $schemaInfo = array();
26  var $schemaTargetNamespace = '';
27  // types, elements, attributes defined by the schema
28  var $attributes = array();
29  var $complexTypes = array();
30  var $complexTypeStack = array();
31  var $currentComplexType = null;
32  var $elements = array();
33  var $elementStack = array();
34  var $currentElement = null;
35  var $simpleTypes = array();
36  var $simpleTypeStack = array();
37  var $currentSimpleType = null;
38  // imports
39  var $imports = array();
40  // parser vars
41  var $parser;
42  var $position = 0;
43  var $depth = 0;
44  var $depth_array = array();
45  var $message = array();
46  var $defaultNamespace = array();
47 
56  function XMLSchema($schema='',$xml='',$namespaces=array()){
58  $this->debug('xmlschema class instantiated, inside constructor');
59  // files
60  $this->schema = $schema;
61  $this->xml = $xml;
62 
63  // namespaces
64  $this->enclosingNamespaces = $namespaces;
65  $this->namespaces = array_merge($this->namespaces, $namespaces);
66 
67  // parse schema file
68  if($schema != ''){
69  $this->debug('initial schema file: '.$schema);
70  $this->parseFile($schema, 'schema');
71  }
72 
73  // parse xml file
74  if($xml != ''){
75  $this->debug('initial xml file: '.$xml);
76  $this->parseFile($xml, 'xml');
77  }
78 
79  }
80 
89  function parseFile($xml,$type){
90  // parse xml file
91  if($xml != ""){
92  $xmlStr = @join("",@file($xml));
93  if($xmlStr == ""){
94  $msg = 'Error reading XML from '.$xml;
95  $this->setError($msg);
96  $this->debug($msg);
97  return false;
98  } else {
99  $this->debug("parsing $xml");
100  $this->parseString($xmlStr,$type);
101  $this->debug("done parsing $xml");
102  return true;
103  }
104  }
105  return false;
106  }
107 
115  function parseString($xml,$type){
116  // parse xml string
117  if($xml != ""){
118 
119  // Create an XML parser.
120  $this->parser = xml_parser_create();
121  // Set the options for parsing the XML data.
122  xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
123 
124  // Set the object for the parser.
125  xml_set_object($this->parser, $this);
126 
127  // Set the element handlers for the parser.
128  if($type == "schema"){
129  xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
130  xml_set_character_data_handler($this->parser,'schemaCharacterData');
131  } elseif($type == "xml"){
132  xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
133  xml_set_character_data_handler($this->parser,'xmlCharacterData');
134  }
135 
136  // Parse the XML file.
137  if(!xml_parse($this->parser,$xml,true)){
138  // Display an error message.
139  $errstr = sprintf('XML error parsing XML schema on line %d: %s',
140  xml_get_current_line_number($this->parser),
141  xml_error_string(xml_get_error_code($this->parser))
142  );
143  $this->debug($errstr);
144  $this->debug("XML payload:\n" . $xml);
145  $this->setError($errstr);
146  }
147 
148  xml_parser_free($this->parser);
149  } else{
150  $this->debug('no xml passed to parseString()!!');
151  $this->setError('no xml passed to parseString()!!');
152  }
153  }
154 
163  function schemaStartElement($parser, $name, $attrs) {
164 
165  // position in the total number of elements, starting from 0
166  $pos = $this->position++;
167  $depth = $this->depth++;
168  // set self as current value for this depth
169  $this->depth_array[$depth] = $pos;
170  $this->message[$pos] = array('cdata' => '');
171  if ($depth > 0) {
172  $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
173  } else {
174  $this->defaultNamespace[$pos] = false;
175  }
176 
177  // get element prefix
178  if($prefix = $this->getPrefix($name)){
179  // get unqualified name
180  $name = $this->getLocalPart($name);
181  } else {
182  $prefix = '';
183  }
184 
185  // loop thru attributes, expanding, and registering namespace declarations
186  if(count($attrs) > 0){
187  foreach($attrs as $k => $v){
188  // if ns declarations, add to class level array of valid namespaces
189  if(ereg("^xmlns",$k)){
190  //$this->xdebug("$k: $v");
191  //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
192  if($ns_prefix = substr(strrchr($k,':'),1)){
193  //$this->xdebug("Add namespace[$ns_prefix] = $v");
194  $this->namespaces[$ns_prefix] = $v;
195  } else {
196  $this->defaultNamespace[$pos] = $v;
197  if (! $this->getPrefixFromNamespace($v)) {
198  $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
199  }
200  }
201  if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
202  $this->XMLSchemaVersion = $v;
203  $this->namespaces['xsi'] = $v.'-instance';
204  }
205  }
206  }
207  foreach($attrs as $k => $v){
208  // expand each attribute
209  $k = strpos($k,':') ? $this->expandQname($k) : $k;
210  $v = strpos($v,':') ? $this->expandQname($v) : $v;
211  $eAttrs[$k] = $v;
212  }
213  $attrs = $eAttrs;
214  } else {
215  $attrs = array();
216  }
217  // find status, register data
218  switch($name){
219  case 'all': // (optional) compositor content for a complexType
220  case 'choice':
221  case 'group':
222  case 'sequence':
223  //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
224  $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
225  //if($name == 'all' || $name == 'sequence'){
226  // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
227  //}
228  break;
229  case 'attribute': // complexType attribute
230  //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
231  $this->xdebug("parsing attribute:");
232  $this->appendDebug($this->varDump($attrs));
233  if (!isset($attrs['form'])) {
234  $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
235  }
236  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
237  $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
238  if (!strpos($v, ':')) {
239  // no namespace in arrayType attribute value...
240  if ($this->defaultNamespace[$pos]) {
241  // ...so use the default
242  $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
243  }
244  }
245  }
246  if(isset($attrs['name'])){
247  $this->attributes[$attrs['name']] = $attrs;
248  $aname = $attrs['name'];
249  } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
250  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
251  $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
252  } else {
253  $aname = '';
254  }
255  } elseif(isset($attrs['ref'])){
256  $aname = $attrs['ref'];
257  $this->attributes[$attrs['ref']] = $attrs;
258  }
259 
260  if($this->currentComplexType){ // This should *always* be
261  $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
262  }
263  // arrayType attribute
264  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
265  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
266  $prefix = $this->getPrefix($aname);
267  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
268  $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
269  } else {
270  $v = '';
271  }
272  if(strpos($v,'[,]')){
273  $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
274  }
275  $v = substr($v,0,strpos($v,'[')); // clip the []
276  if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
277  $v = $this->XMLSchemaVersion.':'.$v;
278  }
279  $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
280  }
281  break;
282  case 'complexContent': // (optional) content for a complexType
283  break;
284  case 'complexType':
285  array_push($this->complexTypeStack, $this->currentComplexType);
286  if(isset($attrs['name'])){
287  $this->xdebug('processing named complexType '.$attrs['name']);
288  //$this->currentElement = false;
289  $this->currentComplexType = $attrs['name'];
290  $this->complexTypes[$this->currentComplexType] = $attrs;
291  $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
292  // This is for constructs like
293  // <complexType name="ListOfString" base="soap:Array">
294  // <sequence>
295  // <element name="string" type="xsd:string"
296  // minOccurs="0" maxOccurs="unbounded" />
297  // </sequence>
298  // </complexType>
299  if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
300  $this->xdebug('complexType is unusual array');
301  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
302  } else {
303  $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
304  }
305  }else{
306  $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
307  $this->currentComplexType = $this->currentElement . '_ContainedType';
308  //$this->currentElement = false;
309  $this->complexTypes[$this->currentComplexType] = $attrs;
310  $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
311  // This is for constructs like
312  // <complexType name="ListOfString" base="soap:Array">
313  // <sequence>
314  // <element name="string" type="xsd:string"
315  // minOccurs="0" maxOccurs="unbounded" />
316  // </sequence>
317  // </complexType>
318  if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
319  $this->xdebug('complexType is unusual array');
320  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
321  } else {
322  $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
323  }
324  }
325  break;
326  case 'element':
327  array_push($this->elementStack, $this->currentElement);
328  // elements defined as part of a complex type should
329  // not really be added to $this->elements, but for some
330  // reason, they are
331  if (!isset($attrs['form'])) {
332  $attrs['form'] = $this->schemaInfo['elementFormDefault'];
333  }
334  if(isset($attrs['type'])){
335  $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
336  if (! $this->getPrefix($attrs['type'])) {
337  if ($this->defaultNamespace[$pos]) {
338  $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
339  $this->xdebug('used default namespace to make type ' . $attrs['type']);
340  }
341  }
342  // This is for constructs like
343  // <complexType name="ListOfString" base="soap:Array">
344  // <sequence>
345  // <element name="string" type="xsd:string"
346  // minOccurs="0" maxOccurs="unbounded" />
347  // </sequence>
348  // </complexType>
349  if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
350  $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
351  $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
352  }
353  $this->currentElement = $attrs['name'];
354  $this->elements[ $attrs['name'] ] = $attrs;
355  $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
356  $ename = $attrs['name'];
357  } elseif(isset($attrs['ref'])){
358  $this->xdebug("processing element as ref to ".$attrs['ref']);
359  $this->currentElement = "ref to ".$attrs['ref'];
360  $ename = $this->getLocalPart($attrs['ref']);
361  } else {
362  $this->xdebug("processing untyped element ".$attrs['name']);
363  $this->currentElement = $attrs['name'];
364  $this->elements[ $attrs['name'] ] = $attrs;
365  $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
366  $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
367  $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
368  $ename = $attrs['name'];
369  }
370  if(isset($ename) && $this->currentComplexType){
371  $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
372  }
373  break;
374  case 'enumeration': // restriction value list member
375  $this->xdebug('enumeration ' . $attrs['value']);
376  if ($this->currentSimpleType) {
377  $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
378  } elseif ($this->currentComplexType) {
379  $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
380  }
381  break;
382  case 'extension': // simpleContent or complexContent type extension
383  $this->xdebug('extension ' . $attrs['base']);
384  if ($this->currentComplexType) {
385  $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
386  }
387  break;
388  case 'import':
389  if (isset($attrs['schemaLocation'])) {
390  //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
391  $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
392  } else {
393  //$this->xdebug('import namespace ' . $attrs['namespace']);
394  $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
395  if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
396  $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
397  }
398  }
399  break;
400  case 'list': // simpleType value list
401  break;
402  case 'restriction': // simpleType, simpleContent or complexContent value restriction
403  $this->xdebug('restriction ' . $attrs['base']);
404  if($this->currentSimpleType){
405  $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
406  } elseif($this->currentComplexType){
407  $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
408  if(strstr($attrs['base'],':') == ':Array'){
409  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
410  }
411  }
412  break;
413  case 'schema':
414  $this->schemaInfo = $attrs;
415  $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
416  if (isset($attrs['targetNamespace'])) {
417  $this->schemaTargetNamespace = $attrs['targetNamespace'];
418  }
419  if (!isset($attrs['elementFormDefault'])) {
420  $this->schemaInfo['elementFormDefault'] = 'unqualified';
421  }
422  if (!isset($attrs['attributeFormDefault'])) {
423  $this->schemaInfo['attributeFormDefault'] = 'unqualified';
424  }
425  break;
426  case 'simpleContent': // (optional) content for a complexType
427  break;
428  case 'simpleType':
429  array_push($this->simpleTypeStack, $this->currentSimpleType);
430  if(isset($attrs['name'])){
431  $this->xdebug("processing simpleType for name " . $attrs['name']);
432  $this->currentSimpleType = $attrs['name'];
433  $this->simpleTypes[ $attrs['name'] ] = $attrs;
434  $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
435  $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
436  } else {
437  $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
438  $this->currentSimpleType = $this->currentElement . '_ContainedType';
439  //$this->currentElement = false;
440  $this->simpleTypes[$this->currentSimpleType] = $attrs;
441  $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
442  }
443  break;
444  case 'union': // simpleType type list
445  break;
446  default:
447  //$this->xdebug("do not have anything to do for element $name");
448  }
449  }
450 
459  // bring depth down a notch
460  $this->depth--;
461  // position of current element is equal to the last value left in depth_array for my depth
462  if(isset($this->depth_array[$this->depth])){
463  $pos = $this->depth_array[$this->depth];
464  }
465  // get element prefix
466  if ($prefix = $this->getPrefix($name)){
467  // get unqualified name
468  $name = $this->getLocalPart($name);
469  } else {
470  $prefix = '';
471  }
472  // move on...
473  if($name == 'complexType'){
474  $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
475  $this->currentComplexType = array_pop($this->complexTypeStack);
476  //$this->currentElement = false;
477  }
478  if($name == 'element'){
479  $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
480  $this->currentElement = array_pop($this->elementStack);
481  }
482  if($name == 'simpleType'){
483  $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
484  $this->currentSimpleType = array_pop($this->simpleTypeStack);
485  }
486  }
487 
496  $pos = $this->depth_array[$this->depth - 1];
497  $this->message[$pos]['cdata'] .= $data;
498  }
499 
505  function serializeSchema(){
506 
507  $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
508  $xml = '';
509  // imports
510  if (sizeof($this->imports) > 0) {
511  foreach($this->imports as $ns => $list) {
512  foreach ($list as $ii) {
513  if ($ii['location'] != '') {
514  $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
515  } else {
516  $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
517  }
518  }
519  }
520  }
521  // complex types
522  foreach($this->complexTypes as $typeName => $attrs){
523  $contentStr = '';
524  // serialize child elements
525  if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
526  foreach($attrs['elements'] as $element => $eParts){
527  if(isset($eParts['ref'])){
528  $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
529  } else {
530  $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
531  foreach ($eParts as $aName => $aValue) {
532  // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
533  if ($aName != 'name' && $aName != 'type') {
534  $contentStr .= " $aName=\"$aValue\"";
535  }
536  }
537  $contentStr .= "/>\n";
538  }
539  }
540  // compositor wraps elements
541  if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
542  $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
543  }
544  }
545  // attributes
546  if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
547  foreach($attrs['attrs'] as $attr => $aParts){
548  $contentStr .= " <$schemaPrefix:attribute";
549  foreach ($aParts as $a => $v) {
550  if ($a == 'ref' || $a == 'type') {
551  $contentStr .= " $a=\"".$this->contractQName($v).'"';
552  } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
553  $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
554  $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
555  } else {
556  $contentStr .= " $a=\"$v\"";
557  }
558  }
559  $contentStr .= "/>\n";
560  }
561  }
562  // if restriction
563  if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
564  $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
565  // complex or simple content
566  if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
567  $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
568  }
569  }
570  // finalize complex type
571  if($contentStr != ''){
572  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
573  } else {
574  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
575  }
576  $xml .= $contentStr;
577  }
578  // simple types
579  if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
580  foreach($this->simpleTypes as $typeName => $eParts){
581  $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
582  if (isset($eParts['enumeration'])) {
583  foreach ($eParts['enumeration'] as $e) {
584  $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
585  }
586  }
587  $xml .= " </$schemaPrefix:simpleType>";
588  }
589  }
590  // elements
591  if(isset($this->elements) && count($this->elements) > 0){
592  foreach($this->elements as $element => $eParts){
593  $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
594  }
595  }
596  // attributes
597  if(isset($this->attributes) && count($this->attributes) > 0){
598  foreach($this->attributes as $attr => $aParts){
599  $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
600  }
601  }
602  // finish 'er up
603  $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
604  foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
605  $el .= " xmlns:$nsp=\"$ns\"\n";
606  }
607  $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
608  return $xml;
609  }
610 
617  function xdebug($string){
618  $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
619  }
620 
633  function getPHPType($type,$ns){
634  if(isset($this->typemap[$ns][$type])){
635  //print "found type '$type' and ns $ns in typemap<br>";
636  return $this->typemap[$ns][$type];
637  } elseif(isset($this->complexTypes[$type])){
638  //print "getting type '$type' and ns $ns from complexTypes array<br>";
639  return $this->complexTypes[$type]['phpType'];
640  }
641  return false;
642  }
643 
666  function getTypeDef($type){
667  //$this->debug("in getTypeDef for type $type");
668  if(isset($this->complexTypes[$type])){
669  $this->xdebug("in getTypeDef, found complexType $type");
670  return $this->complexTypes[$type];
671  } elseif(isset($this->simpleTypes[$type])){
672  $this->xdebug("in getTypeDef, found simpleType $type");
673  if (!isset($this->simpleTypes[$type]['phpType'])) {
674  // get info for type to tack onto the simple type
675  // TODO: can this ever really apply (i.e. what is a simpleType really?)
676  $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
677  $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
678  $etype = $this->getTypeDef($uqType);
679  if ($etype) {
680  $this->xdebug("in getTypeDef, found type for simpleType $type:");
681  $this->xdebug($this->varDump($etype));
682  if (isset($etype['phpType'])) {
683  $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
684  }
685  if (isset($etype['elements'])) {
686  $this->simpleTypes[$type]['elements'] = $etype['elements'];
687  }
688  }
689  }
690  return $this->simpleTypes[$type];
691  } elseif(isset($this->elements[$type])){
692  $this->xdebug("in getTypeDef, found element $type");
693  if (!isset($this->elements[$type]['phpType'])) {
694  // get info for type to tack onto the element
695  $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
696  $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
697  $etype = $this->getTypeDef($uqType);
698  if ($etype) {
699  $this->xdebug("in getTypeDef, found type for element $type:");
700  $this->xdebug($this->varDump($etype));
701  if (isset($etype['phpType'])) {
702  $this->elements[$type]['phpType'] = $etype['phpType'];
703  }
704  if (isset($etype['elements'])) {
705  $this->elements[$type]['elements'] = $etype['elements'];
706  }
707  } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
708  $this->xdebug("in getTypeDef, element $type is an XSD type");
709  $this->elements[$type]['phpType'] = 'scalar';
710  }
711  }
712  return $this->elements[$type];
713  } elseif(isset($this->attributes[$type])){
714  $this->xdebug("in getTypeDef, found attribute $type");
715  return $this->attributes[$type];
716  } elseif (ereg('_ContainedType$', $type)) {
717  $this->xdebug("in getTypeDef, have an untyped element $type");
718  $typeDef['typeClass'] = 'simpleType';
719  $typeDef['phpType'] = 'scalar';
720  $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
721  return $typeDef;
722  }
723  $this->xdebug("in getTypeDef, did not find $type");
724  return false;
725  }
726 
736  //print "in sTD() for type $type<br>";
737  if($typeDef = $this->getTypeDef($type)){
738  $str .= '<'.$type;
739  if(is_array($typeDef['attrs'])){
740  foreach($attrs as $attName => $data){
741  $str .= " $attName=\"{type = ".$data['type']."}\"";
742  }
743  }
744  $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
745  if(count($typeDef['elements']) > 0){
746  $str .= ">";
747  foreach($typeDef['elements'] as $element => $eData){
748  $str .= $this->serializeTypeDef($element);
749  }
750  $str .= "</$type>";
751  } elseif($typeDef['typeClass'] == 'element') {
752  $str .= "></$type>";
753  } else {
754  $str .= "/>";
755  }
756  return $str;
757  }
758  return false;
759  }
760 
771  function typeToForm($name,$type){
772  // get typedef
773  if($typeDef = $this->getTypeDef($type)){
774  // if struct
775  if($typeDef['phpType'] == 'struct'){
776  $buffer .= '<table>';
777  foreach($typeDef['elements'] as $child => $childDef){
778  $buffer .= "
779  <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
780  <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
781  }
782  $buffer .= '</table>';
783  // if array
784  } elseif($typeDef['phpType'] == 'array'){
785  $buffer .= '<table>';
786  for($i=0;$i < 3; $i++){
787  $buffer .= "
788  <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
789  <td><input type='text' name='parameters[".$name."][]'></td></tr>";
790  }
791  $buffer .= '</table>';
792  // if scalar
793  } else {
794  $buffer .= "<input type='text' name='parameters[$name]'>";
795  }
796  } else {
797  $buffer .= "<input type='text' name='parameters[$name]'>";
798  }
799  return $buffer;
800  }
801 
843  function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
844  $this->complexTypes[$name] = array(
845  'name' => $name,
846  'typeClass' => $typeClass,
847  'phpType' => $phpType,
848  'compositor'=> $compositor,
849  'restrictionBase' => $restrictionBase,
850  'elements' => $elements,
851  'attrs' => $attrs,
852  'arrayType' => $arrayType
853  );
854 
855  $this->xdebug("addComplexType $name:");
856  $this->appendDebug($this->varDump($this->complexTypes[$name]));
857  }
858 
871  function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
872  $this->simpleTypes[$name] = array(
873  'name' => $name,
874  'typeClass' => $typeClass,
875  'phpType' => $phpType,
876  'type' => $restrictionBase,
877  'enumeration' => $enumeration
878  );
879 
880  $this->xdebug("addSimpleType $name:");
881  $this->appendDebug($this->varDump($this->simpleTypes[$name]));
882  }
883 
891  function addElement($attrs) {
892  if (! $this->getPrefix($attrs['type'])) {
893  $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
894  }
895  $this->elements[ $attrs['name'] ] = $attrs;
896  $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
897 
898  $this->xdebug("addElement " . $attrs['name']);
899  $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
900  }
901 }
902 
903 
904 
905 
906 ?>