From 7c35ac36c1dea2d6f26d8184dcbf1fe5afae59ac Mon Sep 17 00:00:00 2001
From: Dominik Eckelmann <deckelmann@gmail.com>
Date: Wed, 21 Mar 2012 13:15:18 +0100
Subject: [PATCH] added RPC_CALL_ADD event.

This event enables plugins to register custom method names.
---
 _test/cases/inc/remote.test.php | 12 +++++++++++
 inc/remote.php                  | 37 ++++++++++++++++++++++++++++++---
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/_test/cases/inc/remote.test.php b/_test/cases/inc/remote.test.php
index 186f8e65a..f03d13ce1 100644
--- a/_test/cases/inc/remote.test.php
+++ b/_test/cases/inc/remote.test.php
@@ -309,4 +309,16 @@ class remote_test extends UnitTestCase {
         $remoteApi->call('plugin.testplugin.methodString');
     }
 
+    function test_pluginCallCustomPath() {
+        global $EVENT_HANDLER;
+        $EVENT_HANDLER->register_hook('RPC_CALL_ADD', 'BEFORE', &$this, 'pluginCallCustomPathRegister');
+
+        $remoteApi = new RemoteAPI();
+        $result = $remoteApi->call('custom.path');
+        $this->assertEqual($result, 'success');
+    }
+
+    function pluginCallCustomPathRegister(&$event, $param) {
+        $event->data['custom.path'] = array('testplugin', 'methodString');
+    }
 }
diff --git a/inc/remote.php b/inc/remote.php
index b4cc8e6cc..089a5f7d4 100644
--- a/inc/remote.php
+++ b/inc/remote.php
@@ -35,8 +35,6 @@ class RemoteAccessDeniedException extends RemoteException {}
  * plugin methods are formed like 'plugin.<plugin name>.<method name>'.
  * i.e.: plugin.clock.getTime or plugin.clock_gmt.getTime
  *
- *
- *
  * @throws RemoteException
  */
 class RemoteAPI {
@@ -52,6 +50,14 @@ class RemoteAPI {
      */
     private $pluginMethods = null;
 
+    /**
+     * @var array contains custom calls to the api. Plugins can use the XML_CALL_REGISTER event.
+     * The data inside is 'custom.call.something' => array('plugin name', 'remote method name')
+     *
+     * The remote method name is the same as in the remote name returned by _getMethods().
+     */
+    private $pluginCustomCalls = null;
+
     private $dateTransformation;
     private $fileTransformation;
 
@@ -83,9 +89,34 @@ class RemoteAPI {
         list($type, $pluginName, $call) = explode('.', $method, 3);
         if ($type === 'plugin') {
             return $this->callPlugin($pluginName, $method, $args);
-        } else {
+        }
+        if ($this->coreMethodExist($method)) {
             return $this->callCoreMethod($method, $args);
         }
+        return $this->callCustomCallPlugin($method, $args);
+    }
+
+    private function coreMethodExist($name) {
+        $coreMethods = $this->getCoreMethods();
+        return array_key_exists($name, $coreMethods);
+    }
+
+    private function  callCustomCallPlugin($method, $args) {
+        $customCalls = $this->getCustomCallPlugins();
+        if (!array_key_exists($method, $customCalls)) {
+            throw new RemoteException('Method does not exist', -32603);
+        }
+        $customCall = $customCalls[$method];
+        return $this->callPlugin($customCall[0], $customCall[1], $args);
+    }
+
+    private function getCustomCallPlugins() {
+        if ($this->pluginCustomCalls === null) {
+            $data = array();
+            trigger_event('RPC_CALL_ADD', $data);
+            $this->pluginCustomCalls = $data;
+        }
+        return $this->pluginCustomCalls;
     }
 
     private function callPlugin($pluginName, $method, $args) {
-- 
GitLab