From b5311ce466aa12322f71ee4c5dd6e40123471f39 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 14 Aug 2018 13:32:06 +0100 Subject: [PATCH] MDL-63131 Web services: Callback to allow web service overrides --- lib/externallib.php | 25 +++++++++++++++++++++---- webservice/lib.php | 20 +++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/externallib.php b/lib/externallib.php index 44fbd297a17..50a88f1b078 100644 --- a/lib/externallib.php +++ b/lib/externallib.php @@ -221,11 +221,28 @@ class external_api { $params = call_user_func($callable, $externalfunctioninfo->parameters_desc, $args); + $params = array_values($params); - // Execute - gulp! - $callable = array($externalfunctioninfo->classname, $externalfunctioninfo->methodname); - $result = call_user_func_array($callable, - array_values($params)); + // Allow any Moodle plugin a chance to override this call. This is a convenient spot to + // make arbitrary behaviour customisations. The overriding plugin could call the 'real' + // function first and then modify the results, or it could do a completely separate + // thing. + $callbacks = get_plugins_with_function('override_webservice_execution'); + $result = false; + foreach ($callbacks as $plugintype => $plugins) { + foreach ($plugins as $plugin => $callback) { + $result = $callback($externalfunctioninfo, $params); + if ($result !== false) { + break; + } + } + } + + // If the function was not overridden, call the real one. + if ($result === false) { + $callable = array($externalfunctioninfo->classname, $externalfunctioninfo->methodname); + $result = call_user_func_array($callable, $params); + } // Validate the return parameters. if ($externalfunctioninfo->returns_desc !== null) { diff --git a/webservice/lib.php b/webservice/lib.php index 5da1bba99bb..fedfbc8e46b 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -1392,9 +1392,27 @@ abstract class webservice_base_server extends webservice_server { protected function execute() { // validate params, this also sorts the params properly, we need the correct order in the next part $params = call_user_func(array($this->function->classname, 'validate_parameters'), $this->function->parameters_desc, $this->parameters); + $params = array_values($params); + + // Allow any Moodle plugin a chance to override this call. This is a convenient spot to + // make arbitrary behaviour customisations, for example to affect the mobile app behaviour. + // The overriding plugin could call the 'real' function first and then modify the results, + // or it could do a completely separate thing. + $callbacks = get_plugins_with_function('override_webservice_execution'); + foreach ($callbacks as $plugintype => $plugins) { + foreach ($plugins as $plugin => $callback) { + $result = $callback($this->function, $params); + if ($result !== false) { + // If the callback returns anything other than false, we assume it replaces the + // real function. + $this->returns = $result; + return; + } + } + } // execute - yay! - $this->returns = call_user_func_array(array($this->function->classname, $this->function->methodname), array_values($params)); + $this->returns = call_user_func_array(array($this->function->classname, $this->function->methodname), $params); } /**