function call($methodname, $args) { Logger::log("XML-RPC call: {$methodname}"); list($methodname, $func_desc, $php_func) = api_get_function_descriptor($methodname); // make sure $args is a 1-elem array containing a hash if (gettype($args) != "array") { api_error("Parameters should be in an array", 'validation_request_wrapper'); } switch ($func_desc['argstyle']) { case 'positional': $arg = array(); $argorder = $func_desc['argorder']; if (count($args) != count($argorder)) { api_error("Incorrect number of arguments; expected " . count($argorder), 'validation_incorrect_number_of_arguments'); } for ($i = 0; $i < count($args); ++$i) { $arg[$argorder[$i]] = $args[$i]; } break; case 'named': if (sizeof($args) != 1) { api_error("You should only send a single parameter in your XML-RPC request: a struct, containing all the required keys.", 'validation_request_wrapper'); } $arg = $args[0]; if (gettype($arg) != "array") { api_error("Expected a single parameter containing an XML-RPC struct, but got a value of type '" . gettype($arg) . "' instead.", 'validation_request_wrapper'); } break; default: api_error("Invalid argument style " . $func_desc['argstyle']); } // var_dump($func_desc['args']); // validate the struct validate_content($arg, array("type" => "hash", "content" => $func_desc['args']), "input to XML-RPC function", "auto"); // call function, capturing any output - which might include errors ob_start("xmlrpc_ob_end"); try { $ret = $php_func($arg); // check output if ($ret['success']) { validate_content($ret, $func_desc['return'], "XML-RPC response - not your fault!", "auto"); } } catch (PAException $e) { $ret = api_err_from_exception($e); Logger::log("An exception occurred in an API call: code " . $e->getCode() . ", message " . $e->getMessage() . "\n" . $e->getTraceAsString(), LOGGER_ERROR); } return $ret; }
function handle_rest_call() { global $api_desc; set_error_handler("rest_error_handler"); $magic = ini_get("magic_quotes_gpc"); $path = explode('/', $_SERVER['PATH_INFO']); while (sizeof($path) && !$path[0]) { array_shift($path); } // get function name $funcname = implode(".", $path); // find function descriptor list($funcname, $func_desc, $php_func) = api_get_function_descriptor($funcname); // check request method if (strtolower($_SERVER['REQUEST_METHOD']) != $func_desc['type']) { api_error("Request method " . $_SERVER['REQUEST_METHOD'] . " is incorrect for this function; " . strtoupper($func_desc['type']) . " is required.", 'invalid_request_method'); } // check and parse input $args_desc = $func_desc['args']; $args = array(); foreach ($args_desc as $arg_name => $arg_desc) { // get value $v = @$_REQUEST[$arg_name]; if ($v === NULL) { continue; } // missing keys will be detected during validation // massage it into required type $arg_type = $arg_desc['type']; switch ($arg_type) { case 'string': case 'enum': if ($magic) { $v = stripslashes($v); } break; case 'boolean': switch ($v) { case 'true': $v = TRUE; break; case 'false': $v = FALSE; break; default: api_error("Invalid boolean value '{$v}' (must be 'true' or 'false') passed as argument {$arg_name} to function {$funcname}", "validation_invalid_value"); } break; case 'int': $v = intval($v); break; case 'float': $v = floatval($v); break; default: api_error("Argument type '{$arg_type}' not supported in REST mode"); } // and store $args[$arg_name] = $v; } // validate input validate_content($args, array("type" => "hash", "content" => $func_desc['args']), "REST input", "auto"); // call function try { $ret = $php_func($args); // check output type if (gettype($ret) != 'array') { api_error("Returned data from {$php_func} should be an array, but received " . gettype($ret) . " instead."); } $validate = TRUE; if ($path[0] == 'peopleaggregator') { if (!array_key_exists("success", $ret)) { api_error("Missing 'success' field in returned data from {$php_func}."); } if (!$ret['success']) { $validate = FALSE; } } // check output if ($validate) { validate_content($ret, $func_desc['return'], "REST response", "auto", true); } } catch (PAException $e) { $ret = api_err_from_exception($e); Logger::log("An exception occurred in an API call: code " . $e->getCode() . ", message " . $e->getMessage() . "\n" . $e->getTraceAsString(), LOGGER_ERROR); } // if we got this var, it validates return array($ret, $func_desc); }