public static function handleInvoke(Request $request, $targetObject, $function, &$arg) { $namedObject = $arg[0]; $source = $namedObject->defaultAdapt()->source; $operation = $namedObject->defaultAdapt()->operation; $bodys = $namedObject->defaultAdapt()->body->getBody(); $arguments = array(); foreach ($bodys as $body) { $arguments[] = $body->defaultAdapt(); } $arguments = unserialize(str_replace('s:6:"userid";', 's:3:"uid";', serialize($arguments))); $result = services_method_call($source . "." . $operation, $arguments); $result = unserialize(str_replace('s:3:"uid";', 's:6:"userid";', serialize($result))); return $result; }
public function handle() { //A method is required, no matter what if (empty($this->method_name)) { return $this->error(JSONRPC_ERROR_REQUEST, t("The received JSON not a valid JSON-RPC Request")); } //Find the method $methods = services_get_all(); $args = array(); foreach ($methods as $method) { if ($method['#method'] == $this->method_name) { $this->method = $method; break; } } if (!isset($this->method)) { // No method found is a fatal error return $this->error(JSONRPC_ERROR_PROCEDURE_NOT_FOUND, t("Invalid method @method", array('@method' => $request))); } //If needed, check if parameters can be omitted $arg_count = count($this->method['#args']); if (!isset($this->params)) { for ($i = 0; $i < $arg_count; $i++) { $arg = $this->method['#args'][$i]; if (!$arg['#optional']) { if (empty($this->in['params'])) { return $this->error(JSONRPC_ERROR_PARAMS, t("No parameters recieved, the method '@method' has required parameters.", array('@method' => $this->method_name))); } else { return $this->error(JSONRPC_ERROR_PARSE, t("Missing parameters, the likely reason is malformed json, the method '@method' has required parameters.", array('@method' => $this->method_name))); } } } } // Map parameters to arguments, the 1.1 draft is more generous than the 2.0 proposal when // it comes to parameter passing. 1.1-d allows mixed positional and named parameters while // 2.0-p forces the client to choose between the two. // // 2.0 proposal on parameters: http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal#parameters-positional-and-named // 1.1 draft on parameters: http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html#NamedPositionalParameters if ($this->array_is_assoc($this->params)) { $this->args = array(); //Create a assoc array to look up indexes for parameter names $arg_dict = array(); for ($i = 0; $i < $arg_count; $i++) { $arg = $this->method['#args'][$i]; $arg_dict[$arg['#name']] = $i; } foreach ($this->params as $key => $value) { if ($this->major_version == 1 && preg_match('/^\\d+$/', $key)) { //A positional argument (only allowed in v1.1 calls) if ($key >= $arg_count) { //Index outside bounds return $this->error(JSONRPC_ERROR_PARAMS, t("Positional parameter with a position outside the bounds (index: @index) recieved", array('@index' => $key))); } else { $this->args[intval($key)] = $value; } } else { //Associative key if (!isset($arg_dict[$key])) { //Unknown parameter return $this->error(JSONRPC_ERROR_PARAMS, t("Unknown named parameter '@name' recieved", array('@name' => $key))); } else { $this->args[$arg_dict[$key]] = $value; } } } } else { //Non associative arrays can be mapped directly $param_count = count($this->params); if ($param_count > $arg_count) { return $this->error(JSONRPC_ERROR_PARAMS, t("Too many arguments recieved, the method '@method' only takes '@num' argument(s)", array('@method' => $this->method_name, '@num' => $arg_count))); } $this->args = $this->params; } //Validate arguments for ($i = 0; $i < $arg_count; $i++) { $val = $this->args[$i]; $arg = $this->method['#args'][$i]; if (isset($val)) { //If we have data //Only array-type parameters accepts arrays if (is_array($val) && $arg['#type'] != 'array') { return $this->error_wrong_type($arg, 'array'); } else { if (($arg['#type'] == 'int' || $arg['#type'] == 'float') && !is_numeric($val)) { return $this->error_wrong_type($arg, 'string'); } } } else { if (!$arg['#optional']) { //Trigger error if a required parameter is missing return $this->error(JSONRPC_ERROR_PARAMS, t("Argument '@name' is required but was not recieved", array('@name' => $arg['#name']))); } } } // We are returning JSON, so tell the browser. drupal_set_header('Content-Type: application/json; charset=utf-8'); //Call service method try { $result = services_method_call($this->method['#method'], $this->args); if (is_array($result) && isset($result['#error']) && $result['#error'] === TRUE) { return $this->error(JSONRPC_ERROR_INTERNAL_ERROR, $result['#message']); } else { return $this->result($result); } } catch (Exception $e) { return $this->error(JSONRPC_ERROR_INTERNAL_ERROR, $e->getMessage()); } }