From 2abc370848cc6d801c2a242e9c9b45f3028dfff3 Mon Sep 17 00:00:00 2001 From: gggeek Date: Tue, 10 Jan 2023 12:28:29 +0000 Subject: [PATCH] add two demos for code generation capabilities --- demo/client/codegen.php | 55 +++++++++++++ demo/server/codegen.php | 68 ++++++++++++++++ demo/server/discuss.php | 79 +------------------ .../server/methodProviders/CommentManager.php | 78 ++++++++++++++++++ 4 files changed, 203 insertions(+), 77 deletions(-) create mode 100644 demo/client/codegen.php create mode 100644 demo/server/codegen.php create mode 100644 demo/server/methodProviders/CommentManager.php diff --git a/demo/client/codegen.php b/demo/client/codegen.php new file mode 100644 index 00000000..25727723 --- /dev/null +++ b/demo/client/codegen.php @@ -0,0 +1,55 @@ +wrapXmlrpcServer( + new Client(XMLRPCSERVER), + array( + 'return_source' => true, + 'new_class_name' => 'MyClient', + 'method_filter' => '/^examples\./', + 'simple_client_copy' => true, + ) +); + +// the generated code does not have an autoloader included - we need to add in one +$autoloader = __DIR__ . "/_prepend.php"; + +$targetFile = '/tmp/MyClient.php'; +$generated = file_put_contents($targetFile, + "examples_sortByAge(array( + array('name' => 'Dave', 'age' => 24), + array('name' => 'Edd', 'age' => 45), + array('name' => 'Joe', 'age' => 37), + array('name' => 'Fred', 'age' => 27), +)); + +echo "Sorted array:\n"; +print_r($sorted); diff --git a/demo/server/codegen.php b/demo/server/codegen.php new file mode 100644 index 00000000..103b2e60 --- /dev/null +++ b/demo/server/codegen.php @@ -0,0 +1,68 @@ +wrapPhpClass( + $cm, + array( + 'method_type' => 'nonstatic', + 'return_source' => true, + ) +); + +// the generated code does not have an autoloader included - we need to add in one +$autoloader = __DIR__ . "/_prepend.php"; + +$targetClassFile = '/tmp/MyServerClass.php'; +$targetDispatchMapFile = '/tmp/myServerDM.php'; + +// generate a file with a class definition + +file_put_contents($targetClassFile, + " $methodDef) { + file_put_contents($targetClassFile, 'public static ' . $methodDef['source'] . "\n\n", FILE_APPEND) || die('uh oh'); + $code[$methodName]['function'] = 'MyServerClass::' . $methodDef['function']; + unset($code[$methodName]['source']); +} +file_put_contents($targetClassFile, "}\n", FILE_APPEND) || die('uh oh'); + +// and a separate file with the dispatch map + +file_put_contents($targetDispatchMapFile, + "setDebug(2); +$s->exception_handling = 1; +$s->service(); diff --git a/demo/server/discuss.php b/demo/server/discuss.php index 6f2f905b..b31dc3c9 100644 --- a/demo/server/discuss.php +++ b/demo/server/discuss.php @@ -1,7 +1,6 @@ exec('CREATE TABLE IF NOT EXISTS comments (msg_id TEXT NOT NULL, name TEXT NOT NULL, comment TEXT NOT NULL)'); - } - - /** - * NB: we know for a fact that this will be called with 3 string arguments because of the signature used to register - * this method in the dispatch map. But nothing prevents the client from sending empty strings, nor sql-injection attempts! - * - * @param string $msgID - * @param string $name - * @param string $comment - * @return int - * @throws \Exception - */ - public function addComment($msgID, $name, $comment) - { - $db = new SQLite3($this->dbFile); - $this->createTable($db); - - $statement = $db->prepare("INSERT INTO comments VALUES(:msg_id, :name, :comment)"); - $statement->bindValue(':msg_id', $msgID); - $statement->bindValue(':name', $name); - $statement->bindValue(':comment', $comment); - $statement->execute(); - - /// @todo this insert-then-count is not really atomic - we should use a transaction - - $statement = $db->prepare("SELECT count(*) AS tot FROM comments WHERE msg_id = :id"); - $statement->bindValue(':id', $msgID); - $results = $statement->execute(); - $row = $results->fetchArray(SQLITE3_ASSOC); - $results->finalize(); - $count = $row['tot']; - - $db->close(); - - return $count; - } - - /** - * NB: we know for a fact that this will be called with 1 strin arguments because of the signature used to register - * this method in the dispatch map. But nothing prevents the client from sending empty strings, nor sql-injection attempts! - * - * @param string $msgID - * @return Response|array[] - * @throws \Exception - */ - public function getComments($msgID) - { - $db = new SQLite3($this->dbFile); - $this->createTable($db); - - $ra = array(); - $statement = $db->prepare("SELECT name, comment FROM comments WHERE msg_id = :id ORDER BY rowid"); - $statement->bindValue(':id', $msgID); - $results = $statement->execute(); - while ($row = $results->fetchArray(SQLITE3_ASSOC)) { - $ra[] = $row; - } - $results->finalize(); - - $db->close(); - - return $ra; - } -} - -// Here starts the mapping of CommentManager's methods into xml-rpc methods - $manager = new CommentManager(); $addComment_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString)); diff --git a/demo/server/methodProviders/CommentManager.php b/demo/server/methodProviders/CommentManager.php new file mode 100644 index 00000000..f5174113 --- /dev/null +++ b/demo/server/methodProviders/CommentManager.php @@ -0,0 +1,78 @@ +exec('CREATE TABLE IF NOT EXISTS comments (msg_id TEXT NOT NULL, name TEXT NOT NULL, comment TEXT NOT NULL)'); + } + + /** + * NB: we know for a fact that this will be called with 3 string arguments because of the signature used to register + * this method in the dispatch map. But nothing prevents the client from sending empty strings, nor sql-injection attempts! + * + * @param string $msgID + * @param string $name username + * @param string $comment comment text + * @return int the number of comments for the given message + * @throws \Exception + */ + public function addComment($msgID, $name, $comment) + { + $db = new SQLite3($this->dbFile); + $this->createTable($db); + + $statement = $db->prepare("INSERT INTO comments VALUES(:msg_id, :name, :comment)"); + $statement->bindValue(':msg_id', $msgID); + $statement->bindValue(':name', $name); + $statement->bindValue(':comment', $comment); + $statement->execute(); + + /// @todo this insert-then-count is not really atomic - we should use a transaction + + $statement = $db->prepare("SELECT count(*) AS tot FROM comments WHERE msg_id = :id"); + $statement->bindValue(':id', $msgID); + $results = $statement->execute(); + $row = $results->fetchArray(SQLITE3_ASSOC); + $results->finalize(); + $count = $row['tot']; + + $db->close(); + + return $count; + } + + /** + * NB: we know for a fact that this will be called with 1 string arguments because of the signature used to register + * this method in the dispatch map. But nothing prevents the client from sending empty strings, nor sql-injection attempts! + * + * @param string $msgID + * @return array[] each element is a struct, with elements 'name', 'comment' + * @throws \Exception + */ + public function getComments($msgID) + { + $db = new SQLite3($this->dbFile); + $this->createTable($db); + + $ra = array(); + $statement = $db->prepare("SELECT name, comment FROM comments WHERE msg_id = :id ORDER BY rowid"); + $statement->bindValue(':id', $msgID); + $results = $statement->execute(); + while ($row = $results->fetchArray(SQLITE3_ASSOC)) { + $ra[] = $row; + } + $results->finalize(); + + $db->close(); + + return $ra; + } +} -- 2.47.0