Example #1
0
 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;
 }
Example #2
0
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);
}