summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Eckelmann <deckelmann@gmail.com>2011-12-08 19:57:18 +0100
committerDominik Eckelmann <deckelmann@gmail.com>2011-12-08 19:57:18 +0100
commit4815d222f25c9a31949297223c98cfca7151ae8d (patch)
tree8cc6ae8845ad7ddf40a40663f32a9c17845f5d85
parent3f3bb97fcdd30282632d96a5bb19d2ea61c01504 (diff)
downloadrpg-4815d222f25c9a31949297223c98cfca7151ae8d.tar.gz
rpg-4815d222f25c9a31949297223c98cfca7151ae8d.tar.bz2
RemoteAPI can now handle remote calls.
-rw-r--r--_test/cases/inc/remote.test.php102
-rw-r--r--inc/RemoteAPICore.php43
-rw-r--r--inc/remote.php68
3 files changed, 193 insertions, 20 deletions
diff --git a/_test/cases/inc/remote.test.php b/_test/cases/inc/remote.test.php
index aa7a8cd1b..b33d8039f 100644
--- a/_test/cases/inc/remote.test.php
+++ b/_test/cases/inc/remote.test.php
@@ -1,9 +1,74 @@
<?php
require_once DOKU_INC . 'inc/init.php';
+require_once DOKU_INC . 'inc/RemoteAPICore.php';
Mock::generate('Doku_Plugin_Controller');
+class RemoteAPICoreTest {
+
+ function __getRemoteInfo() {
+ return array(
+ 'wiki.stringTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'string',
+ 'doc' => 'Test method',
+ 'name' => 'stringTestMethod',
+ ), 'wiki.intTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'int',
+ 'doc' => 'Test method',
+ 'name' => 'intTestMethod',
+ ), 'wiki.floatTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'float',
+ 'doc' => 'Test method',
+ 'name' => 'floatTestMethod',
+ ), 'wiki.dateTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'date',
+ 'doc' => 'Test method',
+ 'name' => 'dateTestMethod',
+ ), 'wiki.fileTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'file',
+ 'doc' => 'Test method',
+ 'name' => 'fileTestMethod',
+ ), 'wiki.voidTestMethod' => array(
+ 'args' => array(),
+ 'return' => 'void',
+ 'doc' => 'Test method',
+ 'name' => 'voidTestMethod',
+ ), 'wiki.oneStringArgMethod' => array(
+ 'args' => array('string'),
+ 'return' => 'string',
+ 'doc' => 'Test method',
+ 'name' => 'oneStringArgMethod',
+ ), 'wiki.twoArgMethod' => array(
+ 'args' => array('string', 'int'),
+ 'return' => 'array',
+ 'doc' => 'Test method',
+ 'name' => 'twoArgMethod',
+ ), 'wiki.twoArgWithDefaultArg' => array(
+ 'args' => array('string', 'string'),
+ 'return' => 'string',
+ 'doc' => 'Test method',
+ 'name' => 'twoArgWithDefaultArg',
+ ),
+ );
+ }
+ function stringTestMethod() { return 'success'; }
+ function intTestMethod() { return 42; }
+ function floatTestMethod() { return 3.14159265; }
+ function dateTestMethod() { return 2623452346; }
+ function fileTestMethod() { return 'file content'; }
+ function voidTestMethod() { return null; }
+ function oneStringArgMethod($arg) {return $arg; }
+ function twoArgMethod($string, $int) { return array($string, $int); }
+ function twoArgWithDefaultArg($string1, $string2 = 'default') { return array($string1, $string2); }
+
+}
+
class remote_plugin_testplugin extends DokuWiki_Remote_Plugin {
function _getMethods() {
return array(
@@ -74,4 +139,41 @@ class remote_test extends UnitTestCase {
$this->expectException('RemoteException');
$this->remote->forceAccess();
}
+
+ function test_generalCoreFunctionWithoutArguments() {
+ global $conf;
+ $conf['remote'] = 1;
+ $remoteApi = new RemoteApi();
+ $remoteApi->getCoreMethods(new RemoteAPICoreTest());
+
+ $this->assertEqual($remoteApi->call('wiki.stringTestMethod'), 'success');
+ $this->assertEqual($remoteApi->call('wiki.intTestMethod'), 42);
+ $this->assertEqual($remoteApi->call('wiki.floatTestMethod'), 3.14159265);
+ $this->assertEqual($remoteApi->call('wiki.dateTestMethod'), 2623452346);
+ $this->assertEqual($remoteApi->call('wiki.fileTestMethod'), 'file content');
+ $this->assertEqual($remoteApi->call('wiki.voidTestMethod'), null);
+ }
+
+ function test_generalCoreFunctionOnArgumentMismatch() {
+ global $conf;
+ $conf['remote'] = 1;
+ $remoteApi = new RemoteApi();
+ $remoteApi->getCoreMethods(new RemoteAPICoreTest());
+
+ $this->expectException('RemoteException');
+ $remoteApi->call('wiki.voidTestMethod', array('something'));
+ }
+
+ function test_generalCoreFunctionWithArguments() {
+ global $conf;
+ $conf['remote'] = 1;
+
+ $remoteApi = new RemoteApi();
+ $remoteApi->getCoreMethods(new RemoteAPICoreTest());
+
+ $this->assertEqual($remoteApi->call('wiki.oneStringArgMethod', array('string')), 'string');
+ $this->assertEqual($remoteApi->call('wiki.twoArgMethod', array('string', 1)), array('string' , 1));
+ $this->assertEqual($remoteApi->call('wiki.twoArgWithDefaultArg', array('string')), array('string', 'default'));
+ $this->assertEqual($remoteApi->call('wiki.twoArgWithDefaultArg', array('string', 'another')), array('string', 'another'));
+ }
}
diff --git a/inc/RemoteAPICore.php b/inc/RemoteAPICore.php
index c4324ba29..a2e12c7f1 100644
--- a/inc/RemoteAPICore.php
+++ b/inc/RemoteAPICore.php
@@ -2,6 +2,47 @@
class RemoteAPICore {
+ function __getRemoteInfo() {
+ return array(
+ 'wiki.getPage' => array(
+ 'args' => array(
+ 'id' => array(
+ 'type' => 'string',
+ 'doc' => 'wiki page id'
+ ),
+ ),
+ 'return' => 'string',
+ 'doc' => 'Return a raw wiki page',
+ 'name' => 'rawPage',
+ ),
+ 'wiki.getPageVersion' => array(
+ 'args' => array(
+ 'id' => array(
+ 'type' => 'string',
+ 'doc' => 'wiki page id'
+ ),
+ 'rev' => array(
+ 'type' => 'int',
+ 'doc' => 'revision number of the page',
+ ),
+ ),
+ 'name' => 'rawPage',
+ 'return' => 'string',
+ 'doc' => 'Return a raw wiki page'
+ ),
+ 'wiki.getAttachment' => array(
+ 'args' => array(
+ 'type' => 'string',
+ 'doc' => 'file id',
+ ),
+ 'doc' => 'Return a media file',
+ 'return' => 'file',
+ 'name' => 'getAttachment',
+ ),
+
+ );
+ }
+
/**
* Return a raw wiki page
* @param string $id wiki page id
@@ -58,7 +99,7 @@ class RemoteAPICore {
$file = mediaFN($id);
if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
- $info['lastModified'] = new IXR_Date(filemtime($file));
+ $info['lastModified'] = filemtime($file);
$info['size'] = filesize($file);
}
diff --git a/inc/remote.php b/inc/remote.php
index 14f6614f1..5f136a43d 100644
--- a/inc/remote.php
+++ b/inc/remote.php
@@ -2,6 +2,9 @@
if (!defined('DOKU_INC')) die();
+class RemoteException extends Exception {}
+class RemoteAccessDenied extends RemoteException {}
+
/**
* This class provides information about remote access to the wiki.
*
@@ -13,11 +16,16 @@ if (!defined('DOKU_INC')) die();
* == Information structure ==
* The information about methods will be given in an array with the following structure:
* array(
- * 'method.name' => array(
+ * 'method.remoteName' => array(
* 'args' => array(
- * 'type' => 'string|int|...',
+ * 'name' => array(
+ * 'type' => 'string|int|...|date|file',
+ * ['doc' = 'argument documentation'],
+ * ),
* )
- * 'return' => 'type'
+ * 'name' => 'method name in class',
+ * 'return' => 'type',
+* ['doc' = 'method documentation'],
* )
* )
*
@@ -35,9 +43,9 @@ if (!defined('DOKU_INC')) die();
class RemoteAPI {
/**
- * @var array remote methods provided by dokuwiki.
+ * @var RemoteAPICore
*/
- private $coreMethods = array();
+ private $coreMethods = null;
/**
* @var array remote methods provided by dokuwiki plugins - will be filled lazy via
@@ -62,19 +70,36 @@ class RemoteAPI {
* @param array $args arguments to pass to the given method
* @return mixed result of method call, must be a primitive type.
*/
- public function call($method, $args) {
+ public function call($method, $args = array()) {
$this->forceAccess();
- $method = explode('.', $method);
- if ($method[0] === 'plugin') {
- $plugin = plugin_load('remote', $method[1]);
+ list($type, $pluginName, $call) = explode('.', $method, 3);
+ if ($type === 'plugin') {
+ $plugin = plugin_load('remote', $pluginName);
if (!$plugin) {
- throw new RemoteException('Method unavailable');
+ throw new RemoteException('Method dose not exists');
}
- return call_user_func_array(array($plugin, $method[2]), $args);
+ return call_user_func_array(array($plugin, $call), $args);
} else {
- // TODO call core method
+ $coreMethods = $this->getCoreMethods();
+ if (!isset($coreMethods[$method])) {
+ throw new RemoteException('Method dose not exists');
+ }
+ $this->checkArgumentLength($coreMethods[$method], $args);
+ return call_user_func_array(array($this->coreMethods, $this->getMethodName($coreMethods, $method)), $args);
}
+ }
+ private function checkArgumentLength($method, $args) {
+ if (count($method['args']) < count($args)) {
+ throw new RemoteException('Method dose not exists - wrong parameter count.');
+ }
+ }
+
+ private function getMethodName($methodMeta, $method) {
+ if (isset($methodMeta[$method]['name'])) {
+ return $methodMeta[$method]['name'];
+ }
+ return $method;
}
/**
@@ -122,13 +147,18 @@ class RemoteAPI {
}
/**
+ * @param RemoteAPICore $apiCore this parameter is used for testing. Here you can pass a non-default RemoteAPICore
+ * instance. (for mocking)
* @return array all core methods.
*/
- public function getCoreMethods() {
- return $this->coreMethods;
+ public function getCoreMethods($apiCore = null) {
+ if ($this->coreMethods === null) {
+ if ($apiCore === null) {
+ $this->coreMethods = new RemoteAPICore();
+ } else {
+ $this->coreMethods = $apiCore;
+ }
+ }
+ return $this->coreMethods->__getRemoteInfo();
}
-}
-
-
-class RemoteException extends Exception {}
-class RemoteAccessDenied extends RemoteException {} \ No newline at end of file
+} \ No newline at end of file