|
13 | 13 | use PhpXmlRpc\Wrapper; |
14 | 14 |
|
15 | 15 | if (isset($_GET['generate']) && $_GET['generate']) { |
16 | | -// CommentManager is the "xml-rpc-unaware" class, whose methods we want to make accessible via xml-rpc calls |
17 | | -$cm = new CommentManager(sys_get_temp_dir() . "/comments.db"); |
18 | | - |
19 | | -// analyze the CommentManager instance and generate both code defining stub-methods and a dispatch map for the xml-rpc Server |
20 | | -$w = new Wrapper(); |
21 | | -$code = $w->wrapPhpClass( |
22 | | - $cm, |
23 | | - array( |
24 | | - 'method_type' => 'nonstatic', |
25 | | - 'return_source' => true, |
26 | | - // this is used to encode php NULL values into xml-rpc <NIL/> elements. If the partner does not support that, disable it |
27 | | - 'encode_nulls' => true, |
28 | | - ) |
29 | | -); |
30 | | - |
31 | | -// save the generated code in 3 files: a new class definition, holding all the stub methods, a file with the dispatch-map, |
32 | | -// and a controller, to be accessed from the internet. This split allows to a) hand-edit the controller code if needed, |
33 | | -// and b) later regenerate the stub-methods-holder and dispatch map without touching the controller. |
34 | | -// NB: good security practices dictate that none of those files should be writeable by the webserver user account |
35 | | -$targetClassFile = sys_get_temp_dir() . '/MyServerClass.php'; |
36 | | -$targetDispatchMapFile = sys_get_temp_dir() . '/myServerDispatchMap.php'; |
37 | | -$targetControllerFile = sys_get_temp_dir() . '/myServerController.php'; |
38 | | - |
39 | | -// generate a file with a class definition |
40 | | - |
41 | | -// the generated code does not have an autoloader included - we need to add in one |
42 | | -$autoloader = __DIR__ . "/_prepend.php"; |
43 | | - |
44 | | -file_put_contents($targetClassFile, |
45 | | - "<?php\n\n" . |
46 | | - "require_once '$autoloader';\n\n" . |
47 | | - "class MyServerClass\n{\n\n" |
48 | | -) || die('uh oh'); |
49 | | - |
50 | | -// we mangle a bit the code we get from wrapPhpClass to turn it into a php class definition instead of a bunch of functions |
51 | | - |
52 | | -foreach ($code as $methodName => $methodDef) { |
53 | | - file_put_contents($targetClassFile, ' ' . str_replace(array('function ', "\n"), array('public static function ', "\n "), $methodDef['source']) . "\n\n", FILE_APPEND) || die('uh oh'); |
54 | | - $code[$methodName]['function'] = 'MyServerClass::' . $methodDef['function']; |
55 | | - unset($code[$methodName]['source']); |
56 | | -} |
57 | | -file_put_contents($targetClassFile, "}\n", FILE_APPEND) || die('uh oh'); |
| 16 | + // *** NB do not do this in prod! The whole concept of code-generation is to do it offline using console scripts/ci/cd *** |
| 17 | + |
| 18 | + // CommentManager is the "xml-rpc-unaware" class, whose methods we want to make accessible via xml-rpc calls |
| 19 | + $cm = new CommentManager(sys_get_temp_dir() . "/comments.db"); |
| 20 | + |
| 21 | + // analyze the CommentManager instance and generate both code defining stub-methods and a dispatch map for the xml-rpc Server |
| 22 | + $w = new Wrapper(); |
| 23 | + $code = $w->wrapPhpClass( |
| 24 | + $cm, |
| 25 | + array( |
| 26 | + 'method_type' => 'nonstatic', |
| 27 | + 'return_source' => true, |
| 28 | + // this is used to encode php NULL values into xml-rpc <NIL/> elements. If the partner does not support that, disable it |
| 29 | + 'encode_nulls' => true, |
| 30 | + ) |
| 31 | + ); |
| 32 | + |
| 33 | + // save the generated code in 3 files: a new class definition, holding all the stub methods, a file with the dispatch-map, |
| 34 | + // and a controller, to be accessed from the internet. This split allows to a) hand-edit the controller code if needed, |
| 35 | + // and b) later regenerate the stub-methods-holder and dispatch map without touching the controller. |
| 36 | + // NB: good security practices dictate that none of those files should be writeable by the webserver user account |
| 37 | + $targetClassFile = sys_get_temp_dir() . '/MyServerClass.php'; |
| 38 | + $targetDispatchMapFile = sys_get_temp_dir() . '/myServerDispatchMap.php'; |
| 39 | + $targetControllerFile = sys_get_temp_dir() . '/myServerController.php'; |
| 40 | + |
| 41 | + // generate a file with a class definition |
| 42 | + |
| 43 | + // the generated code does not have an autoloader included - we need to add in one |
| 44 | + $autoloader = __DIR__ . "/_prepend.php"; |
58 | 45 |
|
59 | | -// generate separate files with the xml-rpc server instantiation and its dispatch map |
| 46 | + file_put_contents($targetClassFile, |
| 47 | + "<?php\n\n" . |
| 48 | + "require_once '$autoloader';\n\n" . |
| 49 | + "class MyServerClass\n{\n\n" |
| 50 | + ) || die('uh oh'); |
60 | 51 |
|
61 | | -file_put_contents($targetDispatchMapFile, "<?php\n\nreturn " . var_export($code, true) . ";\n"); |
| 52 | + // we mangle a bit the code we get from wrapPhpClass to turn it into a php class definition instead of a bunch of functions |
62 | 53 |
|
63 | | -file_put_contents($targetControllerFile, |
64 | | - "<?php\n\n" . |
| 54 | + foreach ($code as $methodName => $methodDef) { |
| 55 | + file_put_contents($targetClassFile, ' ' . str_replace(array('function ', "\n"), array('public static function ', "\n "), $methodDef['source']) . "\n\n", FILE_APPEND) || die('uh oh'); |
| 56 | + $code[$methodName]['function'] = 'MyServerClass::' . $methodDef['function']; |
| 57 | + unset($code[$methodName]['source']); |
| 58 | + } |
| 59 | + file_put_contents($targetClassFile, "}\n", FILE_APPEND) || die('uh oh'); |
65 | 60 |
|
66 | | - "// autoloader\n" . |
67 | | - "require_once '$autoloader';\n\n" . |
| 61 | + // generate separate files with the xml-rpc server instantiation and its dispatch map |
68 | 62 |
|
69 | | - "require_once '$targetClassFile';\n\n" . |
| 63 | + file_put_contents($targetDispatchMapFile, "<?php\n\nreturn " . var_export($code, true) . ";\n"); |
| 64 | + |
| 65 | + file_put_contents($targetControllerFile, |
| 66 | + "<?php\n\n" . |
| 67 | + |
| 68 | + "// class autoloader\n" . |
| 69 | + "require_once '$autoloader';\n\n" . |
70 | 70 |
|
71 | 71 | // NB: if we were running the generated code within the same script, the existing CommentManager instance would be |
72 | 72 | // available for usage by the methods of MyServerClass, as we keep a reference to them within the variable Wrapper::$objHolder, |
73 | 73 | // but since we are generating a php file for later use, it is up to us to initialize that variable with a |
74 | | - // CommentManager instance: |
| 74 | + // CommentManager instance |
| 75 | + "// business logic setup\n" . |
75 | 76 | "\$cm = new CommentManager(sys_get_temp_dir() . '/comments.db');\n" . |
| 77 | + "// save reference to the biz logic object so that it can be used by the code in the generated class\n" . |
76 | 78 | "\PhpXmlRpc\Wrapper::holdObject('*', \$cm);\n\n" . |
77 | 79 |
|
78 | | - "\$dm = require_once '$targetDispatchMapFile';\n" . |
79 | | - '$s = new \PhpXmlRpc\Server($dm, false);' . "\n\n" . |
80 | | - '// NB: do not leave these 2 debug lines enabled on publicly accessible servers!' . "\n" . |
81 | | - '$s->setOption(\PhpXmlRpc\Server::OPT_DEBUG, 2);' . "\n" . |
82 | | - '$s->setOption(\PhpXmlRpc\Server::OPT_EXCEPTION_HANDLING, 1);' . "\n\n" . |
83 | | - '$s->service();' . "\n" |
84 | | -) || die('uh oh'); |
| 80 | + "// the generated class implementing the json-rpc methods is not namespaced, load it explicitly\n" . |
| 81 | + "require_once '$targetClassFile';\n\n" . |
| 82 | + |
| 83 | + "// load the dispatch map and feed it to the json-rpc server\n" . |
| 84 | + "\$dm = require_once '$targetDispatchMapFile';\n" . |
| 85 | + '$s = new \PhpXmlRpc\Server($dm, false);' . "\n\n" . |
| 86 | + '// NB: do not leave these 2 debug lines enabled on publicly accessible servers!' . "\n" . |
| 87 | + '$s->setOption(\PhpXmlRpc\Server::OPT_DEBUG, 2);' . "\n" . |
| 88 | + '$s->setOption(\PhpXmlRpc\Server::OPT_EXCEPTION_HANDLING, 1);' . "\n\n" . |
| 89 | + '$s->service();' . "\n" |
| 90 | + ) || die('uh oh'); |
85 | 91 |
|
86 | 92 | echo "Code generated"; |
87 | 93 | } else { |
88 | 94 | // test that everything worked by running it in realtime (note that this script will return an xml-rpc error message if |
89 | 95 | // run from the command line, as the server will find no xml-rpc payload to operate on) |
90 | 96 |
|
91 | | - // *** NB do not do this in prod! The whole concept of code-generation is to do it offline using console scripts/ci/cd *** |
92 | | - |
93 | 97 | $targetControllerFile = sys_get_temp_dir() . '/myServerController.php'; |
94 | 98 | require $targetControllerFile; |
95 | 99 | } |
0 commit comments