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