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 | IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002 |
||
5 | Version 1.62WP - Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars) |
||
6 | ^^^^^^ (We've made some changes) |
||
7 | Site: http://scripts.incutio.com/xmlrpc/ |
||
8 | Manual: http://scripts.incutio.com/xmlrpc/manual.php |
||
9 | Made available under the BSD License: http://www.opensource.org/licenses/bsd-license.php |
||
10 | */ |
||
11 | |||
12 | /** |
||
13 | * Class IXR_Value |
||
14 | */ |
||
15 | class IXR_Value |
||
16 | { |
||
17 | public $data; |
||
18 | public $type; |
||
19 | |||
20 | /** |
||
21 | * IXR_Value constructor. |
||
22 | * @param $data |
||
23 | * @param bool $type |
||
24 | */ |
||
25 | public function __construct($data, $type = false) |
||
26 | { |
||
27 | $this->data = $data; |
||
28 | if (!$type) { |
||
29 | $type = $this->calculateType(); |
||
30 | } |
||
31 | $this->type = $type; |
||
32 | if ('struct' === $type) { |
||
33 | /* Turn all the values in the array in to new IXR_Value objects */ |
||
34 | foreach ($this->data as $key => $value) { |
||
35 | $this->data[$key] = new IXR_Value($value); |
||
36 | } |
||
37 | } |
||
38 | if ('array' === $type) { |
||
39 | for ($i = 0, $j = count($this->data); $i < $j; ++$i) { |
||
40 | $this->data[$i] = new IXR_Value($this->data[$i]); |
||
41 | } |
||
42 | } |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * @return string |
||
47 | */ |
||
48 | public function calculateType() |
||
49 | { |
||
50 | if (true === $this->data || false === $this->data) { |
||
51 | return 'boolean'; |
||
52 | } |
||
53 | if (is_int($this->data)) { |
||
54 | return 'int'; |
||
55 | } |
||
56 | if (is_float($this->data)) { |
||
57 | return 'double'; |
||
58 | } |
||
59 | // Deal with IXR object types base64 and date |
||
60 | if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { |
||
61 | return 'date'; |
||
62 | } |
||
63 | if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { |
||
64 | return 'base64'; |
||
65 | } |
||
66 | // If it is a normal PHP object convert it in to a struct |
||
67 | if (is_object($this->data)) { |
||
68 | $this->data = get_object_vars($this->data); |
||
69 | |||
70 | return 'struct'; |
||
71 | } |
||
72 | if (!is_array($this->data)) { |
||
73 | return 'string'; |
||
74 | } |
||
75 | /* We have an array - is it an array or a struct ? */ |
||
76 | if ($this->isStruct($this->data)) { |
||
77 | return 'struct'; |
||
78 | } else { |
||
79 | return 'array'; |
||
80 | } |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * @return bool|string |
||
85 | */ |
||
86 | public function getXml() |
||
87 | { |
||
88 | /* Return XML for this value */ |
||
89 | switch ($this->type) { |
||
90 | case 'boolean': |
||
91 | return '<boolean>' . ($this->data ? '1' : '0') . '</boolean>'; |
||
92 | break; |
||
0 ignored issues
–
show
|
|||
93 | case 'int': |
||
94 | return '<int>' . $this->data . '</int>'; |
||
95 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
96 | case 'double': |
||
97 | return '<double>' . $this->data . '</double>'; |
||
98 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
99 | case 'string': |
||
100 | return '<string>' . htmlspecialchars($this->data, ENT_QUOTES | ENT_HTML5) . '</string>'; |
||
101 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
102 | case 'array': |
||
103 | $return = '<array><data>' . "\n"; |
||
104 | foreach ($this->data as $item) { |
||
105 | $return .= ' <value>' . $item->getXml() . "</value>\n"; |
||
106 | } |
||
107 | $return .= '</data></array>'; |
||
108 | |||
109 | return $return; |
||
110 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
111 | case 'struct': |
||
112 | $return = '<struct>' . "\n"; |
||
113 | foreach ($this->data as $name => $value) { |
||
114 | $return .= " <member><name>$name</name><value>"; |
||
115 | $return .= $value->getXml() . "</value></member>\n"; |
||
116 | } |
||
117 | $return .= '</struct>'; |
||
118 | |||
119 | return $return; |
||
120 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
121 | case 'date': |
||
122 | case 'base64': |
||
123 | return $this->data->getXml(); |
||
0 ignored issues
–
show
|
|||
124 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
125 | } |
||
126 | |||
127 | return false; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * @param $array |
||
132 | * @return bool |
||
133 | */ |
||
134 | public function isStruct($array) |
||
135 | { |
||
136 | /* Nasty function to check if an array is a struct or not */ |
||
137 | $expected = 0; |
||
138 | foreach ($array as $key => $value) { |
||
139 | if ((string)$key != (string)$expected) { |
||
140 | return true; |
||
141 | } |
||
142 | ++$expected; |
||
143 | } |
||
144 | |||
145 | return false; |
||
146 | } |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Class IXR_Message |
||
151 | */ |
||
152 | class IXR_Message |
||
153 | { |
||
154 | public $message; |
||
155 | public $messageType; // methodCall / methodResponse / fault |
||
156 | public $faultCode; |
||
157 | public $faultString; |
||
158 | public $methodName; |
||
159 | public $params; |
||
160 | // Current variable stacks |
||
161 | public $_arraystructs = []; // The stack used to keep track of the current array/struct |
||
162 | public $_arraystructstypes = []; // Stack keeping track of if things are structs or array |
||
163 | public $_currentStructName = []; // A stack as well |
||
164 | public $_param; |
||
165 | public $_value; |
||
166 | public $_currentTag; |
||
167 | public $_currentTagContents; |
||
168 | // The XML parser |
||
169 | public $_parser; |
||
170 | |||
171 | /** |
||
172 | * IXR_Message constructor. |
||
173 | * @param $message |
||
174 | */ |
||
175 | public function __construct($message) |
||
176 | { |
||
177 | $this->message = $message; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * @return bool |
||
182 | */ |
||
183 | public function parse() |
||
184 | { |
||
185 | // first remove the XML declaration |
||
186 | $this->message = preg_replace('/<\?xml(.*)?\?' . '>/', '', $this->message); |
||
187 | if ('' == trim($this->message)) { |
||
188 | return false; |
||
189 | } |
||
190 | $this->_parser = xml_parser_create(); |
||
191 | // Set XML parser to take the case of tags in to account |
||
192 | xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); |
||
193 | // Set XML parser callback functions |
||
194 | xml_set_object($this->_parser, $this); |
||
195 | xml_set_elementHandler($this->_parser, 'tag_open', 'tag_close'); |
||
196 | xml_set_character_dataHandler($this->_parser, 'cdata'); |
||
197 | if (!xml_parse($this->_parser, $this->message)) { |
||
198 | /* die(sprintf('XML error: %s at line %d', |
||
199 | xml_error_string(xml_get_error_code($this->_parser)), |
||
200 | xml_get_current_line_number($this->_parser))); */ |
||
201 | |||
202 | return false; |
||
203 | } |
||
204 | xml_parser_free($this->_parser); |
||
205 | // Grab the error messages, if any |
||
206 | if ('fault' === $this->messageType) { |
||
207 | $this->faultCode = $this->params[0]['faultCode']; |
||
208 | $this->faultString = $this->params[0]['faultString']; |
||
209 | } |
||
210 | |||
211 | return true; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * @param $parser |
||
216 | * @param $tag |
||
217 | * @param $attr |
||
218 | */ |
||
219 | public function tag_open($parser, $tag, $attr) |
||
0 ignored issues
–
show
|
|||
220 | { |
||
221 | $this->currentTag = $tag; |
||
0 ignored issues
–
show
The property
currentTag does not seem to exist. Did you mean _currentTag ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
222 | switch ($tag) { |
||
223 | case 'methodCall': |
||
224 | case 'methodResponse': |
||
225 | case 'fault': |
||
226 | $this->messageType = $tag; |
||
227 | break; |
||
228 | /* Deal with stacks of arrays and structs */ |
||
229 | case 'data': // data is to all intents and puposes more interesting than array |
||
230 | $this->_arraystructstypes[] = 'array'; |
||
231 | $this->_arraystructs[] = []; |
||
232 | break; |
||
233 | case 'struct': |
||
234 | $this->_arraystructstypes[] = 'struct'; |
||
235 | $this->_arraystructs[] = []; |
||
236 | break; |
||
237 | } |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * @param $parser |
||
242 | * @param $cdata |
||
243 | */ |
||
244 | public function cdata($parser, $cdata) |
||
0 ignored issues
–
show
|
|||
245 | { |
||
246 | $this->_currentTagContents .= $cdata; |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * @param $parser |
||
251 | * @param $tag |
||
252 | */ |
||
253 | public function tag_close($parser, $tag) |
||
0 ignored issues
–
show
|
|||
254 | { |
||
255 | $valueFlag = false; |
||
256 | switch ($tag) { |
||
257 | case 'int': |
||
258 | case 'i4': |
||
259 | $value = (int)trim($this->_currentTagContents); |
||
260 | $this->_currentTagContents = ''; |
||
261 | $valueFlag = true; |
||
262 | break; |
||
263 | case 'double': |
||
264 | $value = (double)trim($this->_currentTagContents); |
||
265 | $this->_currentTagContents = ''; |
||
266 | $valueFlag = true; |
||
267 | break; |
||
268 | case 'string': |
||
269 | $value = trim($this->_currentTagContents); |
||
270 | $this->_currentTagContents = ''; |
||
271 | $valueFlag = true; |
||
272 | break; |
||
273 | case 'dateTime.iso8601': |
||
274 | $value = new IXR_Date(trim($this->_currentTagContents)); |
||
275 | // $value = $iso->getTimestamp(); |
||
276 | $this->_currentTagContents = ''; |
||
277 | $valueFlag = true; |
||
278 | break; |
||
279 | View Code Duplication | case 'value': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
280 | // "If no type is indicated, the type is string." |
||
281 | if ('' != trim($this->_currentTagContents)) { |
||
282 | $value = (string)$this->_currentTagContents; |
||
283 | $this->_currentTagContents = ''; |
||
284 | $valueFlag = true; |
||
285 | } |
||
286 | break; |
||
287 | View Code Duplication | case 'boolean': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
288 | $value = (boolean)trim($this->_currentTagContents); |
||
289 | $this->_currentTagContents = ''; |
||
290 | $valueFlag = true; |
||
291 | break; |
||
292 | case 'base64': |
||
293 | $value = base64_decode(trim($this->_currentTagContents)); |
||
294 | $this->_currentTagContents = ''; |
||
295 | $valueFlag = true; |
||
296 | break; |
||
297 | /* Deal with stacks of arrays and structs */ |
||
298 | case 'data': |
||
299 | case 'struct': |
||
300 | $value = array_pop($this->_arraystructs); |
||
301 | array_pop($this->_arraystructstypes); |
||
302 | $valueFlag = true; |
||
303 | break; |
||
304 | case 'member': |
||
305 | array_pop($this->_currentStructName); |
||
306 | break; |
||
307 | case 'name': |
||
308 | $this->_currentStructName[] = trim($this->_currentTagContents); |
||
309 | $this->_currentTagContents = ''; |
||
310 | break; |
||
311 | case 'methodName': |
||
312 | $this->methodName = trim($this->_currentTagContents); |
||
313 | $this->_currentTagContents = ''; |
||
314 | break; |
||
315 | } |
||
316 | if ($valueFlag) { |
||
317 | /* |
||
318 | if (!is_array($value) && !is_object($value)) { |
||
319 | $value = trim($value); |
||
320 | } |
||
321 | */ |
||
322 | if (count($this->_arraystructs) > 0) { |
||
323 | // Add value to struct or array |
||
324 | if ('struct' === $this->_arraystructstypes[count($this->_arraystructstypes) - 1]) { |
||
325 | // Add to struct |
||
326 | $this->_arraystructs[count($this->_arraystructs) - 1][$this->_currentStructName[count($this->_currentStructName) - 1]] = $value; |
||
0 ignored issues
–
show
The variable
$value does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
327 | } else { |
||
328 | // Add to array |
||
329 | $this->_arraystructs[count($this->_arraystructs) - 1][] = $value; |
||
330 | } |
||
331 | } else { |
||
332 | // Just add as a paramater |
||
333 | $this->params[] = $value; |
||
334 | } |
||
335 | } |
||
336 | } |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * Class IXR_Server |
||
341 | */ |
||
342 | class IXR_Server |
||
343 | { |
||
344 | public $data; |
||
345 | public $callbacks = []; |
||
346 | public $message; |
||
347 | public $capabilities; |
||
348 | |||
349 | /** |
||
350 | * IXR_Server constructor. |
||
351 | * @param bool $callbacks |
||
352 | * @param bool $data |
||
353 | */ |
||
354 | public function __construct($callbacks = false, $data = false) |
||
355 | { |
||
356 | $this->setCapabilities(); |
||
357 | if ($callbacks) { |
||
358 | $this->callbacks = $callbacks; |
||
0 ignored issues
–
show
It seems like
$callbacks of type boolean is incompatible with the declared type array of property $callbacks .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
359 | } |
||
360 | $this->setCallbacks(); |
||
361 | $this->serve($data); |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * @param bool $data |
||
366 | */ |
||
367 | public function serve($data = false) |
||
368 | { |
||
369 | if (!$data) { |
||
370 | $http_raw_post_data = file_get_contents('php://input'); |
||
371 | if (!$http_raw_post_data) { |
||
372 | die('XML-RPC server accepts POST requests only.'); |
||
373 | } |
||
374 | $data = $http_raw_post_data; |
||
375 | } |
||
376 | $this->message = new IXR_Message($data); |
||
377 | if (!$this->message->parse()) { |
||
378 | $this->error(-32700, 'parse error. not well formed'); |
||
0 ignored issues
–
show
'parse error. not well formed' is of type string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
379 | } |
||
380 | if ('methodCall' !== $this->message->messageType) { |
||
381 | $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall'); |
||
0 ignored issues
–
show
'server error. invalid x...t must be a methodCall' is of type string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
382 | } |
||
383 | $result = $this->call($this->message->methodName, $this->message->params); |
||
384 | // Is the result an error? |
||
385 | if (is_a($result, 'IXR_Error')) { |
||
386 | $this->error($result); |
||
387 | } |
||
388 | // Encode the result |
||
389 | $r = new IXR_Value($result); |
||
390 | $resultxml = $r->getXml(); |
||
391 | // Create the XML |
||
392 | $xml = <<<EOD |
||
393 | <methodResponse> |
||
394 | <params> |
||
395 | <param> |
||
396 | <value> |
||
397 | $resultxml |
||
398 | </value> |
||
399 | </param> |
||
400 | </params> |
||
401 | </methodResponse> |
||
402 | |||
403 | EOD; |
||
404 | // Send it |
||
405 | $this->output($xml); |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * @param $methodname |
||
410 | * @param $args |
||
411 | * @return IXR_Error|mixed |
||
412 | */ |
||
413 | public function call($methodname, $args) |
||
414 | { |
||
415 | if (!$this->hasMethod($methodname)) { |
||
416 | return new IXR_Error(-32601, 'server error. requested method ' . $methodname . ' does not exist.'); |
||
417 | } |
||
418 | $method = $this->callbacks[$methodname]; |
||
419 | // Perform the callback and send the response |
||
420 | if (1 == count($args)) { |
||
421 | // If only one paramater just send that instead of the whole array |
||
422 | $args = $args[0]; |
||
423 | } |
||
424 | // Are we dealing with a function or a method? |
||
425 | if ('this:' === substr($method, 0, 5)) { |
||
426 | // It's a class method - check it exists |
||
427 | $method = substr($method, 5); |
||
428 | if (!method_exists($this, $method)) { |
||
429 | return new IXR_Error(-32601, 'server error. requested class method "' . $method . '" does not exist.'); |
||
430 | } |
||
431 | // Call the method |
||
432 | $result = $this->$method($args); |
||
433 | } else { |
||
434 | // It's a function - does it exist? |
||
435 | if (is_array($method)) { |
||
436 | if (!method_exists($method[0], $method[1])) { |
||
437 | return new IXR_Error(-32601, 'server error. requested object method "' . $method[1] . '" does not exist.'); |
||
438 | } |
||
439 | } elseif (!function_exists($method)) { |
||
440 | return new IXR_Error(-32601, 'server error. requested function "' . $method . '" does not exist.'); |
||
441 | } |
||
442 | // Call the function |
||
443 | $result = call_user_func($method, $args); |
||
444 | } |
||
445 | |||
446 | return $result; |
||
447 | } |
||
448 | |||
449 | /** |
||
450 | * @param $error |
||
451 | * @param bool $message |
||
452 | */ |
||
453 | public function error($error, $message = false) |
||
454 | { |
||
455 | // Accepts either an error object or an error code and message |
||
456 | if ($message && !is_object($error)) { |
||
457 | $error = new IXR_Error($error, $message); |
||
458 | } |
||
459 | $this->output($error->getXml()); |
||
460 | } |
||
461 | |||
462 | /** |
||
463 | * @param $xml |
||
464 | */ |
||
465 | public function output($xml) |
||
466 | { |
||
467 | $xml = '<?xml version="1.0"?>' . "\n" . $xml; |
||
468 | $length = strlen($xml); |
||
469 | header('Connection: close'); |
||
470 | header('Content-Length: ' . $length); |
||
471 | header('Content-Type: text/xml'); |
||
472 | header('Date: ' . date('r')); |
||
473 | echo $xml; |
||
474 | exit; |
||
475 | } |
||
476 | |||
477 | /** |
||
478 | * @param $method |
||
479 | * @return bool |
||
480 | */ |
||
481 | public function hasMethod($method) |
||
482 | { |
||
483 | return in_array($method, array_keys($this->callbacks)); |
||
484 | } |
||
485 | |||
486 | public function setCapabilities() |
||
487 | { |
||
488 | // Initialises capabilities array |
||
489 | $this->capabilities = [ |
||
490 | 'xmlrpc' => [ |
||
491 | 'specUrl' => 'http://www.xmlrpc.com/spec', |
||
492 | 'specVersion' => 1 |
||
493 | ], |
||
494 | 'faults_interop' => [ |
||
495 | 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', |
||
496 | 'specVersion' => 20010516 |
||
497 | ], |
||
498 | 'system.multicall' => [ |
||
499 | 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', |
||
500 | 'specVersion' => 1 |
||
501 | ] |
||
502 | ]; |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * @param $args |
||
507 | * @return mixed |
||
508 | */ |
||
509 | public function getCapabilities($args) |
||
0 ignored issues
–
show
|
|||
510 | { |
||
511 | return $this->capabilities; |
||
512 | } |
||
513 | |||
514 | public function setCallbacks() |
||
515 | { |
||
516 | $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; |
||
517 | $this->callbacks['system.listMethods'] = 'this:listMethods'; |
||
518 | $this->callbacks['system.multicall'] = 'this:multiCall'; |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * @param $args |
||
523 | * @return array |
||
524 | */ |
||
525 | public function listMethods($args) |
||
0 ignored issues
–
show
|
|||
526 | { |
||
527 | // Returns a list of methods - uses array_reverse to ensure user defined |
||
528 | // methods are listed before server defined methods |
||
529 | return array_reverse(array_keys($this->callbacks)); |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * @param $methodcalls |
||
534 | * @return array |
||
535 | */ |
||
536 | public function multiCall($methodcalls) |
||
537 | { |
||
538 | // See http://www.xmlrpc.com/discuss/msgReader$1208 |
||
539 | $return = []; |
||
540 | foreach ($methodcalls as $call) { |
||
541 | $method = $call['methodName']; |
||
542 | $params = $call['params']; |
||
543 | if ('system.multicall' === $method) { |
||
544 | $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); |
||
545 | } else { |
||
546 | $result = $this->call($method, $params); |
||
547 | } |
||
548 | if (is_a($result, 'IXR_Error')) { |
||
549 | $return[] = [ |
||
550 | 'faultCode' => $result->code, |
||
551 | 'faultString' => $result->message |
||
552 | ]; |
||
553 | } else { |
||
554 | $return[] = [$result]; |
||
555 | } |
||
556 | } |
||
557 | |||
558 | return $return; |
||
559 | } |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * Class IXR_Request |
||
564 | */ |
||
565 | class IXR_Request |
||
566 | { |
||
567 | public $method; |
||
568 | public $args; |
||
569 | public $xml; |
||
570 | |||
571 | /** |
||
572 | * IXR_Request constructor. |
||
573 | * @param $method |
||
574 | * @param $args |
||
575 | */ |
||
576 | public function __construct($method, $args) |
||
577 | { |
||
578 | $this->method = $method; |
||
579 | $this->args = $args; |
||
580 | $this->xml = <<<EOD |
||
581 | <?xml version="1.0"?> |
||
582 | <methodCall> |
||
583 | <methodName>{$this->method}</methodName> |
||
584 | <params> |
||
585 | |||
586 | EOD; |
||
587 | foreach ($this->args as $arg) { |
||
588 | $this->xml .= '<param><value>'; |
||
589 | $v = new IXR_Value($arg); |
||
590 | $this->xml .= $v->getXml(); |
||
591 | $this->xml .= "</value></param>\n"; |
||
592 | } |
||
593 | $this->xml .= '</params></methodCall>'; |
||
594 | } |
||
595 | |||
596 | /** |
||
597 | * @return int |
||
598 | */ |
||
599 | public function getLength() |
||
600 | { |
||
601 | return strlen($this->xml); |
||
602 | } |
||
603 | |||
604 | /** |
||
605 | * @return string |
||
606 | */ |
||
607 | public function getXml() |
||
608 | { |
||
609 | return $this->xml; |
||
610 | } |
||
611 | } |
||
612 | |||
613 | /** |
||
614 | * Class IXR_Client |
||
615 | */ |
||
616 | class IXR_Client |
||
617 | { |
||
618 | public $server; |
||
619 | public $port; |
||
620 | public $path; |
||
621 | public $useragent; |
||
622 | public $response; |
||
623 | public $timeout; |
||
624 | public $vendor = ''; |
||
625 | public $message = false; |
||
626 | public $debug = false; |
||
627 | // Storage place for an error message |
||
628 | public $error = false; |
||
629 | |||
630 | /** |
||
631 | * IXR_Client constructor. |
||
632 | * @param $server |
||
633 | * @param bool $path |
||
634 | * @param int $port |
||
635 | * @param int $timeout |
||
636 | * @param string $vendor |
||
637 | */ |
||
638 | public function __construct($server, $path = false, $port = 80, $timeout = 30, $vendor = '') |
||
0 ignored issues
–
show
|
|||
639 | { |
||
640 | if (!$path) { |
||
641 | // Assume we have been given a URL instead |
||
642 | $bits = parse_url($server); |
||
643 | $this->server = $bits['host']; |
||
644 | $this->port = isset($bits['port']) ? $bits['port'] : 80; |
||
645 | $this->path = isset($bits['path']) ? $bits['path'] : '/'; |
||
646 | // Make absolutely sure we have a path |
||
647 | if (!$this->path) { |
||
648 | $this->path = '/'; |
||
649 | } |
||
650 | } else { |
||
651 | $this->server = $server; |
||
652 | $this->path = $path; |
||
653 | $this->port = $port; |
||
654 | $this->timeout = $timeout; |
||
655 | } |
||
656 | $this->useragent = 'The Incutio XML-RPC PHP Library'; |
||
657 | } |
||
658 | |||
659 | /** |
||
660 | * @return bool |
||
661 | */ |
||
662 | public function query() |
||
663 | { |
||
664 | $args = func_get_args(); |
||
665 | $method = array_shift($args); |
||
666 | $request = new IXR_Request($method, $args); |
||
667 | $length = $request->getLength(); |
||
668 | $xml = $request->getXml(); |
||
669 | $r = "\r\n"; |
||
670 | $request = "POST {$this->path} HTTP/1.0$r"; |
||
671 | $request .= "Host: {$this->server}$r"; |
||
672 | $request .= "Content-Type: text/xml$r"; |
||
673 | $request .= "User-Agent: {$this->useragent}$r"; |
||
674 | $request .= "Content-length: {$length}$r$r"; |
||
675 | $request .= $xml; |
||
676 | // Now send the request |
||
677 | View Code Duplication | if ($this->debug) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
678 | echo '<pre>' . htmlspecialchars($request, ENT_QUOTES | ENT_HTML5) . "\n</pre>\n\n"; |
||
679 | } |
||
680 | $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); |
||
681 | if (!$fp) { |
||
682 | $this->error = new IXR_Error(-32300, 'transport error - could not open socket'); |
||
0 ignored issues
–
show
It seems like
new \IXR_Error(-32300, '...could not open socket') of type object<IXR_Error> is incompatible with the declared type boolean of property $error .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
683 | |||
684 | return false; |
||
685 | } |
||
686 | fwrite($fp, $request); |
||
687 | $contents = ''; |
||
688 | $gotFirstLine = false; |
||
689 | $gettingHeaders = true; |
||
690 | while (!feof($fp)) { |
||
691 | $line = fgets($fp, 4096); |
||
692 | if (!$gotFirstLine) { |
||
693 | // Check line for '200' |
||
694 | if (false === strpos($line, '200')) { |
||
695 | $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); |
||
0 ignored issues
–
show
It seems like
new \IXR_Error(-32300, '...atus code was not 200') of type object<IXR_Error> is incompatible with the declared type boolean of property $error .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
696 | |||
697 | return false; |
||
698 | } |
||
699 | $gotFirstLine = true; |
||
700 | } |
||
701 | if ('' == trim($line)) { |
||
702 | $gettingHeaders = false; |
||
703 | } |
||
704 | if (!$gettingHeaders) { |
||
705 | $contents .= trim($line) . "\n"; |
||
706 | } |
||
707 | } |
||
708 | View Code Duplication | if ($this->debug) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
709 | echo '<pre>' . htmlspecialchars($contents, ENT_QUOTES | ENT_HTML5) . "\n</pre>\n\n"; |
||
710 | } |
||
711 | // Now parse what we've got back |
||
712 | $this->message = new IXR_Message($contents); |
||
0 ignored issues
–
show
It seems like
new \IXR_Message($contents) of type object<IXR_Message> is incompatible with the declared type boolean of property $message .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
713 | if (!$this->message->parse()) { |
||
714 | // XML error |
||
715 | $this->error = new IXR_Error(-32700, 'parse error. not well formed'); |
||
0 ignored issues
–
show
It seems like
new \IXR_Error(-32700, '...rror. not well formed') of type object<IXR_Error> is incompatible with the declared type boolean of property $error .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
716 | |||
717 | return false; |
||
718 | } |
||
719 | // Is the message a fault? |
||
720 | if ('fault' === $this->message->messageType) { |
||
721 | $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); |
||
0 ignored issues
–
show
It seems like
new \IXR_Error($this->me...->message->faultString) of type object<IXR_Error> is incompatible with the declared type boolean of property $error .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
722 | |||
723 | return false; |
||
724 | } |
||
725 | |||
726 | // Message must be OK |
||
727 | return true; |
||
728 | } |
||
729 | |||
730 | /** |
||
731 | * @return mixed |
||
732 | */ |
||
733 | public function getResponse() |
||
734 | { |
||
735 | // methodResponses can only have one param - return that |
||
736 | return $this->message->params[0]; |
||
737 | } |
||
738 | |||
739 | /** |
||
740 | * @return bool |
||
741 | */ |
||
742 | public function isError() |
||
743 | { |
||
744 | return is_object($this->error); |
||
745 | } |
||
746 | |||
747 | /** |
||
748 | * @return mixed |
||
749 | */ |
||
750 | public function getErrorCode() |
||
751 | { |
||
752 | return $this->error->code; |
||
753 | } |
||
754 | |||
755 | /** |
||
756 | * @return mixed |
||
757 | */ |
||
758 | public function getErrorMessage() |
||
759 | { |
||
760 | return $this->error->message; |
||
761 | } |
||
762 | } |
||
763 | |||
764 | /** |
||
765 | * Class IXR_Error |
||
766 | */ |
||
767 | class IXR_Error |
||
768 | { |
||
769 | public $code; |
||
770 | public $message; |
||
771 | |||
772 | /** |
||
773 | * IXR_Error constructor. |
||
774 | * @param $code |
||
775 | * @param $message |
||
776 | */ |
||
777 | public function __construct($code, $message) |
||
778 | { |
||
779 | $this->code = $code; |
||
780 | $this->message = $message; |
||
781 | } |
||
782 | |||
783 | /** |
||
784 | * @return string |
||
785 | */ |
||
786 | public function getXml() |
||
787 | { |
||
788 | $xml = <<<EOD |
||
789 | <methodResponse> |
||
790 | <fault> |
||
791 | <value> |
||
792 | <struct> |
||
793 | <member> |
||
794 | <name>faultCode</name> |
||
795 | <value><int>{$this->code}</int></value> |
||
796 | </member> |
||
797 | <member> |
||
798 | <name>faultString</name> |
||
799 | <value><string>{$this->message}</string></value> |
||
800 | </member> |
||
801 | </struct> |
||
802 | </value> |
||
803 | </fault> |
||
804 | </methodResponse> |
||
805 | |||
806 | EOD; |
||
807 | |||
808 | return $xml; |
||
809 | } |
||
810 | } |
||
811 | |||
812 | /** |
||
813 | * Class IXR_Date |
||
814 | */ |
||
815 | class IXR_Date |
||
816 | { |
||
817 | public $year; |
||
818 | public $month; |
||
819 | public $day; |
||
820 | public $hour; |
||
821 | public $minute; |
||
822 | public $second; |
||
823 | public $timezone; |
||
824 | |||
825 | /** |
||
826 | * IXR_Date constructor. |
||
827 | * @param $time |
||
828 | */ |
||
829 | public function __construct($time) |
||
830 | { |
||
831 | // $time can be a PHP timestamp or an ISO one |
||
832 | if (is_numeric($time)) { |
||
833 | $this->parseTimestamp($time); |
||
834 | } else { |
||
835 | $this->parseIso($time); |
||
836 | } |
||
837 | } |
||
838 | |||
839 | /** |
||
840 | * @param $timestamp |
||
841 | */ |
||
842 | public function parseTimestamp($timestamp) |
||
843 | { |
||
844 | $this->year = date('Y', $timestamp); |
||
845 | $this->month = date('Y', $timestamp); |
||
846 | $this->day = date('Y', $timestamp); |
||
847 | $this->hour = date('H', $timestamp); |
||
848 | $this->minute = date('i', $timestamp); |
||
849 | $this->second = date('s', $timestamp); |
||
850 | } |
||
851 | |||
852 | /** |
||
853 | * @param $iso |
||
854 | */ |
||
855 | public function parseIso($iso) |
||
856 | { |
||
857 | $this->year = substr($iso, 0, 4); |
||
858 | $this->month = substr($iso, 4, 2); |
||
859 | $this->day = substr($iso, 6, 2); |
||
860 | $this->hour = substr($iso, 9, 2); |
||
861 | $this->minute = substr($iso, 12, 2); |
||
862 | $this->second = substr($iso, 15, 2); |
||
863 | $this->timezone = substr($iso, 17); |
||
864 | } |
||
865 | |||
866 | /** |
||
867 | * @return string |
||
868 | */ |
||
869 | public function getIso() |
||
870 | { |
||
871 | return $this->year . $this->month . $this->day . 'T' . $this->hour . ':' . $this->minute . ':' . $this->second . $this->timezone; |
||
872 | } |
||
873 | |||
874 | /** |
||
875 | * @return string |
||
876 | */ |
||
877 | public function getXml() |
||
878 | { |
||
879 | return '<dateTime.iso8601>' . $this->getIso() . '</dateTime.iso8601>'; |
||
880 | } |
||
881 | |||
882 | /** |
||
883 | * @return int |
||
884 | */ |
||
885 | public function getTimestamp() |
||
886 | { |
||
887 | return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); |
||
888 | } |
||
889 | } |
||
890 | |||
891 | /** |
||
892 | * Class IXR_Base64 |
||
893 | */ |
||
894 | class IXR_Base64 |
||
895 | { |
||
896 | public $data; |
||
897 | |||
898 | /** |
||
899 | * IXR_Base64 constructor. |
||
900 | * @param $data |
||
901 | */ |
||
902 | public function __construct($data) |
||
903 | { |
||
904 | $this->data = $data; |
||
905 | } |
||
906 | |||
907 | /** |
||
908 | * @return string |
||
909 | */ |
||
910 | public function getXml() |
||
911 | { |
||
912 | return '<base64>' . base64_encode($this->data) . '</base64>'; |
||
913 | } |
||
914 | } |
||
915 | |||
916 | /** |
||
917 | * Class IXR_IntrospectionServer |
||
918 | */ |
||
919 | class IXR_IntrospectionServer extends IXR_Server |
||
920 | { |
||
921 | public $signatures; |
||
922 | public $help; |
||
923 | |||
924 | /** |
||
925 | * IXR_IntrospectionServer constructor. |
||
926 | */ |
||
927 | public function __construct() |
||
928 | { |
||
929 | $this->setCallbacks(); |
||
930 | $this->setCapabilities(); |
||
931 | $this->capabilities['introspection'] = [ |
||
932 | 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', |
||
933 | 'specVersion' => 1 |
||
934 | ]; |
||
935 | $this->addCallback('system.methodSignature', 'this:methodSignature', ['array', 'string'], 'Returns an array describing the return type and required parameters of a method'); |
||
936 | $this->addCallback('system.getCapabilities', 'this:getCapabilities', ['struct'], 'Returns a struct describing the XML-RPC specifications supported by this server'); |
||
937 | $this->addCallback('system.listMethods', 'this:listMethods', ['array'], 'Returns an array of available methods on this server'); |
||
938 | $this->addCallback('system.methodHelp', 'this:methodHelp', ['string', 'string'], 'Returns a documentation string for the specified method'); |
||
939 | } |
||
940 | |||
941 | /** |
||
942 | * @param $method |
||
943 | * @param $callback |
||
944 | * @param $args |
||
945 | * @param $help |
||
946 | */ |
||
947 | public function addCallback($method, $callback, $args, $help) |
||
948 | { |
||
949 | $this->callbacks[$method] = $callback; |
||
950 | $this->signatures[$method] = $args; |
||
951 | $this->help[$method] = $help; |
||
952 | } |
||
953 | |||
954 | /** |
||
955 | * @param $methodname |
||
956 | * @param $args |
||
957 | * @return IXR_Error|mixed |
||
958 | */ |
||
959 | public function call($methodname, $args) |
||
960 | { |
||
961 | // Make sure it's in an array |
||
962 | if ($args && !is_array($args)) { |
||
963 | $args = [$args]; |
||
964 | } |
||
965 | // Over-rides default call method, adds signature check |
||
966 | if (!$this->hasMethod($methodname)) { |
||
967 | return new IXR_Error(-32601, 'server error. requested method "' . $this->message->methodName . '" not specified.'); |
||
968 | } |
||
969 | $method = $this->callbacks[$methodname]; |
||
0 ignored issues
–
show
$method is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
970 | $signature = $this->signatures[$methodname]; |
||
971 | $returnType = array_shift($signature); |
||
0 ignored issues
–
show
$returnType is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
972 | // Check the number of arguments |
||
973 | if (count($args) != count($signature)) { |
||
974 | // print 'Num of args: '.count($args).' Num in signature: '.count($signature); |
||
975 | return new IXR_Error(-32602, 'server error. wrong number of method parameters'); |
||
976 | } |
||
977 | // Check the argument types |
||
978 | $ok = true; |
||
979 | $argsbackup = $args; |
||
980 | for ($i = 0, $j = count($args); $i < $j; ++$i) { |
||
981 | $arg = array_shift($args); |
||
982 | $type = array_shift($signature); |
||
983 | switch ($type) { |
||
984 | case 'int': |
||
985 | case 'i4': |
||
986 | if (is_array($arg) || !is_int($arg)) { |
||
987 | $ok = false; |
||
988 | } |
||
989 | break; |
||
990 | case 'base64': |
||
991 | case 'string': |
||
992 | if (!is_string($arg)) { |
||
993 | $ok = false; |
||
994 | } |
||
995 | break; |
||
996 | case 'boolean': |
||
997 | if (false !== $arg && true !== $arg) { |
||
998 | $ok = false; |
||
999 | } |
||
1000 | break; |
||
1001 | case 'float': |
||
1002 | case 'double': |
||
1003 | if (!is_float($arg)) { |
||
1004 | $ok = false; |
||
1005 | } |
||
1006 | break; |
||
1007 | case 'date': |
||
1008 | case 'dateTime.iso8601': |
||
1009 | if (!is_a($arg, 'IXR_Date')) { |
||
1010 | $ok = false; |
||
1011 | } |
||
1012 | break; |
||
1013 | } |
||
1014 | if (!$ok) { |
||
1015 | return new IXR_Error(-32602, 'server error. invalid method parameters'); |
||
1016 | } |
||
1017 | } |
||
1018 | |||
1019 | // It passed the test - run the "real" method call |
||
1020 | return parent::call($methodname, $argsbackup); |
||
1021 | } |
||
1022 | |||
1023 | /** |
||
1024 | * @param $method |
||
1025 | * @return array|IXR_Error |
||
1026 | */ |
||
1027 | public function methodSignature($method) |
||
1028 | { |
||
1029 | if (!$this->hasMethod($method)) { |
||
1030 | return new IXR_Error(-32601, 'server error. requested method "' . $method . '" not specified.'); |
||
1031 | } |
||
1032 | // We should be returning an array of types |
||
1033 | $types = $this->signatures[$method]; |
||
1034 | $return = []; |
||
1035 | foreach ($types as $type) { |
||
1036 | switch ($type) { |
||
1037 | case 'string': |
||
1038 | $return[] = 'string'; |
||
1039 | break; |
||
1040 | case 'int': |
||
1041 | case 'i4': |
||
1042 | $return[] = 42; |
||
1043 | break; |
||
1044 | case 'double': |
||
1045 | $return[] = 3.1415; |
||
1046 | break; |
||
1047 | case 'dateTime.iso8601': |
||
1048 | $return[] = new IXR_Date(time()); |
||
1049 | break; |
||
1050 | case 'boolean': |
||
1051 | $return[] = true; |
||
1052 | break; |
||
1053 | case 'base64': |
||
1054 | $return[] = new IXR_Base64('base64'); |
||
1055 | break; |
||
1056 | case 'array': |
||
1057 | $return[] = ['array']; |
||
1058 | break; |
||
1059 | case 'struct': |
||
1060 | $return[] = ['struct' => 'struct']; |
||
1061 | break; |
||
1062 | } |
||
1063 | } |
||
1064 | |||
1065 | return $return; |
||
1066 | } |
||
1067 | |||
1068 | /** |
||
1069 | * @param $method |
||
1070 | * @return mixed |
||
1071 | */ |
||
1072 | public function methodHelp($method) |
||
1073 | { |
||
1074 | return $this->help[$method]; |
||
1075 | } |
||
1076 | } |
||
1077 | |||
1078 | /** |
||
1079 | * Class IXR_ClientMulticall |
||
1080 | */ |
||
1081 | class IXR_ClientMulticall extends IXR_Client |
||
1082 | { |
||
1083 | public $calls = []; |
||
1084 | |||
1085 | /** |
||
1086 | * IXR_ClientMulticall constructor. |
||
1087 | * @param $server |
||
1088 | * @param bool $path |
||
1089 | * @param int $port |
||
1090 | */ |
||
1091 | public function __construct($server, $path = false, $port = 80) |
||
1092 | { |
||
1093 | parent::IXR_Client($server, $path, $port); |
||
0 ignored issues
–
show
The method
IXR_Client() does not seem to exist on object<IXR_Client> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() It seems like you call parent on a different method (
IXR_Client() instead of __construct() ). Are you sure this is correct? If so, you might want to change this to $this->IXR_Client() .
This check looks for a call to a parent method whose name is different than the method from which it is called. Consider the following code: class Daddy
{
protected function getFirstName()
{
return "Eidur";
}
protected function getSurName()
{
return "Gudjohnsen";
}
}
class Son
{
public function getFirstName()
{
return parent::getSurname();
}
}
The ![]() |
|||
1094 | $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; |
||
1095 | } |
||
1096 | |||
1097 | public function addCall() |
||
1098 | { |
||
1099 | $args = func_get_args(); |
||
1100 | $methodName = array_shift($args); |
||
1101 | $struct = [ |
||
1102 | 'methodName' => $methodName, |
||
1103 | 'params' => $args |
||
1104 | ]; |
||
1105 | $this->calls[] = $struct; |
||
1106 | } |
||
1107 | |||
1108 | /** |
||
1109 | * @return bool |
||
1110 | */ |
||
1111 | public function query() |
||
1112 | { |
||
1113 | // Prepare multicall, then call the parent::query() method |
||
1114 | return parent::query('system.multicall', $this->calls); |
||
1115 | } |
||
1116 | } |
||
1117 |
The break statement is not necessary if it is preceded for example by a return statement:
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.