source: trunk/phpgwapi/inc/class.soap_parser.inc.php @ 2364

Revision 2364, 11.1 KB checked in by amuller, 14 years ago (diff)

Ticket #1008 - Adicionando licença aos arquivos php

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2
3        /***************************************************************************
4        * Expresso Livre                                                           *
5        * http://www.expressolivre.org                                             *
6        * --------------------------------------------                             *
7        *  This program is free software; you can redistribute it and/or modify it *
8        *  under the terms of the GNU General Public License as published by the   *
9        *  Free Software Foundation; either version 2 of the License, or (at your  *
10        *  option) any later version.                                              *
11        \**************************************************************************/
12
13        class soap_parser
14        {
15                function soap_parser($xml='',$encoding='UTF-8')
16                {
17                        global $soapTypes;
18
19                        $this->soapTypes = $soapTypes;
20                        $this->xml = $xml;
21                        $this->xml_encoding = $encoding;
22                        $this->root_struct = "";
23                        // options: envelope,header,body,method
24                        // determines where in the message we are (envelope,header,body,method)
25                        $this->status = '';
26                        $this->position = 0;
27                        $this->pos_stat = 0;
28                        $this->depth = 0;
29                        $this->default_namespace = '';
30                        $this->namespaces = array();
31                        $this->message = array();
32                        $this->fault = false;
33                        $this->fault_code = '';
34                        $this->fault_str = '';
35                        $this->fault_detail = '';
36                        $this->eval_str = '';
37                        $this->depth_array = array();
38                        $this->debug_flag = True;
39                        $this->debug_str = '';
40                        $this->previous_element = '';
41
42                        $this->entities = array (
43                                '&' => '&amp;',
44                                '<' => '&lt;',
45                                '>' => '&gt;',
46                                "'" => '&apos;',
47                                '"' => '&quot;'
48                        );
49
50                        // Check whether content has been read.
51                        if(!empty($xml))
52                        {
53                                $this->debug('Entering soap_parser()');
54                                //$this->debug("DATA DUMP:\n\n$xml");
55                                // Create an XML parser.
56                                $this->parser = xml_parser_create($this->xml_encoding);
57                                // Set the options for parsing the XML data.
58                                //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
59                                xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
60                                // Set the object for the parser.
61                                xml_set_object($this->parser, &$this);
62                                // Set the element handlers for the parser.
63                                xml_set_element_handler($this->parser, 'start_element','end_element');
64                                xml_set_character_data_handler($this->parser,'character_data');
65                                xml_set_default_handler($this->parser, 'default_handler');
66
67                                // Parse the XML file.
68                                if(!xml_parse($this->parser,$xml,true))
69                                {
70                                        // Display an error message.
71                                        $this->debug(sprintf("XML error on line %d: %s",
72                                                xml_get_current_line_number($this->parser),
73                                                xml_error_string(xml_get_error_code($this->parser))));
74                                        $this->fault = true;
75                                }
76                                else
77                                {
78                                        // get final eval string
79                                        $this->eval_str = "\$response = ".trim($this->build_eval($this->root_struct)).";";
80                                }
81                                xml_parser_free($this->parser);
82                        }
83                        else
84                        {
85                                $this->debug("xml was empty, didn't parse!");
86                        }
87                }
88
89                // loop through msg, building eval_str
90                function build_eval($pos)
91                {
92                        $this->debug("inside build_eval() for $pos: ".$this->message[$pos]["name"]);
93                        $eval_str = $this->message[$pos]['eval_str'];
94                        // loop through children, building...
95                        if($this->message[$pos]['children'] != '')
96                        {
97                                $this->debug('children string = '.$this->message[$pos]['children']);
98                                $children = explode('|',$this->message[$pos]['children']);
99                                $this->debug('it has '.count($children).' children');
100                                @reset($children);
101                                while(list($c,$child_pos) = @each($children))
102                                /* foreach($children as $c => $child_pos) */
103                                {
104                                        //$this->debug("child pos $child_pos: ".$this->message[$child_pos]["name"]);
105                                        if($this->message[$child_pos]['eval_str'] != '')
106                                        {
107                                                $this->debug('entering build_eval() for '.$this->message[$child_pos]['name'].", array pos $c, pos: $child_pos");
108                                                $eval_str .= $this->build_eval($child_pos).', ';
109                                        }
110                                }
111                                $eval_str = substr($eval_str,0,strlen($eval_str)-2);
112                        }
113                        // add current node's eval_str
114                        $eval_str .= $this->message[$pos]['end_eval_str'];
115                        return $eval_str;
116                }
117
118                // start-element handler
119                function start_element($parser, $name, $attrs)
120                {
121                        // position in a total number of elements, starting from 0
122                        // update class level pos
123                        $pos = $this->position++;
124                        // and set mine
125                        $this->message[$pos]['pos'] = $pos;
126
127                        // parent/child/depth determinations
128
129                        // depth = how many levels removed from root?
130                        // set mine as current global depth and increment global depth value
131                        $this->message[$pos]['depth'] = $this->depth++;
132
133                        // else add self as child to whoever the current parent is
134                        if($pos != 0)
135                        {
136                                $this->message[$this->parent]['children'] .= "|$pos";
137                        }
138                        // set my parent
139                        $this->message[$pos]['parent'] = $this->parent;
140                        // set self as current value for this depth
141                        $this->depth_array[$this->depth] = $pos;
142                        // set self as current parent
143                        $this->parent = $pos;
144
145                        // set status
146                        if(ereg(":Envelope$",$name))
147                        {
148                                $this->status = 'envelope';
149                        }
150                        elseif(ereg(":Header$",$name))
151                        {
152                                $this->status = 'header';
153                        }
154                        elseif(ereg(":Body$",$name))
155                        {
156                                $this->status = 'body';
157                        // set method
158                        }
159                        elseif($this->status == 'body')
160                        {
161                                $this->status = 'method';
162                                if(ereg(':',$name))
163                                {
164                                        $this->root_struct_name = substr(strrchr($name,':'),1);
165                                }
166                                else
167                                {
168                                        $this->root_struct_name = $name;
169                                }
170                                $this->root_struct = $pos;
171                                $this->message[$pos]['type'] = 'struct';
172                        }
173                        // set my status
174                        $this->message[$pos]['status'] = $this->status;
175
176                        // set name
177                        $this->message[$pos]['name'] = htmlspecialchars($name);
178                        // set attrs
179                        $this->message[$pos]['attrs'] = $attrs;
180                        // get namespace
181                        if(ereg(":",$name))
182                        {
183                                $namespace = substr($name,0,strpos($name,':'));
184                                $this->message[$pos]['namespace'] = $namespace;
185                                $this->default_namespace = $namespace;
186                        }
187                        else
188                        {
189                                $this->message[$pos]['namespace'] = $this->default_namespace;
190                        }
191                        // loop through atts, logging ns and type declarations
192                        @reset($attrs);
193                        while (list($key,$value) = @each($attrs))
194                        /* foreach($attrs as $key => $value) */
195                        {
196                                // if ns declarations, add to class level array of valid namespaces
197                                if(ereg('xmlns:',$key))
198                                {
199                                        $namespaces[substr(strrchr($key,':'),1)] = $value;
200                                        if($name == $this->root_struct_name)
201                                        {
202                                                $this->methodNamespace = $value;
203                                        }
204                                }
205                                // if it's a type declaration, set type
206                                elseif($key == 'xsi:type')
207                                {
208                                        // then get attname and set $type
209                                        $type = substr(strrchr($value,':'),1);
210                                }
211                        }
212
213                        // set type if available
214                        if($type)
215                        {
216                                $this->message[$pos]['type'] = $type;
217                        }
218
219                        // debug
220                        //$this->debug("parsed $name start, eval = '".$this->message[$pos]["eval_str"]."'");
221                }
222
223                // end-element handler
224                function end_element($parser, $name)
225                {
226                        // position of current element is equal to the last value left in depth_array for my depth
227                        $pos = $this->depth_array[$this->depth];
228                        // bring depth down a notch
229                        $this->depth--;
230               
231                        // get type if not set already
232                        if($this->message[$pos]['type'] == '')
233                        {
234//                              if($this->message[$pos]['cdata'] == '' && $this->message[$pos]['children'] != '')
235                                if($this->message[$pos]['children'] != '')
236                                {
237                                        $this->message[$pos]['type'] = 'SOAPStruct';
238                                }
239                                else
240                                {
241                                        $this->message[$pos]['type'] = 'string';
242                                }
243                        }
244
245                        // set eval str start if it has a valid type and is inside the method
246                        if($pos >= $this->root_struct)
247                        {
248                                $this->message[$pos]['eval_str'] .= "\n CreateObject(\"phpgwapi.soapval\",\"".htmlspecialchars($name)."\", \"".$this->message[$pos]["type"]."\" ";
249                                $this->message[$pos]['end_eval_str'] = ')';
250                                $this->message[$pos]['inval'] = 'true';
251                                /*
252                                if($this->message[$pos]["name"] == $this->root_struct_name){
253                                        $this->message[$pos]["end_eval_str"] .= " ,\"$this->methodNamespace\"";
254                                }
255                                */
256                                if($this->message[$pos]['children'] != '')
257                                {
258                                        $this->message[$pos]['eval_str'] .= ', array( ';
259                                        $this->message[$pos]['end_eval_str'] .= ' )';
260                                }
261                        }
262
263                        // if i have no children and have cdata...then i must be a scalar value, so add my data to the eval_str
264                        if($this->status == 'method' && $this->message[$pos]['children'] == '')
265                        {
266                                // add cdata w/ no quotes if only int/float/dbl
267                                if($this->message[$pos]['type'] == 'string')
268                                {
269                                        $this->message[$pos]['eval_str'] .= ", \"".$this->message[$pos]['cdata']."\"";
270                                }
271                                elseif($this->message[$pos]['type'] == 'int' || $this->message[$pos]['type'] == 'float' || $this->message[$pos]['type'] == 'double')
272                                {
273                                        //$this->debug("adding cdata w/o quotes");
274                                        $this->message[$pos]['eval_str'] .= ', '.trim($this->message[$pos]['cdata']);
275                                }
276                                elseif(is_string($this->message[$pos]['cdata']))
277                                {
278                                        //$this->debug("adding cdata w/ quotes");
279                                        $this->message[$pos]['eval_str'] .= ", \"".$this->message[$pos]['cdata']."\"";
280                                }
281                        }
282                        // if in the process of making a soap_val, close the parentheses and move on...
283                        if($this->message[$pos]['inval'] == 'true')
284                        {
285                                $this->message[$pos]['inval'] == 'false';
286                        }
287                        // if tag we are currently closing is the method wrapper
288                        if($pos == $this->root_struct)
289                        {
290                                $this->status = 'body';
291                        }
292                        elseif(ereg(':Body',$name))
293                        {
294                                $this->status = 'header';
295                        }
296                        elseif(ereg(':Header',$name))
297                        {
298                                $this->status = 'envelope';
299                        }
300                        // set parent back to my parent
301                        $this->parent = $this->message[$pos]['parent'];
302                        $this->debug("parsed $name end, type '".$this->message[$pos]['type']."'eval_str = '".trim($this->message[$pos]['eval_str'])."' and children = ".$this->message[$pos]['children']);
303                }
304
305                // element content handler
306                function character_data($parser, $data)
307                {
308                        $pos = $this->depth_array[$this->depth];
309                        $this->message[$pos]['cdata'] .= $data;
310                        //$this->debug("parsed ".$this->message[$pos]["name"]." cdata, eval = '$this->eval_str'");
311                }
312
313                // default handler
314                function default_handler($parser, $data)
315                {
316                        //$this->debug("DEFAULT HANDLER: $data");
317                }
318
319                // function to get fault code
320                function fault()
321                {
322                        if($this->fault)
323                        {
324                                return true;
325                        }
326                        else
327                        {
328                                return false;
329                        }
330                }
331
332                // have this return a soap_val object
333                function get_response()
334                {
335                        $this->debug("eval()ing eval_str: $this->eval_str");
336                        @eval("$this->eval_str");
337                        if($response)
338                        {
339                                $this->debug("successfully eval'd msg");
340                                return $response;
341                        }
342                        else
343                        {
344                                $this->debug('ERROR: did not successfully eval the msg');
345                                $this->fault = true;
346                                return CreateObject('phpgwapi.soapval',
347                                        'Fault',
348                                        'struct',
349                                        array(
350                                                CreateObject('phpgwapi.soapval',
351                                                        'faultcode',
352                                                        'string',
353                                                        'SOAP-ENV:Server'
354                                                ),
355                                                CreateObject('phpgwapi.soapval',
356                                                        'faultstring',
357                                                        'string',
358                                                        "couldn't eval \"$this->eval_str\""
359                                                )
360                                        )
361                                );
362                        }
363                }
364
365                function debug($string)
366                {
367                        if($this->debug_flag)
368                        {
369                                $this->debug_str .= "$string\n";
370                        }
371                }
372
373                function decode_entities($text)
374                {
375                        @reset($this->entities);
376                        while(list($entity,$encoded) = @each($this->entities))
377                        /* foreach($this->entities as $entity => $encoded) */
378                        {
379                                $text = str_replace($encoded,$entity,$text);
380                        }
381                        return $text;
382                }
383        }
384?>
Note: See TracBrowser for help on using the repository browser.