Improve generation of methods signature by the Wrapper class
[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($req)
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($req)
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 $num
58     * @return string
59     */
60     public static function findState($num)
61     {
62         return inner_findstate($num);
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($req)
87 {
88     global $stateNames;
89
90     $err = "";
91     // get the first param
92     $sno = $req->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 $findStateClosure = function ($req)
136 {
137     return findState($req);
138 };
139
140 $wrapper = new PhpXmlRpc\Wrapper();
141
142 $findstate2_sig = $wrapper->wrap_php_function('inner_findstate');
143
144 $findstate3_sig = $wrapper->wrap_php_function(array('xmlrpcServerMethodsContainer', 'findState'));
145
146 $obj = new xmlrpcServerMethodsContainer();
147 $findstate4_sig = $wrapper->wrap_php_function(array($obj, 'findstate'));
148
149 $findstate5_sig = $wrapper->wrap_php_function('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true));
150 eval($findstate5_sig['source']);
151
152 $findstate6_sig = $wrapper->wrap_php_function('inner_findstate', '', array('return_source' => true));
153 eval($findstate6_sig['source']);
154
155 $findstate7_sig = $wrapper->wrap_php_function(array('xmlrpcServerMethodsContainer', 'findState'), '', array('return_source' => true));
156 eval($findstate7_sig['source']);
157
158 $obj = new xmlrpcServerMethodsContainer();
159 $findstate8_sig = $wrapper->wrap_php_function(array($obj, 'findstate'), '', array('return_source' => true));
160 eval($findstate8_sig['source']);
161
162 $findstate9_sig = $wrapper->wrap_php_function('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true));
163 eval($findstate9_sig['source']);
164
165 $findstate10_sig = array(
166     "function" => $findStateClosure,
167     "signature" => $findstate_sig,
168     "docstring" => $findstate_doc,
169 );
170
171 $c = new xmlrpcServerMethodsContainer;
172 $moreSignatures = $wrapper->wrap_php_class($c, array('prefix' => 'tests.', 'method_type' => 'all'));
173 var_dump($moreSignatures);
174 die();
175
176 $addtwo_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt, Value::$xmlrpcInt));
177 $addtwo_doc = 'Add two integers together and return the result';
178 function addTwo($req)
179 {
180     $s = $req->getParam(0);
181     $t = $req->getParam(1);
182
183     return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), "int"));
184 }
185
186 $addtwodouble_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble, Value::$xmlrpcDouble));
187 $addtwodouble_doc = 'Add two doubles together and return the result';
188 function addTwoDouble($req)
189 {
190     $s = $req->getParam(0);
191     $t = $req->getParam(1);
192
193     return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), "double"));
194 }
195
196 $stringecho_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
197 $stringecho_doc = 'Accepts a string parameter, returns the string.';
198 function stringEcho($req)
199 {
200     // just sends back a string
201     return new PhpXmlRpc\Response(new Value($req->getParam(0)->scalarval()));
202 }
203
204 $echoback_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
205 $echoback_doc = 'Accepts a string parameter, returns the entire incoming payload';
206 function echoBack($req)
207 {
208     // just sends back a string with what i got sent to me, just escaped, that's all
209     $s = "I got the following message:\n" . $req->serialize();
210
211     return new PhpXmlRpc\Response(new Value($s));
212 }
213
214 $echosixtyfour_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcBase64));
215 $echosixtyfour_doc = 'Accepts a base64 parameter and returns it decoded as a string';
216 function echoSixtyFour($req)
217 {
218     // Accepts an encoded value, but sends it back as a normal string.
219     // This is to test that base64 encoding is working as expected
220     $incoming = $req->getParam(0);
221
222     return new PhpXmlRpc\Response(new Value($incoming->scalarval(), "string"));
223 }
224
225 $bitflipper_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
226 $bitflipper_doc = 'Accepts an array of booleans, and returns them inverted';
227 function bitFlipper($req)
228 {
229     $v = $req->getParam(0);
230     $sz = $v->arraysize();
231     $rv = new Value(array(), Value::$xmlrpcArray);
232
233     for ($j = 0; $j < $sz; $j++) {
234         $b = $v->arraymem($j);
235         if ($b->scalarval()) {
236             $rv->addScalar(false, "boolean");
237         } else {
238             $rv->addScalar(true, "boolean");
239         }
240     }
241
242     return new PhpXmlRpc\Response($rv);
243 }
244
245 // Sorting demo
246 //
247 // send me an array of structs thus:
248 //
249 // Dave 35
250 // Edd  45
251 // Fred 23
252 // Barney 37
253 //
254 // and I'll return it to you in sorted order
255
256 function agesorter_compare($a, $b)
257 {
258     global $agesorter_arr;
259
260     // don't even ask me _why_ these come padded with hyphens, I couldn't tell you :p
261     $a = str_replace("-", "", $a);
262     $b = str_replace("-", "", $b);
263
264     if ($agesorter_arr[$a] == $agesorter_arr[$b]) {
265         return 0;
266     }
267
268     return ($agesorter_arr[$a] > $agesorter_arr[$b]) ? -1 : 1;
269 }
270
271 $agesorter_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
272 $agesorter_doc = 'Send this method an array of [string, int] structs, eg:
273 <pre>
274  Dave   35
275  Edd    45
276  Fred   23
277  Barney 37
278 </pre>
279 And the array will be returned with the entries sorted by their numbers.
280 ';
281 function ageSorter($req)
282 {
283     global $agesorter_arr, $s;
284
285     PhpXmlRpc\Server::xmlrpc_debugmsg("Entering 'agesorter'");
286     // get the parameter
287     $sno = $req->getParam(0);
288     // error string for [if|when] things go wrong
289     $err = "";
290     // create the output value
291     $v = new Value();
292     $agar = array();
293
294     $max = $sno->arraysize();
295     PhpXmlRpc\Server::xmlrpc_debugmsg("Found $max array elements");
296     for ($i = 0; $i < $max; $i++) {
297         $rec = $sno->arraymem($i);
298         if ($rec->kindOf() != "struct") {
299             $err = "Found non-struct in array at element $i";
300             break;
301         }
302         // extract name and age from struct
303         $n = $rec->structmem("name");
304         $a = $rec->structmem("age");
305         // $n and $a are xmlrpcvals,
306         // so get the scalarval from them
307         $agar[$n->scalarval()] = $a->scalarval();
308     }
309
310     $agesorter_arr = $agar;
311     // hack, must make global as uksort() won't
312     // allow us to pass any other auxiliary information
313     uksort($agesorter_arr, 'agesorter_compare');
314     $outAr = array();
315     while (list($key, $val) = each($agesorter_arr)) {
316         // recreate each struct element
317         $outAr[] = new Value(array("name" => new Value($key),
318             "age" => new Value($val, "int"),), "struct");
319     }
320     // add this array to the output value
321     $v->addArray($outAr);
322
323     if ($err) {
324         return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
325     } else {
326         return new PhpXmlRpc\Response($v);
327     }
328 }
329
330 // signature and instructions, place these in the dispatch
331 // map
332 $mailsend_sig = array(array(
333     Value::$xmlrpcBoolean, Value::$xmlrpcString, Value::$xmlrpcString,
334     Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString,
335     Value::$xmlrpcString, Value::$xmlrpcString,
336 ));
337 $mailsend_doc = 'mail.send(recipient, subject, text, sender, cc, bcc, mimetype)<br/>
338 recipient, cc, and bcc are strings, comma-separated lists of email addresses, as described above.<br/>
339 subject is a string, the subject of the message.<br/>
340 sender is a string, it\'s the email address of the person sending the message. This string can not be
341 a comma-separated list, it must contain a single email address only.<br/>
342 text is a string, it contains the body of the message.<br/>
343 mimetype, a string, is a standard MIME type, for example, text/plain.
344 ';
345 // WARNING; this functionality depends on the sendmail -t option
346 // it may not work with Windows machines properly; particularly
347 // the Bcc option. Sneak on your friends at your own risk!
348 function mailSend($req)
349 {
350     $err = "";
351
352     $mTo = $req->getParam(0);
353     $mSub = $req->getParam(1);
354     $mBody = $req->getParam(2);
355     $mFrom = $req->getParam(3);
356     $mCc = $req->getParam(4);
357     $mBcc = $req->getParam(5);
358     $mMime = $req->getParam(6);
359
360     if ($mTo->scalarval() == "") {
361         $err = "Error, no 'To' field specified";
362     }
363
364     if ($mFrom->scalarval() == "") {
365         $err = "Error, no 'From' field specified";
366     }
367
368     $msgHdr = "From: " . $mFrom->scalarval() . "\n";
369     $msgHdr .= "To: " . $mTo->scalarval() . "\n";
370
371     if ($mCc->scalarval() != "") {
372         $msgHdr .= "Cc: " . $mCc->scalarval() . "\n";
373     }
374     if ($mBcc->scalarval() != "") {
375         $msgHdr .= "Bcc: " . $mBcc->scalarval() . "\n";
376     }
377     if ($mMime->scalarval() != "") {
378         $msgHdr .= "Content-type: " . $mMime->scalarval() . "\n";
379     }
380     $msgHdr .= "X-Mailer: XML-RPC for PHP mailer 1.0";
381
382     if ($err == "") {
383         if (!mail("",
384             $mSub->scalarval(),
385             $mBody->scalarval(),
386             $msgHdr)
387         ) {
388             $err = "Error, could not send the mail.";
389         }
390     }
391
392     if ($err) {
393         return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
394     } else {
395         return new PhpXmlRpc\Response(new Value("true", Value::$xmlrpcBoolean));
396     }
397 }
398
399 $getallheaders_sig = array(array(Value::$xmlrpcStruct));
400 $getallheaders_doc = 'Returns a struct containing all the HTTP headers received with the request. Provides limited functionality with IIS';
401 function getAllHeaders_xmlrpc($req)
402 {
403     $encoder = new PhpXmlRpc\Encoder();
404
405     if (function_exists('getallheaders')) {
406         return new PhpXmlRpc\Response($encoder->encode(getallheaders()));
407     } else {
408         $headers = array();
409         // IIS: poor man's version of getallheaders
410         foreach ($_SERVER as $key => $val) {
411             if (strpos($key, 'HTTP_') === 0) {
412                 $key = ucfirst(str_replace('_', '-', strtolower(substr($key, 5))));
413                 $headers[$key] = $val;
414             }
415         }
416
417         return new PhpXmlRpc\Response($encoder->encode($headers));
418     }
419 }
420
421 $setcookies_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
422 $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)';
423 function setCookies($req)
424 {
425     $encoder = new PhpXmlRpc\Encoder();
426     $m = $req->getParam(0);
427     while (list($name, $value) = $m->structeach()) {
428         $cookieDesc = $encoder->decode($value);
429         setcookie($name, @$cookieDesc['value'], @$cookieDesc['expires'], @$cookieDesc['path'], @$cookieDesc['domain'], @$cookieDesc['secure']);
430     }
431
432     return new PhpXmlRpc\Response(new Value(1, 'int'));
433 }
434
435 $getcookies_sig = array(array(Value::$xmlrpcStruct));
436 $getcookies_doc = 'Sends to client a response containing all http cookies as received in the request (as struct)';
437 function getCookies($req)
438 {
439     $encoder = new PhpXmlRpc\Encoder();
440     return new PhpXmlRpc\Response($encoder->encode($_COOKIE));
441 }
442
443 $v1_arrayOfStructs_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcArray));
444 $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.';
445 function v1_arrayOfStructs($req)
446 {
447     $sno = $req->getParam(0);
448     $numCurly = 0;
449     for ($i = 0; $i < $sno->arraysize(); $i++) {
450         $str = $sno->arraymem($i);
451         $str->structreset();
452         while (list($key, $val) = $str->structeach()) {
453             if ($key == "curly") {
454                 $numCurly += $val->scalarval();
455             }
456         }
457     }
458
459     return new PhpXmlRpc\Response(new Value($numCurly, "int"));
460 }
461
462 $v1_easyStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
463 $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.';
464 function v1_easyStruct($req)
465 {
466     $sno = $req->getParam(0);
467     $moe = $sno->structmem("moe");
468     $larry = $sno->structmem("larry");
469     $curly = $sno->structmem("curly");
470     $num = $moe->scalarval() + $larry->scalarval() + $curly->scalarval();
471
472     return new PhpXmlRpc\Response(new Value($num, "int"));
473 }
474
475 $v1_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
476 $v1_echoStruct_doc = 'This handler takes a single parameter, a struct. Your handler must return the struct.';
477 function v1_echoStruct($req)
478 {
479     $sno = $req->getParam(0);
480
481     return new PhpXmlRpc\Response($sno);
482 }
483
484 $v1_manyTypes_sig = array(array(
485     Value::$xmlrpcArray, Value::$xmlrpcInt, Value::$xmlrpcBoolean,
486     Value::$xmlrpcString, Value::$xmlrpcDouble, Value::$xmlrpcDateTime,
487     Value::$xmlrpcBase64,
488 ));
489 $v1_manyTypes_doc = 'This handler takes six parameters, and returns an array containing all the parameters.';
490 function v1_manyTypes($req)
491 {
492     return new PhpXmlRpc\Response(new Value(array(
493         $req->getParam(0),
494         $req->getParam(1),
495         $req->getParam(2),
496         $req->getParam(3),
497         $req->getParam(4),
498         $req->getParam(5),),
499         "array"
500     ));
501 }
502
503 $v1_moderateSizeArrayCheck_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcArray));
504 $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.';
505 function v1_moderateSizeArrayCheck($req)
506 {
507     $ar = $req->getParam(0);
508     $sz = $ar->arraysize();
509     $first = $ar->arraymem(0);
510     $last = $ar->arraymem($sz - 1);
511
512     return new PhpXmlRpc\Response(new Value($first->scalarval() .
513         $last->scalarval(), "string"));
514 }
515
516 $v1_simpleStructReturn_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcInt));
517 $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.';
518 function v1_simpleStructReturn($req)
519 {
520     $sno = $req->getParam(0);
521     $v = $sno->scalarval();
522
523     return new PhpXmlRpc\Response(new Value(array(
524         "times10" => new Value($v * 10, "int"),
525         "times100" => new Value($v * 100, "int"),
526         "times1000" => new Value($v * 1000, "int"),),
527         "struct"
528     ));
529 }
530
531 $v1_nestedStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
532 $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.';
533 function v1_nestedStruct($req)
534 {
535     $sno = $req->getParam(0);
536
537     $twoK = $sno->structmem("2000");
538     $april = $twoK->structmem("04");
539     $fools = $april->structmem("01");
540     $curly = $fools->structmem("curly");
541     $larry = $fools->structmem("larry");
542     $moe = $fools->structmem("moe");
543
544     return new PhpXmlRpc\Response(new Value($curly->scalarval() + $larry->scalarval() + $moe->scalarval(), "int"));
545 }
546
547 $v1_countTheEntities_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcString));
548 $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.';
549 function v1_countTheEntities($req)
550 {
551     $sno = $req->getParam(0);
552     $str = $sno->scalarval();
553     $gt = 0;
554     $lt = 0;
555     $ap = 0;
556     $qu = 0;
557     $amp = 0;
558     for ($i = 0; $i < strlen($str); $i++) {
559         $c = substr($str, $i, 1);
560         switch ($c) {
561             case ">":
562                 $gt++;
563                 break;
564             case "<":
565                 $lt++;
566                 break;
567             case "\"":
568                 $qu++;
569                 break;
570             case "'":
571                 $ap++;
572                 break;
573             case "&":
574                 $amp++;
575                 break;
576             default:
577                 break;
578         }
579     }
580
581     return new PhpXmlRpc\Response(new Value(array(
582         "ctLeftAngleBrackets" => new Value($lt, "int"),
583         "ctRightAngleBrackets" => new Value($gt, "int"),
584         "ctAmpersands" => new Value($amp, "int"),
585         "ctApostrophes" => new Value($ap, "int"),
586         "ctQuotes" => new Value($qu, "int"),),
587         "struct"
588     ));
589 }
590
591 // trivial interop tests
592 // http://www.xmlrpc.com/stories/storyReader$1636
593
594 $i_echoString_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
595 $i_echoString_doc = "Echoes string.";
596
597 $i_echoStringArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
598 $i_echoStringArray_doc = "Echoes string array.";
599
600 $i_echoInteger_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt));
601 $i_echoInteger_doc = "Echoes integer.";
602
603 $i_echoIntegerArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
604 $i_echoIntegerArray_doc = "Echoes integer array.";
605
606 $i_echoFloat_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble));
607 $i_echoFloat_doc = "Echoes float.";
608
609 $i_echoFloatArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
610 $i_echoFloatArray_doc = "Echoes float array.";
611
612 $i_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
613 $i_echoStruct_doc = "Echoes struct.";
614
615 $i_echoStructArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
616 $i_echoStructArray_doc = "Echoes struct array.";
617
618 $i_echoValue_doc = "Echoes any value back.";
619 $i_echoValue_sig = array(array(Value::$xmlrpcValue, Value::$xmlrpcValue));
620
621 $i_echoBase64_sig = array(array(Value::$xmlrpcBase64, Value::$xmlrpcBase64));
622 $i_echoBase64_doc = "Echoes base64.";
623
624 $i_echoDate_sig = array(array(Value::$xmlrpcDateTime, Value::$xmlrpcDateTime));
625 $i_echoDate_doc = "Echoes dateTime.";
626
627 function i_echoParam($req)
628 {
629     $s = $req->getParam(0);
630
631     return new PhpXmlRpc\Response($s);
632 }
633
634 function i_echoString($req)
635 {
636     return i_echoParam($req);
637 }
638
639 function i_echoInteger($req)
640 {
641     return i_echoParam($req);
642 }
643
644 function i_echoFloat($req)
645 {
646     return i_echoParam($req);
647 }
648
649 function i_echoStruct($req)
650 {
651     return i_echoParam($req);
652 }
653
654 function i_echoStringArray($req)
655 {
656     return i_echoParam($req);
657 }
658
659 function i_echoIntegerArray($req)
660 {
661     return i_echoParam($req);
662 }
663
664 function i_echoFloatArray($req)
665 {
666     return i_echoParam($req);
667 }
668
669 function i_echoStructArray($req)
670 {
671     return i_echoParam($req);
672 }
673
674 function i_echoValue($req)
675 {
676     return i_echoParam($req);
677 }
678
679 function i_echoBase64($req)
680 {
681     return i_echoParam($req);
682 }
683
684 function i_echoDate($req)
685 {
686     return i_echoParam($req);
687 }
688
689 $i_whichToolkit_sig = array(array(Value::$xmlrpcStruct));
690 $i_whichToolkit_doc = "Returns a struct containing the following strings: toolkitDocsUrl, toolkitName, toolkitVersion, toolkitOperatingSystem.";
691
692 function i_whichToolkit($req)
693 {
694     global $SERVER_SOFTWARE;
695     $ret = array(
696         "toolkitDocsUrl" => "http://phpxmlrpc.sourceforge.net/",
697         "toolkitName" => PhpXmlRpc\PhpXmlRpc::$xmlrpcName,
698         "toolkitVersion" => PhpXmlRpc\PhpXmlRpc::$xmlrpcVersion,
699         "toolkitOperatingSystem" => isset($SERVER_SOFTWARE) ? $SERVER_SOFTWARE : $_SERVER['SERVER_SOFTWARE'],
700     );
701
702     $encoder = new PhpXmlRpc\Encoder();
703     return new PhpXmlRpc\Response($encoder->encode($ret));
704 }
705
706 $object = new xmlrpcServerMethodsContainer();
707 $signatures = array(
708     "examples.getStateName" => array(
709         "function" => "findState",
710         "signature" => $findstate_sig,
711         "docstring" => $findstate_doc,
712     ),
713     "examples.sortByAge" => array(
714         "function" => "ageSorter",
715         "signature" => $agesorter_sig,
716         "docstring" => $agesorter_doc,
717     ),
718     "examples.addtwo" => array(
719         "function" => "addTwo",
720         "signature" => $addtwo_sig,
721         "docstring" => $addtwo_doc,
722     ),
723     "examples.addtwodouble" => array(
724         "function" => "addTwoDouble",
725         "signature" => $addtwodouble_sig,
726         "docstring" => $addtwodouble_doc,
727     ),
728     "examples.stringecho" => array(
729         "function" => "stringEcho",
730         "signature" => $stringecho_sig,
731         "docstring" => $stringecho_doc,
732     ),
733     "examples.echo" => array(
734         "function" => "echoBack",
735         "signature" => $echoback_sig,
736         "docstring" => $echoback_doc,
737     ),
738     "examples.decode64" => array(
739         "function" => "echoSixtyFour",
740         "signature" => $echosixtyfour_sig,
741         "docstring" => $echosixtyfour_doc,
742     ),
743     "examples.invertBooleans" => array(
744         "function" => "bitFlipper",
745         "signature" => $bitflipper_sig,
746         "docstring" => $bitflipper_doc,
747     ),
748     // signature omitted on purpose
749     "tests.generatePHPWarning" => array(
750         "function" => array($object, "phpWarningGenerator"),
751     ),
752     // signature omitted on purpose
753     "tests.raiseException" => array(
754         "function" => array($object, "exceptionGenerator"),
755     ),
756     // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
757     // NB: we can only register this when setting internal encoding to UTF-8, or it will break system.listMethods
758     "tests.utf8methodname." . 'κόσμε' => array(
759         "function" => "stringEcho",
760         "signature" => $stringecho_sig,
761         "docstring" => $stringecho_doc,
762     ),
763     /*"tests.iso88591methodname." . chr(224) . chr(252) . chr(232) => array(
764         "function" => "stringEcho",
765         "signature" => $stringecho_sig,
766         "docstring" => $stringecho_doc,
767     ),*/
768     "examples.getallheaders" => array(
769         "function" => 'getAllHeaders_xmlrpc',
770         "signature" => $getallheaders_sig,
771         "docstring" => $getallheaders_doc,
772     ),
773     "examples.setcookies" => array(
774         "function" => 'setCookies',
775         "signature" => $setcookies_sig,
776         "docstring" => $setcookies_doc,
777     ),
778     "examples.getcookies" => array(
779         "function" => 'getCookies',
780         "signature" => $getcookies_sig,
781         "docstring" => $getcookies_doc,
782     ),
783     "mail.send" => array(
784         "function" => "mailSend",
785         "signature" => $mailsend_sig,
786         "docstring" => $mailsend_doc,
787     ),
788     "validator1.arrayOfStructsTest" => array(
789         "function" => "v1_arrayOfStructs",
790         "signature" => $v1_arrayOfStructs_sig,
791         "docstring" => $v1_arrayOfStructs_doc,
792     ),
793     "validator1.easyStructTest" => array(
794         "function" => "v1_easyStruct",
795         "signature" => $v1_easyStruct_sig,
796         "docstring" => $v1_easyStruct_doc,
797     ),
798     "validator1.echoStructTest" => array(
799         "function" => "v1_echoStruct",
800         "signature" => $v1_echoStruct_sig,
801         "docstring" => $v1_echoStruct_doc,
802     ),
803     "validator1.manyTypesTest" => array(
804         "function" => "v1_manyTypes",
805         "signature" => $v1_manyTypes_sig,
806         "docstring" => $v1_manyTypes_doc,
807     ),
808     "validator1.moderateSizeArrayCheck" => array(
809         "function" => "v1_moderateSizeArrayCheck",
810         "signature" => $v1_moderateSizeArrayCheck_sig,
811         "docstring" => $v1_moderateSizeArrayCheck_doc,
812     ),
813     "validator1.simpleStructReturnTest" => array(
814         "function" => "v1_simpleStructReturn",
815         "signature" => $v1_simpleStructReturn_sig,
816         "docstring" => $v1_simpleStructReturn_doc,
817     ),
818     "validator1.nestedStructTest" => array(
819         "function" => "v1_nestedStruct",
820         "signature" => $v1_nestedStruct_sig,
821         "docstring" => $v1_nestedStruct_doc,
822     ),
823     "validator1.countTheEntities" => array(
824         "function" => "v1_countTheEntities",
825         "signature" => $v1_countTheEntities_sig,
826         "docstring" => $v1_countTheEntities_doc,
827     ),
828     "interopEchoTests.echoString" => array(
829         "function" => "i_echoString",
830         "signature" => $i_echoString_sig,
831         "docstring" => $i_echoString_doc,
832     ),
833     "interopEchoTests.echoStringArray" => array(
834         "function" => "i_echoStringArray",
835         "signature" => $i_echoStringArray_sig,
836         "docstring" => $i_echoStringArray_doc,
837     ),
838     "interopEchoTests.echoInteger" => array(
839         "function" => "i_echoInteger",
840         "signature" => $i_echoInteger_sig,
841         "docstring" => $i_echoInteger_doc,
842     ),
843     "interopEchoTests.echoIntegerArray" => array(
844         "function" => "i_echoIntegerArray",
845         "signature" => $i_echoIntegerArray_sig,
846         "docstring" => $i_echoIntegerArray_doc,
847     ),
848     "interopEchoTests.echoFloat" => array(
849         "function" => "i_echoFloat",
850         "signature" => $i_echoFloat_sig,
851         "docstring" => $i_echoFloat_doc,
852     ),
853     "interopEchoTests.echoFloatArray" => array(
854         "function" => "i_echoFloatArray",
855         "signature" => $i_echoFloatArray_sig,
856         "docstring" => $i_echoFloatArray_doc,
857     ),
858     "interopEchoTests.echoStruct" => array(
859         "function" => "i_echoStruct",
860         "signature" => $i_echoStruct_sig,
861         "docstring" => $i_echoStruct_doc,
862     ),
863     "interopEchoTests.echoStructArray" => array(
864         "function" => "i_echoStructArray",
865         "signature" => $i_echoStructArray_sig,
866         "docstring" => $i_echoStructArray_doc,
867     ),
868     "interopEchoTests.echoValue" => array(
869         "function" => "i_echoValue",
870         "signature" => $i_echoValue_sig,
871         "docstring" => $i_echoValue_doc,
872     ),
873     "interopEchoTests.echoBase64" => array(
874         "function" => "i_echoBase64",
875         "signature" => $i_echoBase64_sig,
876         "docstring" => $i_echoBase64_doc,
877     ),
878     "interopEchoTests.echoDate" => array(
879         "function" => "i_echoDate",
880         "signature" => $i_echoDate_sig,
881         "docstring" => $i_echoDate_doc,
882     ),
883     "interopEchoTests.whichToolkit" => array(
884         "function" => "i_whichToolkit",
885         "signature" => $i_whichToolkit_sig,
886         "docstring" => $i_whichToolkit_doc,
887     ),
888
889     'tests.getStateName.2' => $findstate2_sig,
890     'tests.getStateName.3' => $findstate3_sig,
891     'tests.getStateName.4' => $findstate4_sig,
892     'tests.getStateName.5' => $findstate5_sig,
893     'tests.getStateName.6' => $findstate6_sig,
894     'tests.getStateName.7' => $findstate7_sig,
895     'tests.getStateName.8' => $findstate8_sig,
896     'tests.getStateName.9' => $findstate9_sig,
897     'tests.getStateName.10' => $findstate10_sig,
898
899 );
900
901 $signatures = array_merge($signatures, $moreSignatures);
902
903 $s = new PhpXmlRpc\Server($signatures, false);
904 $s->setdebug(3);
905 $s->compress_response = true;
906
907 // out-of-band information: let the client manipulate the server operations.
908 // we do this to help the testsuite script: do not reproduce in production!
909 if (isset($_GET['RESPONSE_ENCODING'])) {
910     $s->response_charset_encoding = $_GET['RESPONSE_ENCODING'];
911 }
912 if (isset($_GET['EXCEPTION_HANDLING'])) {
913     $s->exception_handling = $_GET['EXCEPTION_HANDLING'];
914 }
915 $s->service();
916 // that should do all we need!
917
918 // out-of-band information: let the client manipulate the server operations.
919 // we do this to help the testsuite script: do not reproduce in production!
920 if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
921     include_once __DIR__ . "/../../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/append.php";
922 }