function services_method_call in Services 6
Same name and namespace in other branches
- 5 services.module \services_method_call()
- 6.2 services.module \services_method_call()
- 7 services.module \services_method_call()
This is the magic function through which all remote method calls must pass.
2 calls to services_method_call()
- services_admin_browse_test_submit in ./
services_admin_browse.inc - xmlrpc_server_call_wrapper in servers/
xmlrpc_server/ xmlrpc_server.module
File
- ./
services.module, line 252 - @author Services Dev Team
Code
function services_method_call($method_name, $args = array()) {
$method = services_method_get($method_name);
// Check that method exists.
if (empty($method)) {
return services_error(t('Method %name does not exist.', array(
'%name' => $method_name,
)));
}
// Check for missing args and identify if arg is required in the hash.
$hash_parameters = array();
foreach ($method['#args'] as $key => $arg) {
if (!$arg['#optional']) {
if (!is_numeric($args[$key]) and empty($args[$key])) {
return services_error(t('Missing required arguments.'));
}
}
// Key is part of the hash
if ($arg['#signed'] == TRUE && variable_get('services_use_key', TRUE)) {
if (is_numeric($args[$key]) || !empty($args[$key])) {
if (is_array($args[$key]) || is_object($args[$key])) {
$hash_parameters[] = serialize($args[$key]);
}
else {
$hash_parameters[] = $args[$key];
}
}
else {
$hash_parameters[] = '';
}
}
}
if ($method['#key'] and variable_get('services_use_key', TRUE)) {
$hash = array_shift($args);
$domain = array_shift($args);
$timestamp = array_shift($args);
$nonce = array_shift($args);
$expiry_time = $timestamp + variable_get('services_key_expiry', 30);
if ($expiry_time < time()) {
return services_error(t('Token has expired.'));
}
// Still in time but has it been used before
if (db_result(db_query("SELECT count(*) FROM {services_timestamp_nonce}\n WHERE domain = '%s' AND timestamp = %d AND nonce = '%s'", $domain, $timestamp, $nonce))) {
return services_error(t('Token has been used previously for a request.'));
}
else {
db_query("INSERT INTO {services_timestamp_nonce} (domain, timestamp, nonce)\n VALUES ('%s', %d, '%s')", $domain, $timestamp, $nonce);
}
$api_key = db_result(db_query("SELECT kid FROM {services_keys} WHERE domain = '%s'", $domain));
if (!services_validate_key($api_key, $timestamp, $domain, $nonce, $method_name, $hash_parameters, $hash)) {
return services_error(t('Invalid API key.'));
}
}
// Add additonal processing for methods requiring authentication
$session_backup = NULL;
if ($method['#auth'] and variable_get('services_use_sessid', TRUE)) {
$sessid = array_shift($args);
if (empty($sessid)) {
return services_error(t('Invalid sessid.'));
}
$session_backup = services_session_load($sessid);
}
// Load the proper file
if ($file = $method['#file']) {
module_load_include($file['file'], $file['module']);
}
// Check access
$access_arguments = isset($method['#access arguments']) ? $method['#access arguments'] : $args;
// Call default or custom access callback
if (call_user_func_array($method['#access callback'], $access_arguments) != TRUE) {
return services_error(t('Access denied.'));
}
// Change working directory to drupal root to call drupal function,
// then change it back to server module root to handle return.
$server_root = getcwd();
$server_info = services_get_server_info();
if ($server_info) {
chdir($server_info->drupal_path);
}
$result = call_user_func_array($method['#callback'], $args);
if ($server_info) {
chdir($server_root);
}
// Add additonal processing for methods requiring authentication.
if ($session_backup !== NULL) {
services_session_unload($session_backup);
}
return $result;
}