This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | |||
5 | Modification information for LGPL compliance |
||
6 | |||
7 | r57813 - 2010-08-19 10:34:44 -0700 (Thu, 19 Aug 2010) - kjing - Author: John Mertic <[email protected]> |
||
8 | Bug 39085 - When loading the opposite search panel via ajax on the ListViews, call the index action instead of the ListView action to avoid touching pre-MVC code by accident. |
||
9 | |||
10 | r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync |
||
11 | |||
12 | r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover |
||
13 | |||
14 | r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex |
||
15 | |||
16 | r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system |
||
17 | |||
18 | r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development |
||
19 | |||
20 | r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by: |
||
21 | - Changing all ereg function to either preg or simple string based ones |
||
22 | - No more references to magic quotes. |
||
23 | - Change all the session_unregister() functions to just unset() the correct session variable instead. |
||
24 | |||
25 | r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372 |
||
26 | |||
27 | r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm |
||
28 | |||
29 | r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code |
||
30 | |||
31 | r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation |
||
32 | |||
33 | r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap |
||
34 | |||
35 | r7905 - 2005-09-21 19:12:57 -0700 (Wed, 21 Sep 2005) - majed - restores old nusoap pre & with a few fixes |
||
36 | |||
37 | r7861 - 2005-09-20 15:40:25 -0700 (Tue, 20 Sep 2005) - majed - & fix for 3.5.1 |
||
38 | |||
39 | r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9 |
||
40 | |||
41 | r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly. --clint |
||
42 | |||
43 | r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count |
||
44 | |||
45 | r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap |
||
46 | |||
47 | |||
48 | */ |
||
49 | |||
50 | |||
51 | if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
||
52 | |||
53 | |||
54 | |||
55 | |||
56 | /** |
||
57 | * parses a WSDL file, allows access to it's data, other utility methods. |
||
58 | * also builds WSDL structures programmatically. |
||
59 | * |
||
60 | * @author Dietrich Ayala <[email protected]> |
||
61 | * @author Scott Nichol <[email protected]> |
||
62 | |||
63 | * @access public |
||
64 | */ |
||
65 | class wsdl extends nusoap_base { |
||
66 | // URL or filename of the root of this WSDL |
||
67 | var $wsdl; |
||
68 | // define internal arrays of bindings, ports, operations, messages, etc. |
||
69 | var $schemas = array(); |
||
70 | var $currentSchema; |
||
71 | var $message = array(); |
||
72 | var $complexTypes = array(); |
||
73 | var $messages = array(); |
||
74 | var $currentMessage; |
||
75 | var $currentOperation; |
||
76 | var $portTypes = array(); |
||
77 | var $currentPortType; |
||
78 | var $bindings = array(); |
||
79 | var $currentBinding; |
||
80 | var $ports = array(); |
||
81 | var $currentPort; |
||
82 | var $opData = array(); |
||
83 | var $status = ''; |
||
84 | var $documentation = false; |
||
85 | var $endpoint = ''; |
||
86 | // array of wsdl docs to import |
||
87 | var $import = array(); |
||
88 | // parser vars |
||
89 | var $parser; |
||
90 | var $position = 0; |
||
91 | var $depth = 0; |
||
92 | var $depth_array = array(); |
||
93 | // for getting wsdl |
||
94 | var $proxyhost = ''; |
||
95 | var $proxyport = ''; |
||
96 | var $proxyusername = ''; |
||
97 | var $proxypassword = ''; |
||
98 | var $timeout = 0; |
||
99 | var $response_timeout = 30; |
||
100 | var $curl_options = array(); // User-specified cURL options |
||
101 | var $use_curl = false; // whether to always try to use cURL |
||
102 | // for HTTP authentication |
||
103 | var $username = ''; // Username for HTTP authentication |
||
104 | var $password = ''; // Password for HTTP authentication |
||
105 | var $authtype = ''; // Type of HTTP authentication |
||
106 | var $certRequest = array(); // Certificate for HTTP SSL authentication |
||
107 | |||
108 | /** |
||
109 | * constructor |
||
110 | * |
||
111 | * @param string $wsdl WSDL document URL |
||
112 | * @param string $proxyhost |
||
113 | * @param string $proxyport |
||
114 | * @param string $proxyusername |
||
115 | * @param string $proxypassword |
||
116 | * @param integer $timeout set the connection timeout |
||
117 | * @param integer $response_timeout set the response timeout |
||
118 | * @param array $curl_options user-specified cURL options |
||
119 | * @param boolean $use_curl try to use cURL |
||
120 | * @access public |
||
121 | */ |
||
122 | function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){ |
||
123 | parent::nusoap_base(); |
||
124 | $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout"); |
||
125 | $this->proxyhost = $proxyhost; |
||
0 ignored issues
–
show
|
|||
126 | $this->proxyport = $proxyport; |
||
0 ignored issues
–
show
It seems like
$proxyport can also be of type false . However, the property $proxyport is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
127 | $this->proxyusername = $proxyusername; |
||
0 ignored issues
–
show
It seems like
$proxyusername can also be of type false . However, the property $proxyusername is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
128 | $this->proxypassword = $proxypassword; |
||
0 ignored issues
–
show
It seems like
$proxypassword can also be of type false . However, the property $proxypassword is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
129 | $this->timeout = $timeout; |
||
130 | $this->response_timeout = $response_timeout; |
||
131 | if (is_array($curl_options)) |
||
132 | $this->curl_options = $curl_options; |
||
133 | $this->use_curl = $use_curl; |
||
134 | $this->fetchWSDL($wsdl); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * fetches the WSDL document and parses it |
||
139 | * |
||
140 | * @access public |
||
141 | */ |
||
142 | function fetchWSDL($wsdl) { |
||
143 | $this->debug("parse and process WSDL path=$wsdl"); |
||
144 | $this->wsdl = $wsdl; |
||
145 | // parse wsdl file |
||
146 | if ($this->wsdl != "") { |
||
147 | $this->parseWSDL($this->wsdl); |
||
148 | } |
||
149 | // imports |
||
150 | // TODO: handle imports more properly, grabbing them in-line and nesting them |
||
151 | $imported_urls = array(); |
||
152 | $imported = 1; |
||
153 | while ($imported > 0) { |
||
154 | $imported = 0; |
||
155 | // Schema imports |
||
156 | foreach ($this->schemas as $ns => $list) { |
||
157 | foreach ($list as $xs) { |
||
158 | $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! |
||
159 | foreach ($xs->imports as $ns2 => $list2) { |
||
160 | for ($ii = 0; $ii < count($list2); $ii++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
161 | if (! $list2[$ii]['loaded']) { |
||
162 | $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; |
||
163 | $url = $list2[$ii]['location']; |
||
164 | if ($url != '') { |
||
165 | $urlparts = parse_url($url); |
||
166 | if (!isset($urlparts['host'])) { |
||
167 | $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . |
||
168 | substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; |
||
169 | } |
||
170 | if (! in_array($url, $imported_urls)) { |
||
171 | $this->parseWSDL($url); |
||
172 | $imported++; |
||
173 | $imported_urls[] = $url; |
||
174 | } |
||
175 | } else { |
||
176 | $this->debug("Unexpected scenario: empty URL for unloaded import"); |
||
177 | } |
||
178 | } |
||
179 | } |
||
180 | } |
||
181 | } |
||
182 | } |
||
183 | // WSDL imports |
||
184 | $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! |
||
185 | foreach ($this->import as $ns => $list) { |
||
186 | for ($ii = 0; $ii < count($list); $ii++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
187 | if (! $list[$ii]['loaded']) { |
||
188 | $this->import[$ns][$ii]['loaded'] = true; |
||
189 | $url = $list[$ii]['location']; |
||
190 | if ($url != '') { |
||
191 | $urlparts = parse_url($url); |
||
192 | if (!isset($urlparts['host'])) { |
||
193 | $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . |
||
194 | substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; |
||
195 | } |
||
196 | if (! in_array($url, $imported_urls)) { |
||
197 | $this->parseWSDL($url); |
||
198 | $imported++; |
||
199 | $imported_urls[] = $url; |
||
200 | } |
||
201 | } else { |
||
202 | $this->debug("Unexpected scenario: empty URL for unloaded import"); |
||
203 | } |
||
204 | } |
||
205 | } |
||
206 | } |
||
207 | } |
||
208 | // add new data to operation data |
||
209 | foreach($this->bindings as $binding => $bindingData) { |
||
210 | if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { |
||
211 | foreach($bindingData['operations'] as $operation => $data) { |
||
212 | $this->debug('post-parse data gathering for ' . $operation); |
||
213 | $this->bindings[$binding]['operations'][$operation]['input'] = |
||
214 | isset($this->bindings[$binding]['operations'][$operation]['input']) ? |
||
215 | array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : |
||
216 | $this->portTypes[ $bindingData['portType'] ][$operation]['input']; |
||
217 | $this->bindings[$binding]['operations'][$operation]['output'] = |
||
218 | isset($this->bindings[$binding]['operations'][$operation]['output']) ? |
||
219 | array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : |
||
220 | $this->portTypes[ $bindingData['portType'] ][$operation]['output']; |
||
221 | if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ |
||
222 | $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; |
||
223 | } |
||
224 | if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ |
||
225 | $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; |
||
226 | } |
||
227 | // Set operation style if necessary, but do not override one already provided |
||
228 | if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) { |
||
229 | $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; |
||
230 | } |
||
231 | $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; |
||
232 | $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; |
||
233 | $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; |
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * parses the wsdl document |
||
241 | * |
||
242 | * @param string $wsdl path or URL |
||
243 | * @access private |
||
244 | */ |
||
245 | function parseWSDL($wsdl = '') { |
||
246 | $this->debug("parse WSDL at path=$wsdl"); |
||
247 | |||
248 | if ($wsdl == '') { |
||
249 | $this->debug('no wsdl passed to parseWSDL()!!'); |
||
250 | $this->setError('no wsdl passed to parseWSDL()!!'); |
||
251 | return false; |
||
252 | } |
||
253 | |||
254 | // parse $wsdl for url format |
||
255 | $wsdl_props = parse_url($wsdl); |
||
256 | |||
257 | if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { |
||
258 | $this->debug('getting WSDL http(s) URL ' . $wsdl); |
||
259 | // get wsdl |
||
260 | $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl); |
||
261 | $tr->request_method = 'GET'; |
||
262 | $tr->useSOAPAction = false; |
||
263 | if($this->proxyhost && $this->proxyport){ |
||
264 | $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); |
||
265 | } |
||
266 | if ($this->authtype != '') { |
||
267 | $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); |
||
268 | } |
||
269 | $tr->setEncoding('gzip, deflate'); |
||
270 | $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); |
||
271 | //$this->debug("WSDL request\n" . $tr->outgoing_payload); |
||
272 | //$this->debug("WSDL response\n" . $tr->incoming_payload); |
||
273 | $this->appendDebug($tr->getDebug()); |
||
274 | // catch errors |
||
275 | if($err = $tr->getError() ){ |
||
276 | $errstr = 'Getting ' . $wsdl . ' - HTTP ERROR: '.$err; |
||
277 | $this->debug($errstr); |
||
278 | $this->setError($errstr); |
||
279 | unset($tr); |
||
280 | return false; |
||
281 | } |
||
282 | unset($tr); |
||
283 | $this->debug("got WSDL URL"); |
||
284 | } else { |
||
285 | // $wsdl is not http(s), so treat it as a file URL or plain file path |
||
286 | if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { |
||
287 | $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; |
||
288 | } else { |
||
289 | $path = $wsdl; |
||
290 | } |
||
291 | $this->debug('getting WSDL file ' . $path); |
||
292 | $wsdl_string = @file_get_contents($path); |
||
293 | if ($wsdl_string === false) { |
||
294 | $errstr = "Bad path to WSDL file $path"; |
||
295 | $this->debug($errstr); |
||
296 | $this->setError($errstr); |
||
297 | return false; |
||
298 | } |
||
299 | } |
||
300 | $this->debug('Parse WSDL'); |
||
301 | // end new code added |
||
302 | // Create an XML parser. |
||
303 | $this->parser = xml_parser_create(); |
||
304 | // Set the options for parsing the XML data. |
||
305 | // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); |
||
306 | xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); |
||
307 | // Set the object for the parser. |
||
308 | xml_set_object($this->parser, $this); |
||
309 | // Set the element handlers for the parser. |
||
310 | xml_set_element_handler($this->parser, 'start_element', 'end_element'); |
||
311 | xml_set_character_data_handler($this->parser, 'character_data'); |
||
312 | // Parse the XML file. |
||
313 | if (!xml_parse($this->parser, $wsdl_string, true)) { |
||
314 | // Display an error message. |
||
315 | $errstr = sprintf( |
||
316 | 'XML error parsing WSDL from %s on line %d: %s', |
||
317 | $wsdl, |
||
318 | xml_get_current_line_number($this->parser), |
||
319 | xml_error_string(xml_get_error_code($this->parser)) |
||
320 | ); |
||
321 | $this->debug($errstr); |
||
322 | $this->debug("XML payload:\n" . $wsdl_string); |
||
323 | $this->setError($errstr); |
||
324 | return false; |
||
325 | } |
||
326 | // free the parser |
||
327 | xml_parser_free($this->parser); |
||
328 | $this->debug('Parsing WSDL done'); |
||
329 | // catch wsdl parse errors |
||
330 | if($this->getError()){ |
||
331 | return false; |
||
332 | } |
||
333 | return true; |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * start-element handler |
||
338 | * |
||
339 | * @param string $parser XML parser object |
||
340 | * @param string $name element name |
||
341 | * @param string $attrs associative array of attributes |
||
342 | * @access private |
||
343 | */ |
||
344 | function start_element($parser, $name, $attrs) |
||
345 | { |
||
346 | if ($this->status == 'schema') { |
||
347 | $this->currentSchema->schemaStartElement($parser, $name, $attrs); |
||
348 | $this->appendDebug($this->currentSchema->getDebug()); |
||
349 | $this->currentSchema->clearDebug(); |
||
350 | } elseif (preg_match('/schema$/', $name)) { |
||
351 | $this->debug('Parsing WSDL schema'); |
||
352 | // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); |
||
353 | $this->status = 'schema'; |
||
354 | $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces); |
||
355 | $this->currentSchema->schemaStartElement($parser, $name, $attrs); |
||
356 | $this->appendDebug($this->currentSchema->getDebug()); |
||
357 | $this->currentSchema->clearDebug(); |
||
358 | } else { |
||
359 | // position in the total number of elements, starting from 0 |
||
360 | $pos = $this->position++; |
||
361 | $depth = $this->depth++; |
||
362 | // set self as current value for this depth |
||
363 | $this->depth_array[$depth] = $pos; |
||
364 | $this->message[$pos] = array('cdata' => ''); |
||
365 | // process attributes |
||
366 | if (count($attrs) > 0) { |
||
367 | // register namespace declarations |
||
368 | foreach($attrs as $k => $v) { |
||
0 ignored issues
–
show
|
|||
369 | if (preg_match('/^xmlns/',$k)) { |
||
370 | if ($ns_prefix = substr(strrchr($k, ':'), 1)) { |
||
371 | $this->namespaces[$ns_prefix] = $v; |
||
372 | } else { |
||
373 | $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; |
||
374 | } |
||
375 | if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { |
||
376 | $this->XMLSchemaVersion = $v; |
||
377 | $this->namespaces['xsi'] = $v . '-instance'; |
||
378 | } |
||
379 | } |
||
380 | } |
||
381 | // expand each attribute prefix to its namespace |
||
382 | foreach($attrs as $k => $v) { |
||
0 ignored issues
–
show
|
|||
383 | $k = strpos($k, ':') ? $this->expandQname($k) : $k; |
||
384 | if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { |
||
385 | $v = strpos($v, ':') ? $this->expandQname($v) : $v; |
||
386 | } |
||
387 | $eAttrs[$k] = $v; |
||
388 | } |
||
389 | $attrs = $eAttrs; |
||
390 | } else { |
||
391 | $attrs = array(); |
||
392 | } |
||
393 | // get element prefix, namespace and name |
||
394 | if (preg_match('/:/', $name)) { |
||
395 | // get ns prefix |
||
396 | $prefix = substr($name, 0, strpos($name, ':')); |
||
397 | // get ns |
||
398 | $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; |
||
399 | // get unqualified name |
||
400 | $name = substr(strstr($name, ':'), 1); |
||
401 | } |
||
402 | // process attributes, expanding any prefixes to namespaces |
||
403 | // find status, register data |
||
404 | switch ($this->status) { |
||
405 | case 'message': |
||
406 | if ($name == 'part') { |
||
407 | if (isset($attrs['type'])) { |
||
408 | $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs)); |
||
409 | $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; |
||
410 | } |
||
411 | if (isset($attrs['element'])) { |
||
412 | $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs)); |
||
413 | $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^'; |
||
414 | } |
||
415 | } |
||
416 | break; |
||
417 | case 'portType': |
||
418 | switch ($name) { |
||
419 | case 'operation': |
||
420 | $this->currentPortOperation = $attrs['name']; |
||
421 | $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); |
||
422 | if (isset($attrs['parameterOrder'])) { |
||
423 | $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; |
||
424 | } |
||
425 | break; |
||
426 | case 'documentation': |
||
427 | $this->documentation = true; |
||
428 | break; |
||
429 | // merge input/output data |
||
430 | default: |
||
431 | $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; |
||
432 | $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; |
||
433 | break; |
||
434 | } |
||
435 | break; |
||
436 | case 'binding': |
||
437 | switch ($name) { |
||
438 | case 'binding': |
||
439 | // get ns prefix |
||
440 | if (isset($attrs['style'])) { |
||
441 | $this->bindings[$this->currentBinding]['prefix'] = $prefix; |
||
442 | } |
||
443 | $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); |
||
444 | break; |
||
445 | case 'header': |
||
446 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; |
||
447 | break; |
||
448 | case 'operation': |
||
449 | if (isset($attrs['soapAction'])) { |
||
450 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; |
||
451 | } |
||
452 | if (isset($attrs['style'])) { |
||
453 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; |
||
454 | } |
||
455 | if (isset($attrs['name'])) { |
||
456 | $this->currentOperation = $attrs['name']; |
||
457 | $this->debug("current binding operation: $this->currentOperation"); |
||
458 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; |
||
459 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; |
||
460 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; |
||
461 | } |
||
462 | break; |
||
463 | case 'input': |
||
464 | $this->opStatus = 'input'; |
||
465 | break; |
||
466 | case 'output': |
||
467 | $this->opStatus = 'output'; |
||
468 | break; |
||
469 | case 'body': |
||
470 | if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { |
||
471 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); |
||
472 | } else { |
||
473 | $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; |
||
474 | } |
||
475 | break; |
||
476 | } |
||
477 | break; |
||
478 | case 'service': |
||
479 | switch ($name) { |
||
480 | case 'port': |
||
481 | $this->currentPort = $attrs['name']; |
||
482 | $this->debug('current port: ' . $this->currentPort); |
||
483 | $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); |
||
484 | |||
485 | break; |
||
486 | case 'address': |
||
487 | $this->ports[$this->currentPort]['location'] = $attrs['location']; |
||
488 | $this->ports[$this->currentPort]['bindingType'] = $namespace; |
||
489 | $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; |
||
490 | $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; |
||
491 | break; |
||
492 | } |
||
493 | break; |
||
494 | } |
||
495 | // set status |
||
496 | switch ($name) { |
||
497 | case 'import': |
||
498 | if (isset($attrs['location'])) { |
||
499 | $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); |
||
500 | $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); |
||
501 | } else { |
||
502 | $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); |
||
503 | if (! $this->getPrefixFromNamespace($attrs['namespace'])) { |
||
504 | $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; |
||
505 | } |
||
506 | $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); |
||
507 | } |
||
508 | break; |
||
509 | //wait for schema |
||
510 | //case 'types': |
||
511 | // $this->status = 'schema'; |
||
512 | // break; |
||
513 | case 'message': |
||
514 | $this->status = 'message'; |
||
515 | $this->messages[$attrs['name']] = array(); |
||
516 | $this->currentMessage = $attrs['name']; |
||
517 | break; |
||
518 | case 'portType': |
||
519 | $this->status = 'portType'; |
||
520 | $this->portTypes[$attrs['name']] = array(); |
||
521 | $this->currentPortType = $attrs['name']; |
||
522 | break; |
||
523 | case "binding": |
||
524 | if (isset($attrs['name'])) { |
||
525 | // get binding name |
||
526 | if (strpos($attrs['name'], ':')) { |
||
527 | $this->currentBinding = $this->getLocalPart($attrs['name']); |
||
528 | } else { |
||
529 | $this->currentBinding = $attrs['name']; |
||
530 | } |
||
531 | $this->status = 'binding'; |
||
532 | $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); |
||
533 | $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); |
||
534 | } |
||
535 | break; |
||
536 | case 'service': |
||
537 | $this->serviceName = $attrs['name']; |
||
538 | $this->status = 'service'; |
||
539 | $this->debug('current service: ' . $this->serviceName); |
||
540 | break; |
||
541 | case 'definitions': |
||
542 | foreach ($attrs as $name => $value) { |
||
543 | $this->wsdl_info[$name] = $value; |
||
544 | } |
||
545 | break; |
||
546 | } |
||
547 | } |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * end-element handler |
||
552 | * |
||
553 | * @param string $parser XML parser object |
||
554 | * @param string $name element name |
||
555 | * @access private |
||
556 | */ |
||
557 | function end_element($parser, $name){ |
||
558 | // unset schema status |
||
559 | if (/*preg_match('/types$/', $name) ||*/ preg_match('/schema$/', $name)) { |
||
560 | $this->status = ""; |
||
561 | $this->appendDebug($this->currentSchema->getDebug()); |
||
562 | $this->currentSchema->clearDebug(); |
||
563 | $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; |
||
564 | $this->debug('Parsing WSDL schema done'); |
||
565 | } |
||
566 | if ($this->status == 'schema') { |
||
567 | $this->currentSchema->schemaEndElement($parser, $name); |
||
568 | } else { |
||
569 | // bring depth down a notch |
||
570 | $this->depth--; |
||
571 | } |
||
572 | // end documentation |
||
573 | if ($this->documentation) { |
||
574 | //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. |
||
575 | //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; |
||
576 | $this->documentation = false; |
||
577 | } |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * element content handler |
||
582 | * |
||
583 | * @param string $parser XML parser object |
||
584 | * @param string $data element content |
||
585 | * @access private |
||
586 | */ |
||
587 | function character_data($parser, $data) |
||
588 | { |
||
589 | $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; |
||
590 | if (isset($this->message[$pos]['cdata'])) { |
||
591 | $this->message[$pos]['cdata'] .= $data; |
||
592 | } |
||
593 | if ($this->documentation) { |
||
594 | $this->documentation .= $data; |
||
595 | } |
||
596 | } |
||
597 | |||
598 | /** |
||
599 | * if authenticating, set user credentials here |
||
600 | * |
||
601 | * @param string $username |
||
602 | * @param string $password |
||
603 | * @param string $authtype (basic|digest|certificate|ntlm) |
||
604 | * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) |
||
605 | * @access public |
||
606 | */ |
||
607 | function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { |
||
608 | $this->debug("setCredentials username=$username authtype=$authtype certRequest="); |
||
609 | $this->appendDebug($this->varDump($certRequest)); |
||
610 | $this->username = $username; |
||
611 | $this->password = $password; |
||
612 | $this->authtype = $authtype; |
||
613 | $this->certRequest = $certRequest; |
||
614 | } |
||
615 | |||
616 | function getBindingData($binding) |
||
617 | { |
||
618 | if (is_array($this->bindings[$binding])) { |
||
619 | return $this->bindings[$binding]; |
||
620 | } |
||
621 | } |
||
622 | |||
623 | /** |
||
624 | * returns an assoc array of operation names => operation data |
||
625 | * |
||
626 | * @param string $portName WSDL port name |
||
627 | * @param string $bindingType eg: soap, smtp, dime (only soap and soap12 are currently supported) |
||
628 | * @return array |
||
629 | * @access public |
||
630 | */ |
||
631 | function getOperations($portName = '', $bindingType = 'soap') { |
||
632 | $ops = array(); |
||
633 | if ($bindingType == 'soap') { |
||
634 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; |
||
635 | } elseif ($bindingType == 'soap12') { |
||
636 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/'; |
||
637 | } else { |
||
638 | $this->debug("getOperations bindingType $bindingType may not be supported"); |
||
639 | } |
||
640 | $this->debug("getOperations for port '$portName' bindingType $bindingType"); |
||
641 | // loop thru ports |
||
642 | foreach($this->ports as $port => $portData) { |
||
643 | $this->debug("getOperations checking port $port bindingType " . $portData['bindingType']); |
||
644 | if ($portName == '' || $port == $portName) { |
||
645 | // binding type of port matches parameter |
||
646 | if ($portData['bindingType'] == $bindingType) { |
||
647 | $this->debug("getOperations found port $port bindingType $bindingType"); |
||
648 | //$this->debug("port data: " . $this->varDump($portData)); |
||
649 | //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); |
||
650 | // merge bindings |
||
651 | if (isset($this->bindings[ $portData['binding'] ]['operations'])) { |
||
652 | $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); |
||
653 | } |
||
654 | } |
||
655 | } |
||
656 | } |
||
657 | if (count($ops) == 0) { |
||
658 | $this->debug("getOperations found no operations for port '$portName' bindingType $bindingType"); |
||
659 | } |
||
660 | return $ops; |
||
661 | } |
||
662 | |||
663 | /** |
||
664 | * returns an associative array of data necessary for calling an operation |
||
665 | * |
||
666 | * @param string $operation name of operation |
||
667 | * @param string $bindingType type of binding eg: soap, soap12 |
||
668 | * @return array |
||
669 | * @access public |
||
670 | */ |
||
671 | function getOperationData($operation, $bindingType = 'soap') |
||
672 | { |
||
673 | if ($bindingType == 'soap') { |
||
674 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; |
||
675 | } elseif ($bindingType == 'soap12') { |
||
676 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/'; |
||
677 | } |
||
678 | // loop thru ports |
||
679 | foreach($this->ports as $port => $portData) { |
||
680 | // binding type of port matches parameter |
||
681 | if ($portData['bindingType'] == $bindingType) { |
||
682 | // get binding |
||
683 | //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { |
||
684 | foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { |
||
685 | // note that we could/should also check the namespace here |
||
686 | if ($operation == $bOperation) { |
||
687 | $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; |
||
688 | return $opData; |
||
689 | } |
||
690 | } |
||
691 | } |
||
692 | } |
||
693 | } |
||
694 | |||
695 | /** |
||
696 | * returns an associative array of data necessary for calling an operation |
||
697 | * |
||
698 | * @param string $soapAction soapAction for operation |
||
699 | * @param string $bindingType type of binding eg: soap, soap12 |
||
700 | * @return array |
||
701 | * @access public |
||
702 | */ |
||
703 | function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { |
||
704 | if ($bindingType == 'soap') { |
||
705 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; |
||
706 | } elseif ($bindingType == 'soap12') { |
||
707 | $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/'; |
||
708 | } |
||
709 | // loop thru ports |
||
710 | foreach($this->ports as $port => $portData) { |
||
711 | // binding type of port matches parameter |
||
712 | if ($portData['bindingType'] == $bindingType) { |
||
713 | // loop through operations for the binding |
||
714 | foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { |
||
715 | if ($opData['soapAction'] == $soapAction) { |
||
716 | return $opData; |
||
717 | } |
||
718 | } |
||
719 | } |
||
720 | } |
||
721 | } |
||
722 | |||
723 | /** |
||
724 | * returns an array of information about a given type |
||
725 | * returns false if no type exists by the given name |
||
726 | * |
||
727 | * typeDef = array( |
||
728 | * 'elements' => array(), // refs to elements array |
||
729 | * 'restrictionBase' => '', |
||
730 | * 'phpType' => '', |
||
731 | * 'order' => '(sequence|all)', |
||
732 | * 'attrs' => array() // refs to attributes array |
||
733 | * ) |
||
734 | * |
||
735 | * @param string $type the type |
||
736 | * @param string $ns namespace (not prefix) of the type |
||
737 | * @return mixed |
||
738 | * @access public |
||
739 | * @see nusoap_xmlschema |
||
740 | */ |
||
741 | function getTypeDef($type, $ns) { |
||
742 | $this->debug("in getTypeDef: type=$type, ns=$ns"); |
||
743 | if ((! $ns) && isset($this->namespaces['tns'])) { |
||
744 | $ns = $this->namespaces['tns']; |
||
745 | $this->debug("in getTypeDef: type namespace forced to $ns"); |
||
746 | } |
||
747 | if (!isset($this->schemas[$ns])) { |
||
748 | foreach ($this->schemas as $ns0 => $schema0) { |
||
749 | if (strcasecmp($ns, $ns0) == 0) { |
||
750 | $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0"); |
||
751 | $ns = $ns0; |
||
752 | break; |
||
753 | } |
||
754 | } |
||
755 | } |
||
756 | if (isset($this->schemas[$ns])) { |
||
757 | $this->debug("in getTypeDef: have schema for namespace $ns"); |
||
758 | for ($i = 0; $i < count($this->schemas[$ns]); $i++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
759 | $xs = &$this->schemas[$ns][$i]; |
||
760 | $t = $xs->getTypeDef($type); |
||
761 | $this->appendDebug($xs->getDebug()); |
||
762 | $xs->clearDebug(); |
||
763 | if ($t) { |
||
764 | $this->debug("in getTypeDef: found type $type"); |
||
765 | if (!isset($t['phpType'])) { |
||
766 | // get info for type to tack onto the element |
||
767 | $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); |
||
768 | $ns = substr($t['type'], 0, strrpos($t['type'], ':')); |
||
769 | $etype = $this->getTypeDef($uqType, $ns); |
||
770 | if ($etype) { |
||
771 | $this->debug("found type for [element] $type:"); |
||
772 | $this->debug($this->varDump($etype)); |
||
773 | if (isset($etype['phpType'])) { |
||
774 | $t['phpType'] = $etype['phpType']; |
||
775 | } |
||
776 | if (isset($etype['elements'])) { |
||
777 | $t['elements'] = $etype['elements']; |
||
778 | } |
||
779 | if (isset($etype['attrs'])) { |
||
780 | $t['attrs'] = $etype['attrs']; |
||
781 | } |
||
782 | } else { |
||
783 | $this->debug("did not find type for [element] $type"); |
||
784 | } |
||
785 | } |
||
786 | return $t; |
||
787 | } |
||
788 | } |
||
789 | $this->debug("in getTypeDef: did not find type $type"); |
||
790 | } else { |
||
791 | $this->debug("in getTypeDef: do not have schema for namespace $ns"); |
||
792 | } |
||
793 | return false; |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * prints html description of services |
||
798 | * |
||
799 | * @access private |
||
800 | */ |
||
801 | function webDescription(){ |
||
802 | global $HTTP_SERVER_VARS; |
||
803 | |||
804 | if (isset($_SERVER)) { |
||
805 | $PHP_SELF = $_SERVER['PHP_SELF']; |
||
806 | } elseif (isset($HTTP_SERVER_VARS)) { |
||
807 | $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; |
||
808 | } else { |
||
809 | $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); |
||
810 | } |
||
811 | |||
812 | $b = ' |
||
813 | <html><head><title>NuSOAP: '.$this->serviceName.'</title> |
||
814 | <style type="text/css"> |
||
815 | body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; } |
||
816 | p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; } |
||
817 | pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;} |
||
818 | ul { margin-top: 10px; margin-left: 20px; } |
||
819 | li { list-style-type: none; margin-top: 10px; color: #000000; } |
||
820 | .content{ |
||
821 | margin-left: 0px; padding-bottom: 2em; } |
||
822 | .nav { |
||
823 | padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em; |
||
824 | margin-top: 10px; margin-left: 0px; color: #000000; |
||
825 | background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; } |
||
826 | .title { |
||
827 | font-family: arial; font-size: 26px; color: #ffffff; |
||
828 | background-color: #999999; width: 100%; |
||
829 | margin-left: 0px; margin-right: 0px; |
||
830 | padding-top: 10px; padding-bottom: 10px;} |
||
831 | .hidden { |
||
832 | position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px; |
||
833 | font-family: arial; overflow: hidden; width: 600; |
||
834 | padding: 20px; font-size: 10px; background-color: #999999; |
||
835 | layer-background-color:#FFFFFF; } |
||
836 | a,a:active { color: charcoal; font-weight: bold; } |
||
837 | a:visited { color: #666666; font-weight: bold; } |
||
838 | a:hover { color: cc3300; font-weight: bold; } |
||
839 | </style> |
||
840 | <script language="JavaScript" type="text/javascript"> |
||
841 | <!-- |
||
842 | // POP-UP CAPTIONS... |
||
843 | function lib_bwcheck(){ //Browsercheck (needed) |
||
844 | this.ver=navigator.appVersion |
||
845 | this.agent=navigator.userAgent |
||
846 | this.dom=document.getElementById?1:0 |
||
847 | this.opera5=this.agent.indexOf("Opera 5")>-1 |
||
848 | this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; |
||
849 | this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; |
||
850 | this.ie4=(document.all && !this.dom && !this.opera5)?1:0; |
||
851 | this.ie=this.ie4||this.ie5||this.ie6 |
||
852 | this.mac=this.agent.indexOf("Mac")>-1 |
||
853 | this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0; |
||
854 | this.ns4=(document.layers && !this.dom)?1:0; |
||
855 | this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5) |
||
856 | return this |
||
857 | } |
||
858 | var bw = new lib_bwcheck() |
||
859 | //Makes crossbrowser object. |
||
860 | function makeObj(obj){ |
||
861 | this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0; |
||
862 | if(!this.evnt) return false |
||
863 | this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0; |
||
864 | this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0; |
||
865 | this.writeIt=b_writeIt; |
||
866 | return this |
||
867 | } |
||
868 | // A unit of measure that will be added when setting the position of a layer. |
||
869 | //var px = bw.ns4||window.opera?"":"px"; |
||
870 | function b_writeIt(text){ |
||
871 | if (bw.ns4){this.wref.write(text);this.wref.close()} |
||
872 | else this.wref.innerHTML = text |
||
873 | } |
||
874 | //Shows the messages |
||
875 | var oDesc; |
||
876 | function popup(divid){ |
||
877 | if(oDesc = new makeObj(divid)){ |
||
878 | oDesc.css.visibility = "visible" |
||
879 | } |
||
880 | } |
||
881 | function popout(){ // Hides message |
||
882 | if(oDesc) oDesc.css.visibility = "hidden" |
||
883 | } |
||
884 | //--> |
||
885 | </script> |
||
886 | </head> |
||
887 | <body> |
||
888 | <div class=content> |
||
889 | <br><br> |
||
890 | <div class=title>'.$this->serviceName.'</div> |
||
891 | <div class=nav> |
||
892 | <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service. |
||
893 | Click on an operation name to view it's details.</p> |
||
894 | <ul>'; |
||
895 | foreach($this->getOperations() as $op => $data){ |
||
896 | $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>"; |
||
897 | // create hidden div |
||
898 | $b .= "<div id='$op' class='hidden'> |
||
899 | <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>"; |
||
900 | foreach($data as $donnie => $marie){ // loop through opdata |
||
901 | if($donnie == 'input' || $donnie == 'output'){ // show input/output data |
||
902 | $b .= "<font color='white'>".ucfirst($donnie).':</font><br>'; |
||
903 | foreach($marie as $captain => $tenille){ // loop through data |
||
904 | if($captain == 'parts'){ // loop thru parts |
||
905 | $b .= " $captain:<br>"; |
||
906 | //if(is_array($tenille)){ |
||
907 | foreach($tenille as $joanie => $chachi){ |
||
908 | $b .= " $joanie: $chachi<br>"; |
||
909 | } |
||
910 | //} |
||
911 | } else { |
||
912 | $b .= " $captain: $tenille<br>"; |
||
913 | } |
||
914 | } |
||
915 | } else { |
||
916 | $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>"; |
||
917 | } |
||
918 | } |
||
919 | $b .= '</div>'; |
||
920 | } |
||
921 | $b .= ' |
||
922 | <ul> |
||
923 | </div> |
||
924 | </div></body></html>'; |
||
925 | return $b; |
||
926 | } |
||
927 | |||
928 | /** |
||
929 | * serialize the parsed wsdl |
||
930 | * |
||
931 | * @param mixed $debug whether to put debug=1 in endpoint URL |
||
932 | * @return string serialization of WSDL |
||
933 | * @access public |
||
934 | */ |
||
935 | function serialize($debug = 0) |
||
936 | { |
||
937 | $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'; |
||
938 | $xml .= "\n<definitions"; |
||
939 | foreach($this->namespaces as $k => $v) { |
||
940 | $xml .= " xmlns:$k=\"$v\""; |
||
941 | } |
||
942 | // 10.9.02 - add poulter fix for wsdl and tns declarations |
||
943 | if (isset($this->namespaces['wsdl'])) { |
||
944 | $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; |
||
945 | } |
||
946 | if (isset($this->namespaces['tns'])) { |
||
947 | $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; |
||
948 | } |
||
949 | $xml .= '>'; |
||
950 | // imports |
||
951 | if (sizeof($this->import) > 0) { |
||
952 | foreach($this->import as $ns => $list) { |
||
953 | foreach ($list as $ii) { |
||
954 | if ($ii['location'] != '') { |
||
955 | $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />'; |
||
956 | } else { |
||
957 | $xml .= '<import namespace="' . $ns . '" />'; |
||
958 | } |
||
959 | } |
||
960 | } |
||
961 | } |
||
962 | // types |
||
963 | if (count($this->schemas)>=1) { |
||
964 | $xml .= "\n<types>\n"; |
||
965 | foreach ($this->schemas as $ns => $list) { |
||
966 | foreach ($list as $xs) { |
||
967 | $xml .= $xs->serializeSchema(); |
||
968 | } |
||
969 | } |
||
970 | $xml .= '</types>'; |
||
971 | } |
||
972 | // messages |
||
973 | if (count($this->messages) >= 1) { |
||
974 | foreach($this->messages as $msgName => $msgParts) { |
||
975 | $xml .= "\n<message name=\"" . $msgName . '">'; |
||
976 | if(is_array($msgParts)){ |
||
977 | foreach($msgParts as $partName => $partType) { |
||
978 | // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>'; |
||
979 | if (strpos($partType, ':')) { |
||
980 | $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); |
||
0 ignored issues
–
show
|
|||
981 | } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { |
||
982 | // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>'; |
||
983 | $typePrefix = 'xsd'; |
||
984 | } else { |
||
985 | foreach($this->typemap as $ns => $types) { |
||
986 | if (isset($types[$partType])) { |
||
987 | $typePrefix = $this->getPrefixFromNamespace($ns); |
||
988 | } |
||
989 | } |
||
990 | if (!isset($typePrefix)) { |
||
991 | die("$partType has no namespace!"); |
||
992 | } |
||
993 | } |
||
994 | $ns = $this->getNamespaceFromPrefix($typePrefix); |
||
995 | $localPart = $this->getLocalPart($partType); |
||
996 | $typeDef = $this->getTypeDef($localPart, $ns); |
||
997 | if ($typeDef['typeClass'] == 'element') { |
||
998 | $elementortype = 'element'; |
||
999 | if (substr($localPart, -1) == '^') { |
||
1000 | $localPart = substr($localPart, 0, -1); |
||
1001 | } |
||
1002 | } else { |
||
1003 | $elementortype = 'type'; |
||
1004 | } |
||
1005 | $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />'; |
||
1006 | } |
||
1007 | } |
||
1008 | $xml .= '</message>'; |
||
1009 | } |
||
1010 | } |
||
1011 | // bindings & porttypes |
||
1012 | if (count($this->bindings) >= 1) { |
||
1013 | $binding_xml = ''; |
||
1014 | $portType_xml = ''; |
||
1015 | foreach($this->bindings as $bindingName => $attrs) { |
||
1016 | $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">'; |
||
1017 | $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>'; |
||
1018 | $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">'; |
||
1019 | foreach($attrs['operations'] as $opName => $opParts) { |
||
1020 | $binding_xml .= "\n" . ' <operation name="' . $opName . '">'; |
||
1021 | $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>'; |
||
1022 | if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { |
||
1023 | $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; |
||
1024 | } else { |
||
1025 | $enc_style = ''; |
||
1026 | } |
||
1027 | $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>'; |
||
1028 | if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { |
||
1029 | $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; |
||
1030 | } else { |
||
1031 | $enc_style = ''; |
||
1032 | } |
||
1033 | $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>'; |
||
1034 | $binding_xml .= "\n" . ' </operation>'; |
||
1035 | $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"'; |
||
1036 | if (isset($opParts['parameterOrder'])) { |
||
1037 | $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"'; |
||
1038 | } |
||
1039 | $portType_xml .= '>'; |
||
1040 | if(isset($opParts['documentation']) && $opParts['documentation'] != '') { |
||
1041 | $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>'; |
||
1042 | } |
||
1043 | $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>'; |
||
1044 | $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>'; |
||
1045 | $portType_xml .= "\n" . ' </operation>'; |
||
1046 | } |
||
1047 | $portType_xml .= "\n" . '</portType>'; |
||
1048 | $binding_xml .= "\n" . '</binding>'; |
||
1049 | } |
||
1050 | $xml .= $portType_xml . $binding_xml; |
||
1051 | } |
||
1052 | // services |
||
1053 | $xml .= "\n<service name=\"" . $this->serviceName . '">'; |
||
1054 | if (count($this->ports) >= 1) { |
||
1055 | foreach($this->ports as $pName => $attrs) { |
||
1056 | $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">'; |
||
1057 | $xml .= "\n" . ' <soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>'; |
||
1058 | $xml .= "\n" . ' </port>'; |
||
1059 | } |
||
1060 | } |
||
1061 | $xml .= "\n" . '</service>'; |
||
1062 | return $xml . "\n</definitions>"; |
||
1063 | } |
||
1064 | |||
1065 | /** |
||
1066 | * determine whether a set of parameters are unwrapped |
||
1067 | * when they are expect to be wrapped, Microsoft-style. |
||
1068 | * |
||
1069 | * @param string $type the type (element name) of the wrapper |
||
1070 | * @param array $parameters the parameter values for the SOAP call |
||
1071 | * @return boolean whether they parameters are unwrapped (and should be wrapped) |
||
1072 | * @access private |
||
1073 | */ |
||
1074 | function parametersMatchWrapped($type, &$parameters) { |
||
1075 | $this->debug("in parametersMatchWrapped type=$type, parameters="); |
||
1076 | $this->appendDebug($this->varDump($parameters)); |
||
1077 | |||
1078 | // split type into namespace:unqualified-type |
||
1079 | if (strpos($type, ':')) { |
||
1080 | $uqType = substr($type, strrpos($type, ':') + 1); |
||
1081 | $ns = substr($type, 0, strrpos($type, ':')); |
||
1082 | $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns"); |
||
1083 | if ($this->getNamespaceFromPrefix($ns)) { |
||
1084 | $ns = $this->getNamespaceFromPrefix($ns); |
||
1085 | $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns"); |
||
1086 | } |
||
1087 | } else { |
||
1088 | // TODO: should the type be compared to types in XSD, and the namespace |
||
1089 | // set to XSD if the type matches? |
||
1090 | $this->debug("in parametersMatchWrapped: No namespace for type $type"); |
||
1091 | $ns = ''; |
||
1092 | $uqType = $type; |
||
1093 | } |
||
1094 | |||
1095 | // get the type information |
||
1096 | if (!$typeDef = $this->getTypeDef($uqType, $ns)) { |
||
1097 | $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type."); |
||
1098 | return false; |
||
1099 | } |
||
1100 | $this->debug("in parametersMatchWrapped: found typeDef="); |
||
1101 | $this->appendDebug($this->varDump($typeDef)); |
||
1102 | if (substr($uqType, -1) == '^') { |
||
1103 | $uqType = substr($uqType, 0, -1); |
||
1104 | } |
||
1105 | $phpType = $typeDef['phpType']; |
||
1106 | $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : ''); |
||
1107 | $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType"); |
||
1108 | |||
1109 | // we expect a complexType or element of complexType |
||
1110 | if ($phpType != 'struct') { |
||
1111 | $this->debug("in parametersMatchWrapped: not a struct"); |
||
1112 | return false; |
||
1113 | } |
||
1114 | |||
1115 | // see whether the parameter names match the elements |
||
1116 | if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { |
||
1117 | $elements = 0; |
||
1118 | $matches = 0; |
||
1119 | foreach ($typeDef['elements'] as $name => $attrs) { |
||
1120 | if (isset($parameters[$name])) { |
||
1121 | $this->debug("in parametersMatchWrapped: have parameter named $name"); |
||
1122 | $matches++; |
||
1123 | } else { |
||
1124 | $this->debug("in parametersMatchWrapped: do not have parameter named $name"); |
||
1125 | } |
||
1126 | $elements++; |
||
1127 | } |
||
1128 | |||
1129 | $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names"); |
||
1130 | if ($matches == 0) { |
||
1131 | return false; |
||
1132 | } |
||
1133 | return true; |
||
1134 | } |
||
1135 | |||
1136 | // since there are no elements for the type, if the user passed no |
||
1137 | // parameters, the parameters match wrapped. |
||
1138 | $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType"); |
||
1139 | return count($parameters) == 0; |
||
1140 | } |
||
1141 | |||
1142 | /** |
||
1143 | * serialize PHP values according to a WSDL message definition |
||
1144 | * contrary to the method name, this is not limited to RPC |
||
1145 | * |
||
1146 | * TODO |
||
1147 | * - multi-ref serialization |
||
1148 | * - validate PHP values against type definitions, return errors if invalid |
||
1149 | * |
||
1150 | * @param string $operation operation name |
||
1151 | * @param string $direction (input|output) |
||
1152 | * @param mixed $parameters parameter value(s) |
||
1153 | * @param string $bindingType (soap|soap12) |
||
1154 | * @return mixed parameters serialized as XML or false on error (e.g. operation not found) |
||
1155 | * @access public |
||
1156 | */ |
||
1157 | function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') { |
||
1158 | $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType"); |
||
1159 | $this->appendDebug('parameters=' . $this->varDump($parameters)); |
||
1160 | |||
1161 | if ($direction != 'input' && $direction != 'output') { |
||
1162 | $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); |
||
1163 | $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); |
||
1164 | return false; |
||
1165 | } |
||
1166 | if (!$opData = $this->getOperationData($operation, $bindingType)) { |
||
1167 | $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType); |
||
1168 | $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType); |
||
1169 | return false; |
||
1170 | } |
||
1171 | $this->debug('in serializeRPCParameters: opData:'); |
||
1172 | $this->appendDebug($this->varDump($opData)); |
||
1173 | |||
1174 | // Get encoding style for output and set to current |
||
1175 | $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; |
||
1176 | if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { |
||
1177 | $encodingStyle = $opData['output']['encodingStyle']; |
||
1178 | $enc_style = $encodingStyle; |
||
1179 | } |
||
1180 | |||
1181 | // set input params |
||
1182 | $xml = ''; |
||
1183 | if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { |
||
1184 | $parts = &$opData[$direction]['parts']; |
||
1185 | $part_count = sizeof($parts); |
||
1186 | $style = $opData['style']; |
||
1187 | $use = $opData[$direction]['use']; |
||
1188 | $this->debug("have $part_count part(s) to serialize using $style/$use"); |
||
1189 | if (is_array($parameters)) { |
||
1190 | $parametersArrayType = $this->isArraySimpleOrStruct($parameters); |
||
1191 | $parameter_count = count($parameters); |
||
1192 | $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize"); |
||
1193 | // check for Microsoft-style wrapped parameters |
||
1194 | if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) { |
||
1195 | $this->debug('check whether the caller has wrapped the parameters'); |
||
1196 | if ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1) { |
||
1197 | // TODO: consider checking here for double-wrapping, when |
||
1198 | // service function wraps, then NuSOAP wraps again |
||
1199 | $this->debug("change simple array to associative with 'parameters' element"); |
||
1200 | $parameters['parameters'] = $parameters[0]; |
||
1201 | unset($parameters[0]); |
||
1202 | } |
||
1203 | if (($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) { |
||
1204 | $this->debug('check whether caller\'s parameters match the wrapped ones'); |
||
1205 | if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) { |
||
1206 | $this->debug('wrap the parameters for the caller'); |
||
1207 | $parameters = array('parameters' => $parameters); |
||
1208 | $parameter_count = 1; |
||
1209 | } |
||
1210 | } |
||
1211 | } |
||
1212 | foreach ($parts as $name => $type) { |
||
1213 | $this->debug("serializing part $name of type $type"); |
||
1214 | // Track encoding style |
||
1215 | if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { |
||
1216 | $encodingStyle = $opData[$direction]['encodingStyle']; |
||
1217 | $enc_style = $encodingStyle; |
||
1218 | } else { |
||
1219 | $enc_style = false; |
||
1220 | } |
||
1221 | // NOTE: add error handling here |
||
1222 | // if serializeType returns false, then catch global error and fault |
||
1223 | if ($parametersArrayType == 'arraySimple') { |
||
1224 | $p = array_shift($parameters); |
||
1225 | $this->debug('calling serializeType w/indexed param'); |
||
1226 | $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); |
||
1227 | } elseif (isset($parameters[$name])) { |
||
1228 | $this->debug('calling serializeType w/named param'); |
||
1229 | $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); |
||
1230 | } else { |
||
1231 | // TODO: only send nillable |
||
1232 | $this->debug('calling serializeType w/null param'); |
||
1233 | $xml .= $this->serializeType($name, $type, null, $use, $enc_style); |
||
1234 | } |
||
1235 | } |
||
1236 | } else { |
||
1237 | $this->debug('no parameters passed.'); |
||
1238 | } |
||
1239 | } |
||
1240 | $this->debug("serializeRPCParameters returning: $xml"); |
||
1241 | return $xml; |
||
1242 | } |
||
1243 | |||
1244 | /** |
||
1245 | * serialize a PHP value according to a WSDL message definition |
||
1246 | * |
||
1247 | * TODO |
||
1248 | * - multi-ref serialization |
||
1249 | * - validate PHP values against type definitions, return errors if invalid |
||
1250 | * |
||
1251 | * @param string $operation operation name |
||
1252 | * @param string $direction (input|output) |
||
1253 | * @param mixed $parameters parameter value(s) |
||
1254 | * @return mixed parameters serialized as XML or false on error (e.g. operation not found) |
||
1255 | * @access public |
||
1256 | * @deprecated |
||
1257 | */ |
||
1258 | function serializeParameters($operation, $direction, $parameters) |
||
1259 | { |
||
1260 | $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); |
||
1261 | $this->appendDebug('parameters=' . $this->varDump($parameters)); |
||
1262 | |||
1263 | if ($direction != 'input' && $direction != 'output') { |
||
1264 | $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); |
||
1265 | $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); |
||
1266 | return false; |
||
1267 | } |
||
1268 | if (!$opData = $this->getOperationData($operation)) { |
||
1269 | $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); |
||
1270 | $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); |
||
1271 | return false; |
||
1272 | } |
||
1273 | $this->debug('opData:'); |
||
1274 | $this->appendDebug($this->varDump($opData)); |
||
1275 | |||
1276 | // Get encoding style for output and set to current |
||
1277 | $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; |
||
1278 | if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { |
||
1279 | $encodingStyle = $opData['output']['encodingStyle']; |
||
1280 | $enc_style = $encodingStyle; |
||
1281 | } |
||
1282 | |||
1283 | // set input params |
||
1284 | $xml = ''; |
||
1285 | if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { |
||
1286 | |||
1287 | $use = $opData[$direction]['use']; |
||
1288 | $this->debug("use=$use"); |
||
1289 | $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); |
||
1290 | if (is_array($parameters)) { |
||
1291 | $parametersArrayType = $this->isArraySimpleOrStruct($parameters); |
||
1292 | $this->debug('have ' . $parametersArrayType . ' parameters'); |
||
1293 | foreach($opData[$direction]['parts'] as $name => $type) { |
||
1294 | $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); |
||
1295 | // Track encoding style |
||
1296 | if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { |
||
1297 | $encodingStyle = $opData[$direction]['encodingStyle']; |
||
1298 | $enc_style = $encodingStyle; |
||
1299 | } else { |
||
1300 | $enc_style = false; |
||
1301 | } |
||
1302 | // NOTE: add error handling here |
||
1303 | // if serializeType returns false, then catch global error and fault |
||
1304 | if ($parametersArrayType == 'arraySimple') { |
||
1305 | $p = array_shift($parameters); |
||
1306 | $this->debug('calling serializeType w/indexed param'); |
||
1307 | $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); |
||
1308 | } elseif (isset($parameters[$name])) { |
||
1309 | $this->debug('calling serializeType w/named param'); |
||
1310 | $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); |
||
1311 | } else { |
||
1312 | // TODO: only send nillable |
||
1313 | $this->debug('calling serializeType w/null param'); |
||
1314 | $xml .= $this->serializeType($name, $type, null, $use, $enc_style); |
||
1315 | } |
||
1316 | } |
||
1317 | } else { |
||
1318 | $this->debug('no parameters passed.'); |
||
1319 | } |
||
1320 | } |
||
1321 | $this->debug("serializeParameters returning: $xml"); |
||
1322 | return $xml; |
||
1323 | } |
||
1324 | |||
1325 | /** |
||
1326 | * serializes a PHP value according a given type definition |
||
1327 | * |
||
1328 | * @param string $name name of value (part or element) |
||
1329 | * @param string $type XML schema type of value (type or element) |
||
1330 | * @param mixed $value a native PHP value (parameter value) |
||
1331 | * @param string $use use for part (encoded|literal) |
||
1332 | * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) |
||
1333 | * @param boolean $unqualified a kludge for what should be XML namespace form handling |
||
1334 | * @return string value serialized as an XML string |
||
1335 | * @access private |
||
1336 | */ |
||
1337 | function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) |
||
1338 | { |
||
1339 | $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); |
||
1340 | $this->appendDebug("value=" . $this->varDump($value)); |
||
1341 | if($use == 'encoded' && $encodingStyle) { |
||
1342 | $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; |
||
1343 | } |
||
1344 | |||
1345 | // if a soapval has been supplied, let its type override the WSDL |
||
1346 | if (is_object($value) && get_class($value) == 'soapval') { |
||
1347 | if ($value->type_ns) { |
||
1348 | $type = $value->type_ns . ':' . $value->type; |
||
1349 | $forceType = true; |
||
1350 | $this->debug("in serializeType: soapval overrides type to $type"); |
||
1351 | } elseif ($value->type) { |
||
1352 | $type = $value->type; |
||
1353 | $forceType = true; |
||
1354 | $this->debug("in serializeType: soapval overrides type to $type"); |
||
1355 | } else { |
||
1356 | $forceType = false; |
||
1357 | $this->debug("in serializeType: soapval does not override type"); |
||
1358 | } |
||
1359 | $attrs = $value->attributes; |
||
1360 | $value = $value->value; |
||
1361 | $this->debug("in serializeType: soapval overrides value to $value"); |
||
1362 | if ($attrs) { |
||
1363 | if (!is_array($value)) { |
||
1364 | $value['!'] = $value; |
||
1365 | } |
||
1366 | foreach ($attrs as $n => $v) { |
||
1367 | $value['!' . $n] = $v; |
||
1368 | } |
||
1369 | $this->debug("in serializeType: soapval provides attributes"); |
||
1370 | } |
||
1371 | } else { |
||
1372 | $forceType = false; |
||
1373 | } |
||
1374 | |||
1375 | $xml = ''; |
||
1376 | if (strpos($type, ':')) { |
||
1377 | $uqType = substr($type, strrpos($type, ':') + 1); |
||
1378 | $ns = substr($type, 0, strrpos($type, ':')); |
||
1379 | $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); |
||
1380 | if ($this->getNamespaceFromPrefix($ns)) { |
||
1381 | $ns = $this->getNamespaceFromPrefix($ns); |
||
1382 | $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); |
||
1383 | } |
||
1384 | |||
1385 | if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ |
||
1386 | $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); |
||
1387 | if ($unqualified && $use == 'literal') { |
||
1388 | $elementNS = " xmlns=\"\""; |
||
1389 | } else { |
||
1390 | $elementNS = ''; |
||
1391 | } |
||
1392 | if (is_null($value)) { |
||
1393 | if ($use == 'literal') { |
||
1394 | // TODO: depends on minOccurs |
||
1395 | $xml = "<$name$elementNS/>"; |
||
1396 | } else { |
||
1397 | // TODO: depends on nillable, which should be checked before calling this method |
||
1398 | $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; |
||
1399 | } |
||
1400 | $this->debug("in serializeType: returning: $xml"); |
||
1401 | return $xml; |
||
1402 | } |
||
1403 | if ($uqType == 'Array') { |
||
1404 | // JBoss/Axis does this sometimes |
||
1405 | return $this->serialize_val($value, $name, false, false, false, false, $use); |
||
1406 | } |
||
1407 | if ($uqType == 'boolean') { |
||
1408 | if ((is_string($value) && $value == 'false') || (! $value)) { |
||
1409 | $value = 'false'; |
||
1410 | } else { |
||
1411 | $value = 'true'; |
||
1412 | } |
||
1413 | } |
||
1414 | if ($uqType == 'string' && gettype($value) == 'string') { |
||
1415 | $value = $this->expandEntities($value); |
||
1416 | } |
||
1417 | if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { |
||
1418 | $value = sprintf("%.0lf", $value); |
||
1419 | } |
||
1420 | // it's a scalar |
||
1421 | // TODO: what about null/nil values? |
||
1422 | // check type isn't a custom type extending xmlschema namespace |
||
1423 | if (!$this->getTypeDef($uqType, $ns)) { |
||
1424 | if ($use == 'literal') { |
||
1425 | if ($forceType) { |
||
1426 | $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; |
||
1427 | } else { |
||
1428 | $xml = "<$name$elementNS>$value</$name>"; |
||
1429 | } |
||
1430 | } else { |
||
1431 | $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; |
||
1432 | } |
||
1433 | $this->debug("in serializeType: returning: $xml"); |
||
1434 | return $xml; |
||
1435 | } |
||
1436 | $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); |
||
1437 | } else if ($ns == 'http://xml.apache.org/xml-soap') { |
||
1438 | $this->debug('in serializeType: appears to be Apache SOAP type'); |
||
1439 | if ($uqType == 'Map') { |
||
1440 | $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); |
||
1441 | if (! $tt_prefix) { |
||
1442 | $this->debug('in serializeType: Add namespace for Apache SOAP type'); |
||
1443 | $tt_prefix = 'ns' . rand(1000, 9999); |
||
1444 | $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; |
||
1445 | // force this to be added to usedNamespaces |
||
1446 | $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); |
||
1447 | } |
||
1448 | $contents = ''; |
||
1449 | foreach($value as $k => $v) { |
||
1450 | $this->debug("serializing map element: key $k, value $v"); |
||
1451 | $contents .= '<item>'; |
||
1452 | $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); |
||
1453 | $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); |
||
1454 | $contents .= '</item>'; |
||
1455 | } |
||
1456 | if ($use == 'literal') { |
||
1457 | if ($forceType) { |
||
1458 | $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>"; |
||
1459 | } else { |
||
1460 | $xml = "<$name>$contents</$name>"; |
||
1461 | } |
||
1462 | } else { |
||
1463 | $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>"; |
||
1464 | } |
||
1465 | $this->debug("in serializeType: returning: $xml"); |
||
1466 | return $xml; |
||
1467 | } |
||
1468 | $this->debug('in serializeType: Apache SOAP type, but only support Map'); |
||
1469 | } |
||
1470 | } else { |
||
1471 | // TODO: should the type be compared to types in XSD, and the namespace |
||
1472 | // set to XSD if the type matches? |
||
1473 | $this->debug("in serializeType: No namespace for type $type"); |
||
1474 | $ns = ''; |
||
1475 | $uqType = $type; |
||
1476 | } |
||
1477 | if(!$typeDef = $this->getTypeDef($uqType, $ns)){ |
||
1478 | $this->setError("$type ($uqType) is not a supported type."); |
||
1479 | $this->debug("in serializeType: $type ($uqType) is not a supported type."); |
||
1480 | return false; |
||
1481 | } else { |
||
1482 | $this->debug("in serializeType: found typeDef"); |
||
1483 | $this->appendDebug('typeDef=' . $this->varDump($typeDef)); |
||
1484 | if (substr($uqType, -1) == '^') { |
||
1485 | $uqType = substr($uqType, 0, -1); |
||
1486 | } |
||
1487 | } |
||
1488 | if (!isset($typeDef['phpType'])) { |
||
1489 | $this->setError("$type ($uqType) has no phpType."); |
||
1490 | $this->debug("in serializeType: $type ($uqType) has no phpType."); |
||
1491 | return false; |
||
1492 | } |
||
1493 | $phpType = $typeDef['phpType']; |
||
1494 | $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); |
||
1495 | // if php type == struct, map value to the <all> element names |
||
1496 | if ($phpType == 'struct') { |
||
1497 | if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { |
||
1498 | $elementName = $uqType; |
||
1499 | if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { |
||
1500 | $elementNS = " xmlns=\"$ns\""; |
||
1501 | } else { |
||
1502 | $elementNS = " xmlns=\"\""; |
||
1503 | } |
||
1504 | } else { |
||
1505 | $elementName = $name; |
||
1506 | if ($unqualified) { |
||
1507 | $elementNS = " xmlns=\"\""; |
||
1508 | } else { |
||
1509 | $elementNS = ''; |
||
1510 | } |
||
1511 | } |
||
1512 | if (is_null($value)) { |
||
1513 | if ($use == 'literal') { |
||
1514 | // TODO: depends on minOccurs and nillable |
||
1515 | $xml = "<$elementName$elementNS/>"; |
||
1516 | } else { |
||
1517 | $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; |
||
1518 | } |
||
1519 | $this->debug("in serializeType: returning: $xml"); |
||
1520 | return $xml; |
||
1521 | } |
||
1522 | if (is_object($value)) { |
||
1523 | $value = get_object_vars($value); |
||
1524 | } |
||
1525 | if (is_array($value)) { |
||
1526 | $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); |
||
1527 | if ($use == 'literal') { |
||
1528 | if ($forceType) { |
||
1529 | $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; |
||
1530 | } else { |
||
1531 | $xml = "<$elementName$elementNS$elementAttrs>"; |
||
1532 | } |
||
1533 | } else { |
||
1534 | $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; |
||
1535 | } |
||
1536 | |||
1537 | if (isset($typeDef['simpleContent']) && $typeDef['simpleContent'] == 'true') { |
||
1538 | if (isset($value['!'])) { |
||
1539 | $xml .= $value['!']; |
||
1540 | $this->debug("in serializeType: serialized simpleContent for type $type"); |
||
1541 | } else { |
||
1542 | $this->debug("in serializeType: no simpleContent to serialize for type $type"); |
||
1543 | } |
||
1544 | } else { |
||
1545 | // complexContent |
||
1546 | $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); |
||
1547 | } |
||
1548 | $xml .= "</$elementName>"; |
||
1549 | } else { |
||
1550 | $this->debug("in serializeType: phpType is struct, but value is not an array"); |
||
1551 | $this->setError("phpType is struct, but value is not an array: see debug output for details"); |
||
1552 | $xml = ''; |
||
1553 | } |
||
1554 | } elseif ($phpType == 'array') { |
||
1555 | if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { |
||
1556 | $elementNS = " xmlns=\"$ns\""; |
||
1557 | } else { |
||
1558 | if ($unqualified) { |
||
1559 | $elementNS = " xmlns=\"\""; |
||
1560 | } else { |
||
1561 | $elementNS = ''; |
||
1562 | } |
||
1563 | } |
||
1564 | if (is_null($value)) { |
||
1565 | if ($use == 'literal') { |
||
1566 | // TODO: depends on minOccurs |
||
1567 | $xml = "<$name$elementNS/>"; |
||
1568 | } else { |
||
1569 | $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . |
||
1570 | $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . |
||
1571 | ":Array\" " . |
||
1572 | $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . |
||
1573 | ':arrayType="' . |
||
1574 | $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . |
||
0 ignored issues
–
show
|
|||
1575 | ':' . |
||
1576 | $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; |
||
1577 | } |
||
1578 | $this->debug("in serializeType: returning: $xml"); |
||
1579 | return $xml; |
||
1580 | } |
||
1581 | if (isset($typeDef['multidimensional'])) { |
||
1582 | $nv = array(); |
||
1583 | foreach($value as $v) { |
||
0 ignored issues
–
show
The expression
$value of type object|integer|double|string|array|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1584 | $cols = ',' . sizeof($v); |
||
1585 | $nv = array_merge($nv, $v); |
||
1586 | } |
||
1587 | $value = $nv; |
||
1588 | } else { |
||
1589 | $cols = ''; |
||
1590 | } |
||
1591 | if (is_array($value) && sizeof($value) >= 1) { |
||
1592 | $rows = sizeof($value); |
||
1593 | $contents = ''; |
||
1594 | foreach($value as $k => $v) { |
||
1595 | $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); |
||
1596 | //if (strpos($typeDef['arrayType'], ':') ) { |
||
1597 | if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { |
||
1598 | $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); |
||
1599 | } else { |
||
1600 | $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); |
||
1601 | } |
||
1602 | } |
||
1603 | } else { |
||
1604 | $rows = 0; |
||
1605 | $contents = null; |
||
1606 | } |
||
1607 | // TODO: for now, an empty value will be serialized as a zero element |
||
1608 | // array. Revisit this when coding the handling of null/nil values. |
||
1609 | if ($use == 'literal') { |
||
1610 | $xml = "<$name$elementNS>" |
||
1611 | .$contents |
||
1612 | ."</$name>"; |
||
1613 | } else { |
||
1614 | $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. |
||
1615 | $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') |
||
1616 | .':arrayType="' |
||
1617 | .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) |
||
0 ignored issues
–
show
|
|||
1618 | .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" |
||
1619 | .$contents |
||
1620 | ."</$name>"; |
||
1621 | } |
||
1622 | } elseif ($phpType == 'scalar') { |
||
1623 | if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { |
||
1624 | $elementNS = " xmlns=\"$ns\""; |
||
1625 | } else { |
||
1626 | if ($unqualified) { |
||
1627 | $elementNS = " xmlns=\"\""; |
||
1628 | } else { |
||
1629 | $elementNS = ''; |
||
1630 | } |
||
1631 | } |
||
1632 | if ($use == 'literal') { |
||
1633 | if ($forceType) { |
||
1634 | $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>"; |
||
1635 | } else { |
||
1636 | $xml = "<$name$elementNS>$value</$name>"; |
||
1637 | } |
||
1638 | } else { |
||
1639 | $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>"; |
||
1640 | } |
||
1641 | } |
||
1642 | $this->debug("in serializeType: returning: $xml"); |
||
1643 | return $xml; |
||
1644 | } |
||
1645 | |||
1646 | /** |
||
1647 | * serializes the attributes for a complexType |
||
1648 | * |
||
1649 | * @param array $typeDef our internal representation of an XML schema type (or element) |
||
1650 | * @param mixed $value a native PHP value (parameter value) |
||
1651 | * @param string $ns the namespace of the type |
||
1652 | * @param string $uqType the local part of the type |
||
1653 | * @return string value serialized as an XML string |
||
1654 | * @access private |
||
1655 | */ |
||
1656 | function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { |
||
1657 | $this->debug("serializeComplexTypeAttributes for XML Schema type $ns:$uqType"); |
||
1658 | $xml = ''; |
||
1659 | if (isset($typeDef['extensionBase'])) { |
||
1660 | $nsx = $this->getPrefix($typeDef['extensionBase']); |
||
1661 | $uqTypex = $this->getLocalPart($typeDef['extensionBase']); |
||
1662 | if ($this->getNamespaceFromPrefix($nsx)) { |
||
0 ignored issues
–
show
It seems like
$nsx defined by $this->getPrefix($typeDef['extensionBase']) on line 1660 can also be of type false ; however, nusoap_base::getNamespaceFromPrefix() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
1663 | $nsx = $this->getNamespaceFromPrefix($nsx); |
||
0 ignored issues
–
show
It seems like
$nsx defined by $this->getNamespaceFromPrefix($nsx) on line 1663 can also be of type false ; however, nusoap_base::getNamespaceFromPrefix() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
1664 | } |
||
1665 | if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) { |
||
1666 | $this->debug("serialize attributes for extension base $nsx:$uqTypex"); |
||
1667 | $xml .= $this->serializeComplexTypeAttributes($typeDefx, $value, $nsx, $uqTypex); |
||
1668 | } else { |
||
1669 | $this->debug("extension base $nsx:$uqTypex is not a supported type"); |
||
1670 | } |
||
1671 | } |
||
1672 | if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { |
||
1673 | $this->debug("serialize attributes for XML Schema type $ns:$uqType"); |
||
1674 | if (is_array($value)) { |
||
1675 | $xvalue = $value; |
||
1676 | } elseif (is_object($value)) { |
||
1677 | $xvalue = get_object_vars($value); |
||
1678 | } else { |
||
1679 | $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); |
||
1680 | $xvalue = array(); |
||
1681 | } |
||
1682 | foreach ($typeDef['attrs'] as $aName => $attrs) { |
||
1683 | if (isset($xvalue['!' . $aName])) { |
||
1684 | $xname = '!' . $aName; |
||
1685 | $this->debug("value provided for attribute $aName with key $xname"); |
||
1686 | } elseif (isset($xvalue[$aName])) { |
||
1687 | $xname = $aName; |
||
1688 | $this->debug("value provided for attribute $aName with key $xname"); |
||
1689 | } elseif (isset($attrs['default'])) { |
||
1690 | $xname = '!' . $aName; |
||
1691 | $xvalue[$xname] = $attrs['default']; |
||
1692 | $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); |
||
1693 | } else { |
||
1694 | $xname = ''; |
||
1695 | $this->debug("no value provided for attribute $aName"); |
||
1696 | } |
||
1697 | if ($xname) { |
||
1698 | $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; |
||
1699 | } |
||
1700 | } |
||
1701 | } else { |
||
1702 | $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); |
||
1703 | } |
||
1704 | return $xml; |
||
1705 | } |
||
1706 | |||
1707 | /** |
||
1708 | * serializes the elements for a complexType |
||
1709 | * |
||
1710 | * @param array $typeDef our internal representation of an XML schema type (or element) |
||
1711 | * @param mixed $value a native PHP value (parameter value) |
||
1712 | * @param string $ns the namespace of the type |
||
1713 | * @param string $uqType the local part of the type |
||
1714 | * @param string $use use for part (encoded|literal) |
||
1715 | * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) |
||
1716 | * @return string value serialized as an XML string |
||
1717 | * @access private |
||
1718 | */ |
||
1719 | function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { |
||
1720 | $this->debug("in serializeComplexTypeElements for XML Schema type $ns:$uqType"); |
||
1721 | $xml = ''; |
||
1722 | if (isset($typeDef['extensionBase'])) { |
||
1723 | $nsx = $this->getPrefix($typeDef['extensionBase']); |
||
1724 | $uqTypex = $this->getLocalPart($typeDef['extensionBase']); |
||
1725 | if ($this->getNamespaceFromPrefix($nsx)) { |
||
0 ignored issues
–
show
It seems like
$nsx defined by $this->getPrefix($typeDef['extensionBase']) on line 1723 can also be of type false ; however, nusoap_base::getNamespaceFromPrefix() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
1726 | $nsx = $this->getNamespaceFromPrefix($nsx); |
||
0 ignored issues
–
show
It seems like
$nsx defined by $this->getNamespaceFromPrefix($nsx) on line 1726 can also be of type false ; however, nusoap_base::getNamespaceFromPrefix() does only seem to accept string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
1727 | } |
||
1728 | if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) { |
||
1729 | $this->debug("serialize elements for extension base $nsx:$uqTypex"); |
||
1730 | $xml .= $this->serializeComplexTypeElements($typeDefx, $value, $nsx, $uqTypex, $use, $encodingStyle); |
||
1731 | } else { |
||
1732 | $this->debug("extension base $nsx:$uqTypex is not a supported type"); |
||
1733 | } |
||
1734 | } |
||
1735 | if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { |
||
1736 | $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); |
||
1737 | if (is_array($value)) { |
||
1738 | $xvalue = $value; |
||
1739 | } elseif (is_object($value)) { |
||
1740 | $xvalue = get_object_vars($value); |
||
1741 | } else { |
||
1742 | $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); |
||
1743 | $xvalue = array(); |
||
1744 | } |
||
1745 | // toggle whether all elements are present - ideally should validate against schema |
||
1746 | if (count($typeDef['elements']) != count($xvalue)){ |
||
1747 | $optionals = true; |
||
1748 | } |
||
1749 | foreach ($typeDef['elements'] as $eName => $attrs) { |
||
1750 | if (!isset($xvalue[$eName])) { |
||
1751 | if (isset($attrs['default'])) { |
||
1752 | $xvalue[$eName] = $attrs['default']; |
||
1753 | $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); |
||
1754 | } |
||
1755 | } |
||
1756 | // if user took advantage of a minOccurs=0, then only serialize named parameters |
||
1757 | if (isset($optionals) |
||
1758 | && (!isset($xvalue[$eName])) |
||
1759 | && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') |
||
1760 | ){ |
||
1761 | if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { |
||
1762 | $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); |
||
1763 | } |
||
1764 | // do nothing |
||
1765 | $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); |
||
1766 | } else { |
||
1767 | // get value |
||
1768 | if (isset($xvalue[$eName])) { |
||
1769 | $v = $xvalue[$eName]; |
||
1770 | } else { |
||
1771 | $v = null; |
||
1772 | } |
||
1773 | if (isset($attrs['form'])) { |
||
1774 | $unqualified = ($attrs['form'] == 'unqualified'); |
||
1775 | } else { |
||
1776 | $unqualified = false; |
||
1777 | } |
||
1778 | if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { |
||
1779 | $vv = $v; |
||
1780 | foreach ($vv as $k => $v) { |
||
1781 | if (isset($attrs['type']) || isset($attrs['ref'])) { |
||
1782 | // serialize schema-defined type |
||
1783 | $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); |
||
1784 | } else { |
||
1785 | // serialize generic type (can this ever really happen?) |
||
1786 | $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); |
||
1787 | $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); |
||
1788 | } |
||
1789 | } |
||
1790 | } else { |
||
1791 | if (is_null($v) && isset($attrs['minOccurs']) && $attrs['minOccurs'] == '0') { |
||
0 ignored issues
–
show
This
if statement is empty and can be removed.
This check looks for the bodies of These if (rand(1, 6) > 3) {
//print "Check failed";
} else {
print "Check succeeded";
}
could be turned into if (rand(1, 6) <= 3) {
print "Check succeeded";
}
This is much more concise to read. ![]() |
|||
1792 | // do nothing |
||
1793 | } elseif (is_null($v) && isset($attrs['nillable']) && $attrs['nillable'] == 'true') { |
||
1794 | // TODO: serialize a nil correctly, but for now serialize schema-defined type |
||
1795 | $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); |
||
1796 | } elseif (isset($attrs['type']) || isset($attrs['ref'])) { |
||
1797 | // serialize schema-defined type |
||
1798 | $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); |
||
1799 | } else { |
||
1800 | // serialize generic type (can this ever really happen?) |
||
1801 | $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); |
||
1802 | $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); |
||
1803 | } |
||
1804 | } |
||
1805 | } |
||
1806 | } |
||
1807 | } else { |
||
1808 | $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); |
||
1809 | } |
||
1810 | return $xml; |
||
1811 | } |
||
1812 | |||
1813 | /** |
||
1814 | * adds an XML Schema complex type to the WSDL types |
||
1815 | * |
||
1816 | * @param string $name |
||
1817 | * @param string $typeClass (complexType|simpleType|attribute) |
||
1818 | * @param string $phpType currently supported are array and struct (php assoc array) |
||
1819 | * @param string $compositor (all|sequence|choice) |
||
1820 | * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) |
||
1821 | * @param array $elements e.g. array ( name => array(name=>'',type=>'') ) |
||
1822 | * @param array $attrs e.g. array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) |
||
1823 | * @param string $arrayType as namespace:name (xsd:string) |
||
1824 | * @see nusoap_xmlschema |
||
1825 | * @access public |
||
1826 | */ |
||
1827 | function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { |
||
1828 | if (count($elements) > 0) { |
||
1829 | $eElements = array(); |
||
1830 | foreach($elements as $n => $e){ |
||
1831 | // expand each element |
||
1832 | $ee = array(); |
||
1833 | foreach ($e as $k => $v) { |
||
1834 | $k = strpos($k,':') ? $this->expandQname($k) : $k; |
||
1835 | $v = strpos($v,':') ? $this->expandQname($v) : $v; |
||
1836 | $ee[$k] = $v; |
||
1837 | } |
||
1838 | $eElements[$n] = $ee; |
||
1839 | } |
||
1840 | $elements = $eElements; |
||
1841 | } |
||
1842 | |||
1843 | if (count($attrs) > 0) { |
||
1844 | foreach($attrs as $n => $a){ |
||
1845 | // expand each attribute |
||
1846 | foreach ($a as $k => $v) { |
||
1847 | $k = strpos($k,':') ? $this->expandQname($k) : $k; |
||
1848 | $v = strpos($v,':') ? $this->expandQname($v) : $v; |
||
1849 | $aa[$k] = $v; |
||
1850 | } |
||
1851 | $eAttrs[$n] = $aa; |
||
1852 | } |
||
1853 | $attrs = $eAttrs; |
||
1854 | } |
||
1855 | |||
1856 | $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; |
||
1857 | $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; |
||
1858 | |||
1859 | $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; |
||
1860 | $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); |
||
1861 | } |
||
1862 | |||
1863 | /** |
||
1864 | * adds an XML Schema simple type to the WSDL types |
||
1865 | * |
||
1866 | * @param string $name |
||
1867 | * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) |
||
1868 | * @param string $typeClass (should always be simpleType) |
||
1869 | * @param string $phpType (should always be scalar) |
||
1870 | * @param array $enumeration array of values |
||
1871 | * @see nusoap_xmlschema |
||
1872 | * @access public |
||
1873 | */ |
||
1874 | function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { |
||
1875 | $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; |
||
1876 | |||
1877 | $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; |
||
1878 | $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); |
||
1879 | } |
||
1880 | |||
1881 | /** |
||
1882 | * adds an element to the WSDL types |
||
1883 | * |
||
1884 | * @param array $attrs attributes that must include name and type |
||
1885 | * @see nusoap_xmlschema |
||
1886 | * @access public |
||
1887 | */ |
||
1888 | function addElement($attrs) { |
||
1889 | $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; |
||
1890 | $this->schemas[$typens][0]->addElement($attrs); |
||
1891 | } |
||
1892 | |||
1893 | /** |
||
1894 | * register an operation with the server |
||
1895 | * |
||
1896 | * @param string $name operation (method) name |
||
1897 | * @param array $in assoc array of input values: key = param name, value = param type |
||
1898 | * @param array $out assoc array of output values: key = param name, value = param type |
||
1899 | * @param string $namespace optional The namespace for the operation |
||
1900 | * @param string $soapaction optional The soapaction for the operation |
||
1901 | * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically |
||
1902 | * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) |
||
1903 | * @param string $documentation optional The description to include in the WSDL |
||
1904 | * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) |
||
1905 | * @access public |
||
1906 | */ |
||
1907 | function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ |
||
1908 | if ($use == 'encoded' && $encodingStyle == '') { |
||
1909 | $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; |
||
1910 | } |
||
1911 | |||
1912 | if ($style == 'document') { |
||
1913 | $elements = array(); |
||
1914 | foreach ($in as $n => $t) { |
||
0 ignored issues
–
show
The expression
$in of type false|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1915 | $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified'); |
||
1916 | } |
||
1917 | $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); |
||
1918 | $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); |
||
1919 | $in = array('parameters' => 'tns:' . $name . '^'); |
||
1920 | |||
1921 | $elements = array(); |
||
1922 | foreach ($out as $n => $t) { |
||
0 ignored issues
–
show
The expression
$out of type false|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1923 | $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified'); |
||
1924 | } |
||
1925 | $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); |
||
1926 | $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified')); |
||
1927 | $out = array('parameters' => 'tns:' . $name . 'Response' . '^'); |
||
1928 | } |
||
1929 | |||
1930 | // get binding |
||
1931 | $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = |
||
1932 | array( |
||
1933 | 'name' => $name, |
||
1934 | 'binding' => $this->serviceName . 'Binding', |
||
1935 | 'endpoint' => $this->endpoint, |
||
1936 | 'soapAction' => $soapaction, |
||
1937 | 'style' => $style, |
||
1938 | 'input' => array( |
||
1939 | 'use' => $use, |
||
1940 | 'namespace' => $namespace, |
||
1941 | 'encodingStyle' => $encodingStyle, |
||
1942 | 'message' => $name . 'Request', |
||
1943 | 'parts' => $in), |
||
1944 | 'output' => array( |
||
1945 | 'use' => $use, |
||
1946 | 'namespace' => $namespace, |
||
1947 | 'encodingStyle' => $encodingStyle, |
||
1948 | 'message' => $name . 'Response', |
||
1949 | 'parts' => $out), |
||
1950 | 'namespace' => $namespace, |
||
1951 | 'transport' => 'http://schemas.xmlsoap.org/soap/http', |
||
1952 | 'documentation' => $documentation); |
||
1953 | // add portTypes |
||
1954 | // add messages |
||
1955 | if($in) |
||
1956 | { |
||
1957 | foreach($in as $pName => $pType) |
||
1958 | { |
||
1959 | if(strpos($pType,':')) { |
||
1960 | $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); |
||
0 ignored issues
–
show
|
|||
1961 | } |
||
1962 | $this->messages[$name.'Request'][$pName] = $pType; |
||
1963 | } |
||
1964 | } else { |
||
1965 | $this->messages[$name.'Request']= '0'; |
||
1966 | } |
||
1967 | if($out) |
||
1968 | { |
||
1969 | foreach($out as $pName => $pType) |
||
1970 | { |
||
1971 | if(strpos($pType,':')) { |
||
1972 | $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); |
||
0 ignored issues
–
show
|
|||
1973 | } |
||
1974 | $this->messages[$name.'Response'][$pName] = $pType; |
||
1975 | } |
||
1976 | } else { |
||
1977 | $this->messages[$name.'Response']= '0'; |
||
1978 | } |
||
1979 | return true; |
||
1980 | } |
||
1981 | } |
||
1982 | |||
1983 | ?> |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.