fix: the client can now successfully call methods using ISO-8859-1 or UTF-8 character...
[plcapi.git] / demo / server / server.php
1 <?php
2 /**
3  * Demo server for xmlrpc library.
4  *
5  * Implements a lot of webservices, including a suite of services used for
6  * interoperability testing (validator1 methods), and some whose only purpose
7  * is to be used for unit-testing the library.
8  *
9  * Please do not copy this file verbatim into your production server.
10  **/
11
12 // give user a chance to see the source for this server instead of running the services
13 if ($_SERVER['REQUEST_METHOD'] != 'POST' && isset($_GET['showSource'])) {
14     highlight_file(__FILE__);
15     die();
16 }
17
18 include_once __DIR__ . "/../../vendor/autoload.php";
19
20 // out-of-band information: let the client manipulate the server operations.
21 // we do this to help the testsuite script: do not reproduce in production!
22 if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
23     $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = '/tmp/phpxmlrpc_coverage';
24     if (!is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
25         mkdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']);
26     }
27
28     include_once __DIR__ . "/../../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/prepend.php";
29 }
30
31 use PhpXmlRpc\Value;
32
33 /**
34  * Used to test usage of object methods in dispatch maps and in wrapper code.
35  */
36 class xmlrpcServerMethodsContainer
37 {
38     /**
39      * Method used to test logging of php warnings generated by user functions.
40      */
41     public function phpWarningGenerator($m)
42     {
43         $a = $undefinedVariable; // this triggers a warning in E_ALL mode, since $undefinedVariable is undefined
44         return new PhpXmlRpc\Response(new Value(1, 'boolean'));
45     }
46
47     /**
48      * Method used to test catching of exceptions in the server.
49      */
50     public function exceptionGenerator($m)
51     {
52         throw new Exception("it's just a test", 1);
53     }
54
55     /**
56     * A PHP version of the state-number server. Send me an integer and i'll sell you a state
57     * @param integer $s
58     * @return string
59     */
60     public static function findState($s)
61     {
62         return inner_findstate($s);
63     }
64 }
65
66 // a PHP version of the state-number server
67 // send me an integer and i'll sell you a state
68
69 $stateNames = array(
70     "Alabama", "Alaska", "Arizona", "Arkansas", "California",
71     "Colorado", "Columbia", "Connecticut", "Delaware", "Florida",
72     "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",
73     "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan",
74     "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
75     "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
76     "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
77     "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
78     "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming",
79 );
80
81 $findstate_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcInt));
82 $findstate_doc = 'When passed an integer between 1 and 51 returns the
83 name of a US state, where the integer is the index of that state name
84 in an alphabetic order.';
85
86 function findState($m)
87 {
88     global $stateNames;
89
90     $err = "";
91     // get the first param
92     $sno = $m->getParam(0);
93
94     // param must be there and of the correct type: server object does the validation for us
95
96     // extract the value of the state number
97     $snv = $sno->scalarval();
98     // look it up in our array (zero-based)
99     if (isset($stateNames[$snv - 1])) {
100         $stateName = $stateNames[$snv - 1];
101     } else {
102         // not there, so complain
103         $err = "I don't have a state for the index '" . $snv . "'";
104     }
105
106     // if we generated an error, create an error return response
107     if ($err) {
108         return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
109     } else {
110         // otherwise, we create the right response with the state name
111         return new PhpXmlRpc\Response(new Value($stateName));
112     }
113 }
114
115 /**
116  * Inner code of the state-number server.
117  * Used to test auto-registration of PHP functions as xmlrpc methods.
118  *
119  * @param integer $stateNo the state number
120  *
121  * @return string the name of the state (or error description)
122  */
123 function inner_findstate($stateNo)
124 {
125     global $stateNames;
126
127     if (isset($stateNames[$stateNo - 1])) {
128         return $stateNames[$stateNo - 1];
129     } else {
130         // not, there so complain
131         return "I don't have a state for the index '" . $stateNo . "'";
132     }
133 }
134
135 $wrapper = new PhpXmlRpc\Wrapper();
136
137 $findstate2_sig = $wrapper->wrap_php_function('inner_findstate');
138
139 $findstate3_sig = $wrapper->wrap_php_function(array('xmlrpcServerMethodsContainer', 'findState'));
140
141 $findstate5_sig = $wrapper->wrap_php_function('xmlrpcServerMethodsContainer::findState');
142
143 $obj = new xmlrpcServerMethodsContainer();
144 $findstate4_sig = $wrapper->wrap_php_function(array($obj, 'findstate'));
145
146 $addtwo_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt, Value::$xmlrpcInt));
147 $addtwo_doc = 'Add two integers together and return the result';
148 function addTwo($m)
149 {
150     $s = $m->getParam(0);
151     $t = $m->getParam(1);
152
153     return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), "int"));
154 }
155
156 $addtwodouble_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble, Value::$xmlrpcDouble));
157 $addtwodouble_doc = 'Add two doubles together and return the result';
158 function addTwoDouble($m)
159 {
160     $s = $m->getParam(0);
161     $t = $m->getParam(1);
162
163     return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), "double"));
164 }
165
166 $stringecho_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
167 $stringecho_doc = 'Accepts a string parameter, returns the string.';
168 function stringEcho($m)
169 {
170     // just sends back a string
171     return new PhpXmlRpc\Response(new Value($m->getParam(0)->scalarval()));
172 }
173
174 $echoback_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
175 $echoback_doc = 'Accepts a string parameter, returns the entire incoming payload';
176 function echoBack($m)
177 {
178     // just sends back a string with what i got sent to me, just escaped, that's all
179     $s = "I got the following message:\n" . $m->serialize();
180
181     return new PhpXmlRpc\Response(new Value($s));
182 }
183
184 $echosixtyfour_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcBase64));
185 $echosixtyfour_doc = 'Accepts a base64 parameter and returns it decoded as a string';
186 function echoSixtyFour($m)
187 {
188     // Accepts an encoded value, but sends it back as a normal string.
189     // This is to test that base64 encoding is working as expected
190     $incoming = $m->getParam(0);
191
192     return new PhpXmlRpc\Response(new Value($incoming->scalarval(), "string"));
193 }
194
195 $bitflipper_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
196 $bitflipper_doc = 'Accepts an array of booleans, and returns them inverted';
197 function bitFlipper($m)
198 {
199     $v = $m->getParam(0);
200     $sz = $v->arraysize();
201     $rv = new Value(array(), Value::$xmlrpcArray);
202
203     for ($j = 0; $j < $sz; $j++) {
204         $b = $v->arraymem($j);
205         if ($b->scalarval()) {
206             $rv->addScalar(false, "boolean");
207         } else {
208             $rv->addScalar(true, "boolean");
209         }
210     }
211
212     return new PhpXmlRpc\Response($rv);
213 }
214
215 // Sorting demo
216 //
217 // send me an array of structs thus:
218 //
219 // Dave 35
220 // Edd  45
221 // Fred 23
222 // Barney 37
223 //
224 // and I'll return it to you in sorted order
225
226 function agesorter_compare($a, $b)
227 {
228     global $agesorter_arr;
229
230     // don't even ask me _why_ these come padded with hyphens, I couldn't tell you :p
231     $a = str_replace("-", "", $a);
232     $b = str_replace("-", "", $b);
233
234     if ($agesorter_arr[$a] == $agesorter_arr[$b]) {
235         return 0;
236     }
237
238     return ($agesorter_arr[$a] > $agesorter_arr[$b]) ? -1 : 1;
239 }
240
241 $agesorter_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
242 $agesorter_doc = 'Send this method an array of [string, int] structs, eg:
243 <pre>
244  Dave   35
245  Edd    45
246  Fred   23
247  Barney 37
248 </pre>
249 And the array will be returned with the entries sorted by their numbers.
250 ';
251 function ageSorter($m)
252 {
253     global $agesorter_arr, $s;
254
255     PhpXmlRpc\Server::xmlrpc_debugmsg("Entering 'agesorter'");
256     // get the parameter
257     $sno = $m->getParam(0);
258     // error string for [if|when] things go wrong
259     $err = "";
260     // create the output value
261     $v = new Value();
262     $agar = array();
263
264     $max = $sno->arraysize();
265     PhpXmlRpc\Server::xmlrpc_debugmsg("Found $max array elements");
266     for ($i = 0; $i < $max; $i++) {
267         $rec = $sno->arraymem($i);
268         if ($rec->kindOf() != "struct") {
269             $err = "Found non-struct in array at element $i";
270             break;
271         }
272         // extract name and age from struct
273         $n = $rec->structmem("name");
274         $a = $rec->structmem("age");
275         // $n and $a are xmlrpcvals,
276         // so get the scalarval from them
277         $agar[$n->scalarval()] = $a->scalarval();
278     }
279
280     $agesorter_arr = $agar;
281     // hack, must make global as uksort() won't
282     // allow us to pass any other auxiliary information
283     uksort($agesorter_arr, 'agesorter_compare');
284     $outAr = array();
285     while (list($key, $val) = each($agesorter_arr)) {
286         // recreate each struct element
287         $outAr[] = new Value(array("name" => new Value($key),
288             "age" => new Value($val, "int"),), "struct");
289     }
290     // add this array to the output value
291     $v->addArray($outAr);
292
293     if ($err) {
294         return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
295     } else {
296         return new PhpXmlRpc\Response($v);
297     }
298 }
299
300 // signature and instructions, place these in the dispatch
301 // map
302 $mailsend_sig = array(array(
303     Value::$xmlrpcBoolean, Value::$xmlrpcString, Value::$xmlrpcString,
304     Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString,
305     Value::$xmlrpcString, Value::$xmlrpcString,
306 ));
307 $mailsend_doc = 'mail.send(recipient, subject, text, sender, cc, bcc, mimetype)<br/>
308 recipient, cc, and bcc are strings, comma-separated lists of email addresses, as described above.<br/>
309 subject is a string, the subject of the message.<br/>
310 sender is a string, it\'s the email address of the person sending the message. This string can not be
311 a comma-separated list, it must contain a single email address only.<br/>
312 text is a string, it contains the body of the message.<br/>
313 mimetype, a string, is a standard MIME type, for example, text/plain.
314 ';
315 // WARNING; this functionality depends on the sendmail -t option
316 // it may not work with Windows machines properly; particularly
317 // the Bcc option. Sneak on your friends at your own risk!
318 function mailSend($m)
319 {
320     $err = "";
321
322     $mTo = $m->getParam(0);
323     $mSub = $m->getParam(1);
324     $mBody = $m->getParam(2);
325     $mFrom = $m->getParam(3);
326     $mCc = $m->getParam(4);
327     $mBcc = $m->getParam(5);
328     $mMime = $m->getParam(6);
329
330     if ($mTo->scalarval() == "") {
331         $err = "Error, no 'To' field specified";
332     }
333
334     if ($mFrom->scalarval() == "") {
335         $err = "Error, no 'From' field specified";
336     }
337
338     $msghdr = "From: " . $mFrom->scalarval() . "\n";
339     $msghdr .= "To: " . $mTo->scalarval() . "\n";
340
341     if ($mCc->scalarval() != "") {
342         $msghdr .= "Cc: " . $mCc->scalarval() . "\n";
343     }
344     if ($mBcc->scalarval() != "") {
345         $msghdr .= "Bcc: " . $mBcc->scalarval() . "\n";
346     }
347     if ($mMime->scalarval() != "") {
348         $msghdr .= "Content-type: " . $mMime->scalarval() . "\n";
349     }
350     $msghdr .= "X-Mailer: XML-RPC for PHP mailer 1.0";
351
352     if ($err == "") {
353         if (!mail("",
354             $mSub->scalarval(),
355             $mBody->scalarval(),
356             $msghdr)
357         ) {
358             $err = "Error, could not send the mail.";
359         }
360     }
361
362     if ($err) {
363         return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
364     } else {
365         return new PhpXmlRpc\Response(new Value("true", Value::$xmlrpcBoolean));
366     }
367 }
368
369 $getallheaders_sig = array(array(Value::$xmlrpcStruct));
370 $getallheaders_doc = 'Returns a struct containing all the HTTP headers received with the request. Provides limited functionality with IIS';
371 function getallheaders_xmlrpc($m)
372 {
373     $encoder = new PhpXmlRpc\Encoder();
374
375     if (function_exists('getallheaders')) {
376         return new PhpXmlRpc\Response($encoder->encode(getallheaders()));
377     } else {
378         $headers = array();
379         // IIS: poor man's version of getallheaders
380         foreach ($_SERVER as $key => $val) {
381             if (strpos($key, 'HTTP_') === 0) {
382                 $key = ucfirst(str_replace('_', '-', strtolower(substr($key, 5))));
383                 $headers[$key] = $val;
384             }
385         }
386
387         return new PhpXmlRpc\Response($encoder->encode($headers));
388     }
389 }
390
391 $setcookies_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
392 $setcookies_doc = 'Sends to client a response containing a single \'1\' digit, and sets to it http cookies as received in the request (array of structs describing a cookie)';
393 function setCookies($m)
394 {
395     $encoder = new PhpXmlRpc\Encoder();
396     $m = $m->getParam(0);
397     while (list($name, $value) = $m->structeach()) {
398         $cookieDesc = $encoder->decode($value);
399         setcookie($name, @$cookieDesc['value'], @$cookieDesc['expires'], @$cookieDesc['path'], @$cookieDesc['domain'], @$cookieDesc['secure']);
400     }
401
402     return new PhpXmlRpc\Response(new Value(1, 'int'));
403 }
404
405 $getcookies_sig = array(array(Value::$xmlrpcStruct));
406 $getcookies_doc = 'Sends to client a response containing all http cookies as received in the request (as struct)';
407 function getCookies($m)
408 {
409     $encoder = new PhpXmlRpc\Encoder();
410     return new PhpXmlRpc\Response($encoder->encode($_COOKIE));
411 }
412
413 $v1_arrayOfStructs_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcArray));
414 $v1_arrayOfStructs_doc = 'This handler takes a single parameter, an array of structs, each of which contains at least three elements named moe, larry and curly, all <i4>s. Your handler must add all the struct elements named curly and return the result.';
415 function v1_arrayOfStructs($m)
416 {
417     $sno = $m->getParam(0);
418     $numCurly = 0;
419     for ($i = 0; $i < $sno->arraysize(); $i++) {
420         $str = $sno->arraymem($i);
421         $str->structreset();
422         while (list($key, $val) = $str->structeach()) {
423             if ($key == "curly") {
424                 $numCurly += $val->scalarval();
425             }
426         }
427     }
428
429     return new PhpXmlRpc\Response(new Value($numCurly, "int"));
430 }
431
432 $v1_easyStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
433 $v1_easyStruct_doc = 'This handler takes a single parameter, a struct, containing at least three elements named moe, larry and curly, all &lt;i4&gt;s. Your handler must add the three numbers and return the result.';
434 function v1_easyStruct($m)
435 {
436     $sno = $m->getParam(0);
437     $moe = $sno->structmem("moe");
438     $larry = $sno->structmem("larry");
439     $curly = $sno->structmem("curly");
440     $num = $moe->scalarval() + $larry->scalarval() + $curly->scalarval();
441
442     return new PhpXmlRpc\Response(new Value($num, "int"));
443 }
444
445 $v1_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
446 $v1_echoStruct_doc = 'This handler takes a single parameter, a struct. Your handler must return the struct.';
447 function v1_echoStruct($m)
448 {
449     $sno = $m->getParam(0);
450
451     return new PhpXmlRpc\Response($sno);
452 }
453
454 $v1_manyTypes_sig = array(array(
455     Value::$xmlrpcArray, Value::$xmlrpcInt, Value::$xmlrpcBoolean,
456     Value::$xmlrpcString, Value::$xmlrpcDouble, Value::$xmlrpcDateTime,
457     Value::$xmlrpcBase64,
458 ));
459 $v1_manyTypes_doc = 'This handler takes six parameters, and returns an array containing all the parameters.';
460 function v1_manyTypes($m)
461 {
462     return new PhpXmlRpc\Response(new Value(array(
463         $m->getParam(0),
464         $m->getParam(1),
465         $m->getParam(2),
466         $m->getParam(3),
467         $m->getParam(4),
468         $m->getParam(5),),
469         "array"
470     ));
471 }
472
473 $v1_moderateSizeArrayCheck_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcArray));
474 $v1_moderateSizeArrayCheck_doc = 'This handler takes a single parameter, which is an array containing between 100 and 200 elements. Each of the items is a string, your handler must return a string containing the concatenated text of the first and last elements.';
475 function v1_moderateSizeArrayCheck($m)
476 {
477     $ar = $m->getParam(0);
478     $sz = $ar->arraysize();
479     $first = $ar->arraymem(0);
480     $last = $ar->arraymem($sz - 1);
481
482     return new PhpXmlRpc\Response(new Value($first->scalarval() .
483         $last->scalarval(), "string"));
484 }
485
486 $v1_simpleStructReturn_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcInt));
487 $v1_simpleStructReturn_doc = 'This handler takes one parameter, and returns a struct containing three elements, times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000.';
488 function v1_simpleStructReturn($m)
489 {
490     $sno = $m->getParam(0);
491     $v = $sno->scalarval();
492
493     return new PhpXmlRpc\Response(new Value(array(
494         "times10" => new Value($v * 10, "int"),
495         "times100" => new Value($v * 100, "int"),
496         "times1000" => new Value($v * 1000, "int"),),
497         "struct"
498     ));
499 }
500
501 $v1_nestedStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
502 $v1_nestedStruct_doc = 'This handler takes a single parameter, a struct, that models a daily calendar. At the top level, there is one struct for each year. Each year is broken down into months, and months into days. Most of the days are empty in the struct you receive, but the entry for April 1, 2000 contains a least three elements named moe, larry and curly, all &lt;i4&gt;s. Your handler must add the three numbers and return the result.';
503 function v1_nestedStruct($m)
504 {
505     $sno = $m->getParam(0);
506
507     $twoK = $sno->structmem("2000");
508     $april = $twoK->structmem("04");
509     $fools = $april->structmem("01");
510     $curly = $fools->structmem("curly");
511     $larry = $fools->structmem("larry");
512     $moe = $fools->structmem("moe");
513
514     return new PhpXmlRpc\Response(new Value($curly->scalarval() + $larry->scalarval() + $moe->scalarval(), "int"));
515 }
516
517 $v1_countTheEntities_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcString));
518 $v1_countTheEntities_doc = 'This handler takes a single parameter, a string, that contains any number of predefined entities, namely &lt;, &gt;, &amp; \' and ".<BR>Your handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes.';
519 function v1_countTheEntities($m)
520 {
521     $sno = $m->getParam(0);
522     $str = $sno->scalarval();
523     $gt = 0;
524     $lt = 0;
525     $ap = 0;
526     $qu = 0;
527     $amp = 0;
528     for ($i = 0; $i < strlen($str); $i++) {
529         $c = substr($str, $i, 1);
530         switch ($c) {
531             case ">":
532                 $gt++;
533                 break;
534             case "<":
535                 $lt++;
536                 break;
537             case "\"":
538                 $qu++;
539                 break;
540             case "'":
541                 $ap++;
542                 break;
543             case "&":
544                 $amp++;
545                 break;
546             default:
547                 break;
548         }
549     }
550
551     return new PhpXmlRpc\Response(new Value(array(
552         "ctLeftAngleBrackets" => new Value($lt, "int"),
553         "ctRightAngleBrackets" => new Value($gt, "int"),
554         "ctAmpersands" => new Value($amp, "int"),
555         "ctApostrophes" => new Value($ap, "int"),
556         "ctQuotes" => new Value($qu, "int"),),
557         "struct"
558     ));
559 }
560
561 // trivial interop tests
562 // http://www.xmlrpc.com/stories/storyReader$1636
563
564 $i_echoString_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
565 $i_echoString_doc = "Echoes string.";
566
567 $i_echoStringArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
568 $i_echoStringArray_doc = "Echoes string array.";
569
570 $i_echoInteger_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt));
571 $i_echoInteger_doc = "Echoes integer.";
572
573 $i_echoIntegerArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
574 $i_echoIntegerArray_doc = "Echoes integer array.";
575
576 $i_echoFloat_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble));
577 $i_echoFloat_doc = "Echoes float.";
578
579 $i_echoFloatArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
580 $i_echoFloatArray_doc = "Echoes float array.";
581
582 $i_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
583 $i_echoStruct_doc = "Echoes struct.";
584
585 $i_echoStructArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
586 $i_echoStructArray_doc = "Echoes struct array.";
587
588 $i_echoValue_doc = "Echoes any value back.";
589 $i_echoValue_sig = array(array(Value::$xmlrpcValue, Value::$xmlrpcValue));
590
591 $i_echoBase64_sig = array(array(Value::$xmlrpcBase64, Value::$xmlrpcBase64));
592 $i_echoBase64_doc = "Echoes base64.";
593
594 $i_echoDate_sig = array(array(Value::$xmlrpcDateTime, Value::$xmlrpcDateTime));
595 $i_echoDate_doc = "Echoes dateTime.";
596
597 function i_echoParam($m)
598 {
599     $s = $m->getParam(0);
600
601     return new PhpXmlRpc\Response($s);
602 }
603
604 function i_echoString($m)
605 {
606     return i_echoParam($m);
607 }
608
609 function i_echoInteger($m)
610 {
611     return i_echoParam($m);
612 }
613
614 function i_echoFloat($m)
615 {
616     return i_echoParam($m);
617 }
618
619 function i_echoStruct($m)
620 {
621     return i_echoParam($m);
622 }
623
624 function i_echoStringArray($m)
625 {
626     return i_echoParam($m);
627 }
628
629 function i_echoIntegerArray($m)
630 {
631     return i_echoParam($m);
632 }
633
634 function i_echoFloatArray($m)
635 {
636     return i_echoParam($m);
637 }
638
639 function i_echoStructArray($m)
640 {
641     return i_echoParam($m);
642 }
643
644 function i_echoValue($m)
645 {
646     return i_echoParam($m);
647 }
648
649 function i_echoBase64($m)
650 {
651     return i_echoParam($m);
652 }
653
654 function i_echoDate($m)
655 {
656     return i_echoParam($m);
657 }
658
659 $i_whichToolkit_sig = array(array(Value::$xmlrpcStruct));
660 $i_whichToolkit_doc = "Returns a struct containing the following strings: toolkitDocsUrl, toolkitName, toolkitVersion, toolkitOperatingSystem.";
661
662 function i_whichToolkit($m)
663 {
664     global $SERVER_SOFTWARE;
665     $ret = array(
666         "toolkitDocsUrl" => "http://phpxmlrpc.sourceforge.net/",
667         "toolkitName" => PhpXmlRpc\PhpXmlRpc::$xmlrpcName,
668         "toolkitVersion" => PhpXmlRpc\PhpXmlRpc::$xmlrpcVersion,
669         "toolkitOperatingSystem" => isset($SERVER_SOFTWARE) ? $SERVER_SOFTWARE : $_SERVER['SERVER_SOFTWARE'],
670     );
671
672     $encoder = new PhpXmlRpc\Encoder();
673     return new PhpXmlRpc\Response($encoder->encode($ret));
674 }
675
676 $object = new xmlrpcServerMethodsContainer();
677 $signatures = array(
678     "examples.getStateName" => array(
679         "function" => "findState",
680         "signature" => $findstate_sig,
681         "docstring" => $findstate_doc,
682     ),
683     "examples.sortByAge" => array(
684         "function" => "ageSorter",
685         "signature" => $agesorter_sig,
686         "docstring" => $agesorter_doc,
687     ),
688     "examples.addtwo" => array(
689         "function" => "addTwo",
690         "signature" => $addtwo_sig,
691         "docstring" => $addtwo_doc,
692     ),
693     "examples.addtwodouble" => array(
694         "function" => "addTwoDouble",
695         "signature" => $addtwodouble_sig,
696         "docstring" => $addtwodouble_doc,
697     ),
698     "examples.stringecho" => array(
699         "function" => "stringEcho",
700         "signature" => $stringecho_sig,
701         "docstring" => $stringecho_doc,
702     ),
703     "examples.echo" => array(
704         "function" => "echoBack",
705         "signature" => $echoback_sig,
706         "docstring" => $echoback_doc,
707     ),
708     "examples.decode64" => array(
709         "function" => "echoSixtyFour",
710         "signature" => $echosixtyfour_sig,
711         "docstring" => $echosixtyfour_doc,
712     ),
713     "examples.invertBooleans" => array(
714         "function" => "bitFlipper",
715         "signature" => $bitflipper_sig,
716         "docstring" => $bitflipper_doc,
717     ),
718     // signature omitted on purpose
719     "tests.generatePHPWarning" => array(
720         "function" => array($object, "phpWarningGenerator"),
721     ),
722     // signature omitted on purpose
723     "tests.raiseException" => array(
724         "function" => array($object, "exceptionGenerator"),
725     ),
726     /*
727     // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
728     // We can only register this when setting internal encoding to UTF-8, or it will break system.listMethods
729     "tests.utf8methodname." . 'κόσμε' => array(
730         "function" => "stringEcho",
731         "signature" => $stringecho_sig,
732         "docstring" => $stringecho_doc,
733     ),*/
734     "tests.iso88591methodname." . chr(224) . chr(252) . chr(232) => array(
735         "function" => "stringEcho",
736         "signature" => $stringecho_sig,
737         "docstring" => $stringecho_doc,
738     ),
739     "examples.getallheaders" => array(
740         "function" => 'getallheaders_xmlrpc',
741         "signature" => $getallheaders_sig,
742         "docstring" => $getallheaders_doc,
743     ),
744     "examples.setcookies" => array(
745         "function" => 'setCookies',
746         "signature" => $setcookies_sig,
747         "docstring" => $setcookies_doc,
748     ),
749     "examples.getcookies" => array(
750         "function" => 'getCookies',
751         "signature" => $getcookies_sig,
752         "docstring" => $getcookies_doc,
753     ),
754     "mail.send" => array(
755         "function" => "mailSend",
756         "signature" => $mailsend_sig,
757         "docstring" => $mailsend_doc,
758     ),
759     "validator1.arrayOfStructsTest" => array(
760         "function" => "v1_arrayOfStructs",
761         "signature" => $v1_arrayOfStructs_sig,
762         "docstring" => $v1_arrayOfStructs_doc,
763     ),
764     "validator1.easyStructTest" => array(
765         "function" => "v1_easyStruct",
766         "signature" => $v1_easyStruct_sig,
767         "docstring" => $v1_easyStruct_doc,
768     ),
769     "validator1.echoStructTest" => array(
770         "function" => "v1_echoStruct",
771         "signature" => $v1_echoStruct_sig,
772         "docstring" => $v1_echoStruct_doc,
773     ),
774     "validator1.manyTypesTest" => array(
775         "function" => "v1_manyTypes",
776         "signature" => $v1_manyTypes_sig,
777         "docstring" => $v1_manyTypes_doc,
778     ),
779     "validator1.moderateSizeArrayCheck" => array(
780         "function" => "v1_moderateSizeArrayCheck",
781         "signature" => $v1_moderateSizeArrayCheck_sig,
782         "docstring" => $v1_moderateSizeArrayCheck_doc,
783     ),
784     "validator1.simpleStructReturnTest" => array(
785         "function" => "v1_simpleStructReturn",
786         "signature" => $v1_simpleStructReturn_sig,
787         "docstring" => $v1_simpleStructReturn_doc,
788     ),
789     "validator1.nestedStructTest" => array(
790         "function" => "v1_nestedStruct",
791         "signature" => $v1_nestedStruct_sig,
792         "docstring" => $v1_nestedStruct_doc,
793     ),
794     "validator1.countTheEntities" => array(
795         "function" => "v1_countTheEntities",
796         "signature" => $v1_countTheEntities_sig,
797         "docstring" => $v1_countTheEntities_doc,
798     ),
799     "interopEchoTests.echoString" => array(
800         "function" => "i_echoString",
801         "signature" => $i_echoString_sig,
802         "docstring" => $i_echoString_doc,
803     ),
804     "interopEchoTests.echoStringArray" => array(
805         "function" => "i_echoStringArray",
806         "signature" => $i_echoStringArray_sig,
807         "docstring" => $i_echoStringArray_doc,
808     ),
809     "interopEchoTests.echoInteger" => array(
810         "function" => "i_echoInteger",
811         "signature" => $i_echoInteger_sig,
812         "docstring" => $i_echoInteger_doc,
813     ),
814     "interopEchoTests.echoIntegerArray" => array(
815         "function" => "i_echoIntegerArray",
816         "signature" => $i_echoIntegerArray_sig,
817         "docstring" => $i_echoIntegerArray_doc,
818     ),
819     "interopEchoTests.echoFloat" => array(
820         "function" => "i_echoFloat",
821         "signature" => $i_echoFloat_sig,
822         "docstring" => $i_echoFloat_doc,
823     ),
824     "interopEchoTests.echoFloatArray" => array(
825         "function" => "i_echoFloatArray",
826         "signature" => $i_echoFloatArray_sig,
827         "docstring" => $i_echoFloatArray_doc,
828     ),
829     "interopEchoTests.echoStruct" => array(
830         "function" => "i_echoStruct",
831         "signature" => $i_echoStruct_sig,
832         "docstring" => $i_echoStruct_doc,
833     ),
834     "interopEchoTests.echoStructArray" => array(
835         "function" => "i_echoStructArray",
836         "signature" => $i_echoStructArray_sig,
837         "docstring" => $i_echoStructArray_doc,
838     ),
839     "interopEchoTests.echoValue" => array(
840         "function" => "i_echoValue",
841         "signature" => $i_echoValue_sig,
842         "docstring" => $i_echoValue_doc,
843     ),
844     "interopEchoTests.echoBase64" => array(
845         "function" => "i_echoBase64",
846         "signature" => $i_echoBase64_sig,
847         "docstring" => $i_echoBase64_doc,
848     ),
849     "interopEchoTests.echoDate" => array(
850         "function" => "i_echoDate",
851         "signature" => $i_echoDate_sig,
852         "docstring" => $i_echoDate_doc,
853     ),
854     "interopEchoTests.whichToolkit" => array(
855         "function" => "i_whichToolkit",
856         "signature" => $i_whichToolkit_sig,
857         "docstring" => $i_whichToolkit_doc,
858     ),
859 );
860
861 if ($findstate2_sig) {
862     $signatures['examples.php.getStateName'] = $findstate2_sig;
863 }
864
865 if ($findstate3_sig) {
866     $signatures['examples.php2.getStateName'] = $findstate3_sig;
867 }
868
869 if ($findstate4_sig) {
870     $signatures['examples.php3.getStateName'] = $findstate4_sig;
871 }
872
873 if ($findstate5_sig) {
874     $signatures['examples.php4.getStateName'] = $findstate5_sig;
875 }
876
877 $s = new PhpXmlRpc\Server($signatures, false);
878 $s->setdebug(3);
879 $s->compress_response = true;
880
881 // out-of-band information: let the client manipulate the server operations.
882 // we do this to help the testsuite script: do not reproduce in production!
883 if (isset($_GET['RESPONSE_ENCODING'])) {
884     $s->response_charset_encoding = $_GET['RESPONSE_ENCODING'];
885 }
886 if (isset($_GET['EXCEPTION_HANDLING'])) {
887     $s->exception_handling = $_GET['EXCEPTION_HANDLING'];
888 }
889 $s->service();
890 // that should do all we need!
891
892 // out-of-band information: let the client manipulate the server operations.
893 // we do this to help the testsuite script: do not reproduce in production!
894 if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
895     include_once __DIR__ . "/../../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/append.php";
896 }