diff --git a/auth/services_keyauth/services_keyauth.admin.inc b/auth/services_keyauth/services_keyauth.admin.inc
index 1ebf892..c7ffa40 100644
--- a/auth/services_keyauth/services_keyauth.admin.inc
+++ b/auth/services_keyauth/services_keyauth.admin.inc
@@ -1,5 +1,5 @@
t('External domain allowed to use this key.'),
'#required' => TRUE,
);
-
+
$methods = services_get_all();
foreach ($methods as $method) {
- $form_methods[$method['#method']] = $method['#method'];
+ $form_methods[$method['method']] = $method['method'];
}
$form['method_access'] = array(
@@ -128,7 +128,7 @@ function services_keyauth_admin_keys_save(&$key) {
db_query("INSERT INTO {services_key_permissions} (kid, method) VALUES ('%s', '%s')", $key['kid'], $value);
}
}
- return $return;
+ return $return;
}
function services_keyauth_admin_keys_delete($kid) {
diff --git a/auth/services_keyauth/services_keyauth.inc b/auth/services_keyauth/services_keyauth.inc
index 5629f0c..3fb7ef4 100644
--- a/auth/services_keyauth/services_keyauth.inc
+++ b/auth/services_keyauth/services_keyauth.inc
@@ -1,5 +1,5 @@
'checkbox',
'#title' => t('Use keys'),
'#default_value' => variable_get('services_use_key', TRUE),
- '#description' => t('When enabled all method calls need to provide a validation token to autheciate themselves with the server.'),
+ '#description' => t('When enabled all method calls need to provide a validation token to authenticate themselves with the server.'),
);
$form['services_key_expiry'] = array(
'#type' => 'textfield',
@@ -25,7 +25,7 @@ function _services_keyauth_security_settings() {
'#type' => 'checkbox',
'#title' => t('Use sessid'),
'#default_value' => variable_get('services_use_sessid', TRUE),
- '#description' => t('When enabled, all method calls must include a valid sessid. Only disable this setting if the application will user browser-based cookies.')
+ '#description' => t('When enabled, all method calls must include a valid sessid. Only disable this setting if the application will use browser-based cookies.')
);
return $form;
}
@@ -51,76 +51,74 @@ function _services_keyauth_alter_methods(&$methods) {
// sessid arg
$arg_sessid = array(
- '#name' => 'sessid',
- '#type' => 'string',
- '#description' => t('A valid sessid.'),
+ 'name' => 'sessid',
+ 'type' => 'string',
+ 'description' => t('A valid sessid.'),
);
$arg_domain_time_stamp = array(
- '#name' => 'domain_time_stamp',
- '#type' => 'string',
- '#description' => t('Time stamp used to hash key.'),
+ 'name' => 'domain_time_stamp',
+ 'type' => 'string',
+ 'description' => t('Time stamp used to hash key.'),
);
$arg_nonce = array(
- '#name' => 'nonce',
- '#type' => 'string',
- '#description' => t('One time use nonce also used hash key.'),
+ 'name' => 'nonce',
+ 'type' => 'string',
+ 'description' => t('One time use nonce also used hash key.'),
);
// domain arg
$arg_domain_name = array(
- '#name' => 'domain_name',
- '#type' => 'string',
- '#description' => t('A valid domain for the API key.'),
+ 'name' => 'domain_name',
+ 'type' => 'string',
+ 'description' => t('A valid domain for the API key.'),
);
// api_key arg
$arg_api_key = array(
- '#name' => 'hash',
- '#type' => 'string',
- '#description' => t('A valid API key.'),
+ 'name' => 'hash',
+ 'type' => 'string',
+ 'description' => t('A valid API key.'),
);
foreach ($methods as $key => &$method) {
// set method defaults
- switch ($method['#method']) {
+ switch ($method['method']) {
case 'system.connect':
- case 'search.nodes':
- case 'search.content':
- case 'search.users':
- $method['#key'] = FALSE;
- $method['#auth'] = FALSE;
+ $method['key'] = FALSE;
+ $method['auth'] = FALSE;
break;
default:
- $method['#key'] = TRUE;
- $method['#auth'] = TRUE;
+ $method['key'] = isset($method['key']) ? FALSE : TRUE;
+ $method['auth'] = isset($method['auth']) ? FALSE : TRUE;
+ break;
}
-
- if ($method['#auth'] && variable_get('services_use_sessid', TRUE)) {
- array_unshift($method['#args'], $arg_sessid);
+
+ if ($method['auth'] && variable_get('services_use_sessid', TRUE)) {
+ array_unshift($method['args'], $arg_sessid);
}
- if ($method['#key'] && variable_get('services_use_key', TRUE)) {
- array_unshift($method['#args'], $arg_nonce);
- array_unshift($method['#args'], $arg_domain_time_stamp);
- array_unshift($method['#args'], $arg_domain_name);
- array_unshift($method['#args'], $arg_api_key);
+ if ($method['key'] && variable_get('services_use_key', TRUE)) {
+ array_unshift($method['args'], $arg_nonce);
+ array_unshift($method['args'], $arg_domain_time_stamp);
+ array_unshift($method['args'], $arg_domain_name);
+ array_unshift($method['args'], $arg_api_key);
}
}
}
function _services_keyauth_alter_browse_form(&$form, $method) {
- foreach ($method['#args'] as $key => $arg) {
- switch ($arg['#name']) {
+ foreach ($method['args'] as $key => $arg) {
+ switch ($arg['name']) {
case 'hash':
$form['arg'][$key] = array(
'#title' => 'Hash',
'#type' => 'textfield',
'#value' => t('Gets generated after form submission'),
'#disabled' => TRUE
- );
+ );
break;
case 'sessid':
$form['arg'][$key]['#default_value'] = session_id();
@@ -130,11 +128,11 @@ function _services_keyauth_alter_browse_form(&$form, $method) {
break;
case 'domain_time_stamp':
$form['arg'][$key] = array(
- '#title' => 'Timestamp',
- '#type' => 'textfield',
- '#value' => t('Gets generated after form submission'),
- '#disabled' => TRUE
- );
+ '#title' => 'Timestamp',
+ '#type' => 'textfield',
+ '#value' => t('Gets generated after form submission'),
+ '#disabled' => TRUE
+ );
break;
case 'nonce':
$form['arg'][$key]['#default_value'] = user_password();
@@ -144,7 +142,7 @@ function _services_keyauth_alter_browse_form(&$form, $method) {
}
function _services_keyauth_authenticate_call($method, $method_name, &$args) {
- if ($method['#key'] && variable_get('services_use_key', TRUE)) {
+ if ($method['key'] && variable_get('services_use_key', TRUE)) {
$hash = array_shift($args);
$domain = array_shift($args);
$timestamp = array_shift($args);
@@ -160,7 +158,7 @@ function _services_keyauth_authenticate_call($method, $method_name, &$args) {
if (db_result(db_query("SELECT count(*) FROM {services_timestamp_nonce}
WHERE domain = '%s' AND nonce = '%s'",
$domain, $nonce))) {
- return services_error(t('Token has been used previously for a request. Re-try with another nonce key.', 401));
+ return services_error(t('Token has been used previously for a request. Re-try with another nonce key.'), 401);
}
else{
db_query("INSERT INTO {services_timestamp_nonce} (domain, timestamp, nonce)
@@ -173,8 +171,8 @@ function _services_keyauth_authenticate_call($method, $method_name, &$args) {
if ($hash != services_get_hash($timestamp, $domain, $nonce, $method, $args)) {
return services_error(t('Invalid API key.'), 401);
}
-
- if (!db_result(db_query("SELECT COUNT(*) FROM {services_key_permissions}
+
+ if (!db_result(db_query("SELECT COUNT(*) FROM {services_key_permissions}
WHERE kid = '%s' AND method = '%s'", $api_key, $method_name))) {
return services_error(t('Access denied.'), 401);
}
@@ -182,7 +180,7 @@ function _services_keyauth_authenticate_call($method, $method_name, &$args) {
// Add additonal processing for methods requiring session
$session_backup = NULL;
- if ($method['#auth'] && variable_get('services_use_sessid', TRUE)) {
+ if ($method['auth'] && variable_get('services_use_sessid', TRUE)) {
$sessid = array_shift($args);
if (empty($sessid)) {
return t('Invalid sessid.');
@@ -192,9 +190,9 @@ function _services_keyauth_authenticate_call($method, $method_name, &$args) {
}
function _services_keyauth_alter_browse_form_submit($method, &$args) {
- if ($method['#key'] && variable_get('services_use_key', TRUE)) {
+ if ($method['key'] && variable_get('services_use_key', TRUE)) {
$args_stripped = $args;
-
+
for ($i = 1; $i <= 4; $i++) {
array_shift($args_stripped);
}
diff --git a/auth/services_keyauth/services_keyauth.install b/auth/services_keyauth/services_keyauth.install
index 64bcb31..74c993b 100644
--- a/auth/services_keyauth/services_keyauth.install
+++ b/auth/services_keyauth/services_keyauth.install
@@ -1,10 +1,11 @@
array('kid'),
'method' => array('method'),
),
- 'unique key' => array('key_method' => array('kid','method')),
+ 'unique key' => array('key_method' => array('kid', 'method')),
);
return $schema;
}
-function _services_key_auth_permissions (&$update) {
+function _services_key_auth_permissions(&$update) {
$schema['services_key_permissions'] = array(
'description' => t('Stores services method\'s access rights on a per API key basis.'),
'fields' => array(
@@ -116,7 +117,7 @@ function _services_key_auth_permissions (&$update) {
'api_key' => array('kid'),
'method' => array('method'),
),
- 'unique key' => array('key_method' => array('kid','method')),
+ 'unique key' => array('key_method' => array('kid', 'method')),
);
db_create_table($update, 'services_key_permissions', $schema['services_key_permissions']);
@@ -178,7 +179,7 @@ function services_keyauth_update_6004() {
function services_keyauth_update_6005() {
$update = array();
-
+
// A table might fail to exist in certain circumstances due to an issue with the install.
if (!db_table_exists('services_key_permissions')) {
_services_key_auth_permissions($update);
diff --git a/auth/services_keyauth/services_keyauth.module b/auth/services_keyauth/services_keyauth.module
index e18478a..d574873 100644
--- a/auth/services_keyauth/services_keyauth.module
+++ b/auth/services_keyauth/services_keyauth.module
@@ -1,7 +1,6 @@
'services_keyauth.inc',
- '#title' => t('Key authentication'),
- '#description' => t('The default key-based authentication'),
+ 'file' => 'services_keyauth.inc',
+ 'title' => t('Key authentication'),
+ 'description' => t('The default key-based authentication'),
'security_settings' => '_services_keyauth_security_settings',
'security_settings_validate' => '_services_keyauth_security_settings_validate',
'security_settings_submit' => '_services_keyauth_security_settings_submit',
@@ -94,11 +93,11 @@ function services_keyauth_menu() {
}
function services_get_hash($timestamp, $domain, $nonce, $method, $args) {
- $hash_parameters = array($timestamp, $domain, $nonce, $method['#method']);
- foreach ($method['#args'] as $key => $arg) {
- if ($arg['#signed'] == TRUE) {
+ $hash_parameters = array($timestamp, $domain, $nonce, $method['method']);
+ foreach ($method['args'] as $key => $arg) {
+ if ($arg['signed'] == TRUE) {
if (is_numeric($args[$key]) || !empty($args[$key])) {
- if (is_array($args[$key]) || is_object($args[$key])){
+ if (is_array($args[$key]) || is_object($args[$key])) {
$hash_parameters[] = serialize($args[$key]);
}
else{
diff --git a/servers/xmlrpc_server/xmlrpc_server.module b/servers/xmlrpc_server/xmlrpc_server.module
index 6d94f44..200ba34 100644
--- a/servers/xmlrpc_server/xmlrpc_server.module
+++ b/servers/xmlrpc_server/xmlrpc_server.module
@@ -1,7 +1,6 @@
''
),
),
- 'indexes' => array(
- 'timestamp' => array('timestamp'),
- ),
+ 'indexes' => array(
+ 'timestamp' => array('timestamp'),
+ ),
'primary key' => array('nonce'),
);
$update = array();
diff --git a/services.module b/services.module
index d44a28f..3077e86 100644
--- a/services.module
+++ b/services.module
@@ -1,10 +1,11 @@
'."\n";
$output .= ' '."\n";
$output .= ' '."\n";
- $keys = services_get_keys();
+ $keys = (function_exists('services_keyauth_get_keys')) ? services_keyauth_get_keys() : array();
foreach ($keys as $key) {
if (!empty($key->domain)) {
@@ -155,6 +158,13 @@ function services_crossdomain_xml() {
services_xml_output($output);
}
+/**
+ * Helper function for sending xml output. This method outputs a xml
+ * processing instruction and the necessary headers and then exits.
+ *
+ * @param string $xml
+ * @return void
+ */
function services_xml_output($xml) {
$xml = ''."\n". $xml;
header('Connection: close');
@@ -165,6 +175,15 @@ function services_xml_output($xml) {
exit;
}
+/**
+ * Sets information about which server implementation that is used for the
+ * call.
+ *
+ * @param string $module
+ * The server module that's handling the call.
+ * @return object
+ * Server info object.
+ */
function services_set_server_info($module) {
$server_info = new stdClass();
$server_info->module = $module;
@@ -172,6 +191,15 @@ function services_set_server_info($module) {
return services_get_server_info($server_info);
}
+/**
+ * Returns or sets the server info object.
+ *
+ * @param object $server_info
+ * Optional. Pass a object to set the server info object. Omit to just
+ * retrieve the server info.
+ * @return object
+ * Server info object.
+ */
function services_get_server_info($server_info = NULL) {
static $info;
if (!$info && $server_info) {
@@ -180,12 +208,24 @@ function services_get_server_info($server_info = NULL) {
return $info;
}
-/**
- * Prepare an error message for returning to the server.
- */
+ /**
+ * Prepare an error message for returning to the server.
+ *
+ * @param string $message
+ * The error message.
+ * @param int $code
+ * Optional. A error code, these should map as closely to the applicable
+ * http error codes as closely as possible.
+ * @param Exception $exception
+ * Optional. The exception was thrown (if any) when the error occured.
+ * @return mixed
+ */
function services_error($message, $code = 0, $exception = NULL) {
$server_info = services_get_server_info();
+ // Allow external modules to log this error
+ module_invoke_all('services_error', $message, $code, $exception);
+
// Look for custom error handling function.
// Should be defined in each server module.
if ($server_info && module_hook($server_info->module, 'server_error')) {
@@ -214,8 +254,8 @@ function services_auth_info($property = NULL, $module = NULL) {
$module = $module ? $module : variable_get('services_auth_module', '');
if (!isset($info[$module])) {
- if (!empty($module) && module_exists($module) && is_callable($module . '_authentication_info')) {
- $info[$module] = call_user_func($module . '_authentication_info');
+ if (!empty($module) && module_exists($module) && is_callable($module .'_authentication_info')) {
+ $info[$module] = call_user_func($module .'_authentication_info');
}
else {
$info[$module] = FALSE;
@@ -231,13 +271,26 @@ function services_auth_info($property = NULL, $module = NULL) {
return $info[$module];
}
+/**
+ * Invokes a method for the configured authentication module.
+ *
+ * @param string $method
+ * The method to call.
+ * @param mixed $arg1
+ * Optional. First argument.
+ * @param mixed $arg2
+ * Optional. Second argument.
+ * @param mixed $arg3
+ * Optional. Third argument.
+ * @return mixed
+ */
function services_auth_invoke($method, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL) {
$module = variable_get('services_auth_module', '');
// Get information about the current auth module
$func = services_auth_info($method, $module);
if ($func) {
- if ($file = services_auth_info('#file')) {
- require_once(drupal_get_path('module', $module) . '/' . $file);
+ if ($file = services_auth_info('file')) {
+ require_once(drupal_get_path('module', $module) .'/'. $file);
}
if (is_callable($func)) {
@@ -252,12 +305,27 @@ function services_auth_invoke($method, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NU
}
}
+/**
+ * Invokes a method for the given authentication module.
+ *
+ * @param string $module
+ * The authentication module to call the method for.
+ * @param string $method
+ * The method to call.
+ * @param mixed $arg1
+ * Optional. First argument.
+ * @param mixed $arg2
+ * Optional. Second argument.
+ * @param mixed $arg3
+ * Optional. Third argument.
+ * @return mixed
+ */
function services_auth_invoke_custom($module, $method, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL) {
// Get information about the auth module
$func = services_auth_info($method, $module);
if ($func) {
- if ($file = services_auth_info('#file', $module)) {
- require_once(drupal_get_path('module', $module) . '/' . $file);
+ if ($file = services_auth_info('file', $module)) {
+ require_once(drupal_get_path('module', $module) .'/'. $file);
}
if (is_callable($func)) {
@@ -273,10 +341,22 @@ function services_auth_invoke_custom($module, $method, &$arg1 = NULL, &$arg2 = N
}
/**
- * This is the magic function through which all remote method calls must pass.
+ * Invokes a services method.
+ *
+ * @param mixed $method_name
+ * The method name or a method definition array.
+ * @param array $args
+ * Optional. An array containing arguments for the method. These arguments are not
+ * matched by name but by position.
+ * @param bool $browsing
+ * Optional. Whether the call was made by the services browser or not.
+ * @return mixed
*/
function services_method_call($method_name, $args = array(), $browsing = FALSE) {
- if (is_array($method_name) && isset($method_name['#callback'])) {
+ // Allow external modules to log the results of this service call
+ module_invoke_all('services_method_call', $method_name, $args, $browsing);
+
+ if (is_array($method_name) && isset($method_name['callback'])) {
$method = $method_name;
}
else {
@@ -290,8 +370,8 @@ function services_method_call($method_name, $args = array(), $browsing = FALSE)
// Check for missing args
$hash_parameters = array();
- foreach ($method['#args'] as $key => $arg) {
- if (!$arg['#optional']) {
+ foreach ($method['args'] as $key => $arg) {
+ if (!$arg['optional']) {
if (!isset($args[$key]) && !is_array($args[$key]) && !is_bool($args[$key])) {
return services_error(t('Missing required arguments.'), 406);
}
@@ -299,7 +379,7 @@ function services_method_call($method_name, $args = array(), $browsing = FALSE)
}
// Check authentication
- if ($auth_error = services_auth_invoke('authenticate_call', $method, $method_name, $args)) {
+ if ($method['auth'] && $auth_error = services_auth_invoke('authenticate_call', $method, $method_name, $args)) {
if ($browsing) {
drupal_set_message(t('Authentication failed: !message', array('!message' => $auth_error)), 'error');
}
@@ -308,15 +388,17 @@ function services_method_call($method_name, $args = array(), $browsing = FALSE)
}
}
- // Load the proper file
- if ($file = $method['#file']) {
- module_load_include($file['file'], $file['module']);
+ // Load the proper file.
+ if ($file = $method['file']) {
+ // Initialize file name if not given.
+ $file += array('file name' => '');
+ module_load_include($file['file'], $file['module'], $file['file name']);
}
// Construct access arguments array
- if (isset($method['#access arguments'])) {
- $access_arguments = $method['#access arguments'];
- if (isset($method['#access arguments append']) && $method['#access arguments append']) {
+ if (isset($method['access arguments'])) {
+ $access_arguments = $method['access arguments'];
+ if (isset($method['access arguments append']) && $method['access arguments append']) {
$access_arguments[] = $args;
}
}
@@ -326,7 +408,7 @@ function services_method_call($method_name, $args = array(), $browsing = FALSE)
}
// Call default or custom access callback
- if (call_user_func_array($method['#access callback'], $access_arguments) != TRUE) {
+ if (call_user_func_array($method['access callback'], $access_arguments) != TRUE) {
return services_error(t('Access denied'), 401);
}
@@ -337,11 +419,14 @@ function services_method_call($method_name, $args = array(), $browsing = FALSE)
if ($server_info) {
chdir($server_info->drupal_path);
}
- $result = call_user_func_array($method['#callback'], $args);
+ $result = call_user_func_array($method['callback'], $args);
if ($server_info) {
chdir($server_root);
}
+ // Allow external modules to log the results of this service call
+ module_invoke_all('services_method_call_results', $method_name, $args, $browsing, $result);
+
return $result;
}
@@ -388,8 +473,8 @@ function services_resource_uri($path) {
* @return array
* An array containing all resources.
*/
-function services_get_all_resources($include_services = TRUE) {
- $cache_key = 'services:resources' . ($include_services?'_with_services':'');
+function services_get_all_resources($include_services = TRUE, $reset = FALSE) {
+ $cache_key = 'services:resources'. ($include_services?'_with_services':'');
if (!$reset && ($cache = cache_get($cache_key)) && isset($cache->data)) {
return $cache->data;
@@ -397,21 +482,22 @@ function services_get_all_resources($include_services = TRUE) {
else {
$resources = module_invoke_all('service_resource');
drupal_alter('service_resources', $resources);
+ services_strip_hashes($resources);
$controllers = array();
services_process_resources($resources, $controllers);
foreach ($controllers as &$controller) {
- if (!isset($controller['#access callback'])) {
- $controller['#access callback'] = 'services_access_menu';
+ if (!isset($controller['access callback'])) {
+ $controller['access callback'] = 'services_access_menu';
}
- if (!isset($controller['#auth'])) {
- $controller['#auth'] = TRUE;
+ if (!isset($controller['auth'])) {
+ $controller['auth'] = TRUE;
}
- if (!isset($controller['#key'])) {
- $controller['#key'] = TRUE;
+ if (!isset($controller['key'])) {
+ $controller['key'] = TRUE;
}
}
@@ -434,6 +520,36 @@ function services_get_all_resources($include_services = TRUE) {
}
}
+/**
+ * Implementation of hook_form_alter().
+ */
+function services_form_alter(&$form, $form_state, $form_id) {
+ if ($form_id == 'system_modules') {
+ // Add our own submit hook to clear cache
+ $form['#submit'][] = 'services_system_modules_submit';
+ }
+}
+
+/**
+ * Submit handler for the system_modules form that clears the services cache.
+ */
+function services_system_modules_submit($form, &$form_state) {
+ // Reset services cache
+ services_get_all(TRUE, TRUE);
+}
+
+/**
+ * Processes the passed resources and adds all the controllers to the
+ * controller array.
+ *
+ * @param array $resources
+ * The resources that should be processed.
+ * @param string $controllers
+ * An array (passed by reference) that will be populated with the controllers
+ * of the passed resources.
+ * @param string $path
+ * Optional. Deprecated.
+ */
function services_process_resources(&$resources, &$controllers, $path=array()) {
foreach ($resources as $name => &$resource) {
if (drupal_substr($name, 0, 1) != '#') {
@@ -442,60 +558,80 @@ function services_process_resources(&$resources, &$controllers, $path=array()) {
}
}
+/**
+ * Processes a single resource and adds it's controllers to the controllers
+ * array.
+ *
+ * @param string $name
+ * The name of the resource.
+ * @param array $resource
+ * The resource definition.
+ * @param array $controllers
+ * An array (passed by reference) that will be populated with the controllers
+ * of the passed resources.
+ * @return void
+ */
function _services_process_resource($name, &$resource, &$controllers) {
$path = join($name, '/');
- $resource['#name'] = $path;
+ $resource['name'] = $path;
- $keys = array('#retrieve','#create','#update','#delete');
+ $keys = array('retrieve', 'create', 'update', 'delete');
foreach ($keys as $key) {
if (isset($resource[$key])) {
- $controllers[$path . '/' . $key] = &$resource[$key];
+ $controllers[$path .'/'. $key] = &$resource[$key];
}
}
- if (isset($resource['#index'])) {
- $controllers[$path . '/#index'] = &$resource['#index'];
+ if (isset($resource['index'])) {
+ $controllers[$path .'/index'] = &$resource['index'];
}
- if (isset($resource['#relationships'])) {
- foreach ($resource['#relationships'] as $relname => $rel) {
+ if (isset($resource['relationships'])) {
+ foreach ($resource['relationships'] as $relname => $rel) {
// Run some inheritance logic
- if (isset($resource['#retrieve'])) {
- if (empty($rel['#args']) || $rel['#args'][0]['#name'] !== $resource['#retrieve']['#args'][0]['#name']) {
- array_unshift($rel['#args'], $resource['#retrieve']['#args'][0]);
+ if (isset($resource['retrieve'])) {
+ if (empty($rel['args']) || $rel['args'][0]['name'] !== $resource['retrieve']['args'][0]['name']) {
+ array_unshift($rel['args'], $resource['retrieve']['args'][0]);
}
- $resource['#relationships'][$relname] = array_merge($resource['#retrieve'], $rel);
+ $resource['relationships'][$relname] = array_merge($resource['retrieve'], $rel);
}
- $controllers[$path . '/relationship/' . $relname] = &$resource['#relationships'][$relname];
+ $controllers[$path .'/relationship/'. $relname] = &$resource['relationships'][$relname];
}
}
- if (isset($resource['#actions'])) {
- foreach ($resource['#actions'] as $actname => $act) {
+ if (isset($resource['actions'])) {
+ foreach ($resource['actions'] as $actname => $act) {
// Run some inheritance logic
- if (isset($resource['#update'])) {
- $up = $resource['#update'];
- unset($up['#args']);
- $resource['#actions'][$actname] = array_merge($up, $act);
+ if (isset($resource['update'])) {
+ $up = $resource['update'];
+ unset($up['args']);
+ $resource['actions'][$actname] = array_merge($up, $act);
}
- $controllers[$path . '/action/' . $actname] = &$resource['#actions'][$actname];
+ $controllers[$path .'/action/'. $actname] = &$resource['actions'][$actname];
}
}
- if (isset($resource['#targeted actions'])) {
- foreach ($resource['#targeted actions'] as $actname => $act) {
+ if (isset($resource['targeted actions'])) {
+ foreach ($resource['targeted actions'] as $actname => $act) {
// Run some inheritance logic
- if (isset($resource['#update'])) {
- if (empty($act['#args']) || $act['#args'][0]['#name'] !== $resource['#update']['#args'][0]['#name']) {
- array_unshift($act['#args'], $resource['#update']['#args'][0]);
+ if (isset($resource['update'])) {
+ if (empty($act['args']) || $act['args'][0]['name'] !== $resource['update']['args'][0]['name']) {
+ array_unshift($act['args'], $resource['update']['args'][0]);
}
- $resource['#targeted actions'][$actname] = array_merge($resource['#update'], $act);
+ $resource['targeted actions'][$actname] = array_merge($resource['update'], $act);
}
- $controllers[$path . '/targeted_action/' . $actname] = &$resource['#actions'][$actname];
+ $controllers[$path .'/targeted_action/'. $actname] = &$resource['actions'][$actname];
}
}
}
+/**
+ * Should be removed. This code doesn't seem to be used anywhere.
+ *
+ * @param string $perm
+ * The permission to check for.
+ * @return bool
+ */
function services_delegate_access($perm) {
return services_auth_invoke('delegate_access', $perm);
}
@@ -510,42 +646,43 @@ function services_delegate_access($perm) {
* @return array
* An array containing all services and thir methods
*/
-function services_get_all($include_resources = TRUE) {
- $cache_key = 'services:methods' . ($include_resources?'_with_resources':'');
+function services_get_all($include_resources = TRUE, $reset = FALSE) {
+ $cache_key = 'services:methods'. ($include_resources?'_with_resources':'');
- if (($cache = cache_get($cache_key)) && isset($cache->data)) {
+ if (!$reset && ($cache = cache_get($cache_key)) && isset($cache->data)) {
return $cache->data;
}
else {
$methods = module_invoke_all('service');
+ services_strip_hashes($methods);
foreach ($methods as $key => $method) {
- if (!isset($methods[$key]['#access callback'])) {
- $methods[$key]['#access callback'] = 'services_access_menu';
+ if (!isset($methods[$key]['access callback'])) {
+ $methods[$key]['access callback'] = 'services_access_menu';
}
- if (!isset($methods[$key]['#args'])) {
- $methods[$key]['#args'] = array();
+ if (!isset($methods[$key]['args'])) {
+ $methods[$key]['args'] = array();
}
// set defaults for args
- foreach ($methods[$key]['#args'] as $arg_key => $arg) {
+ foreach ($methods[$key]['args'] as $arg_key => $arg) {
if (is_array($arg)) {
- if (!isset($arg['#optional'])) {
- $methods[$key]['#args'][$arg_key]['#optional'] = FALSE;
+ if (!isset($arg['optional'])) {
+ $methods[$key]['args'][$arg_key]['optional'] = FALSE;
}
}
else {
$arr_arg = array();
- $arr_arg['#name'] = t('unnamed');
- $arr_arg['#type'] = $arg;
- $arr_arg['#description'] = t('No description given.');
- $arr_arg['#optional'] = FALSE;
- $methods[$key]['#args'][$arg_key] = $arr_arg;
+ $arr_arg['name'] = t('unnamed');
+ $arr_arg['type'] = $arg;
+ $arr_arg['description'] = t('No description given.');
+ $arr_arg['optional'] = FALSE;
+ $methods[$key]['args'][$arg_key] = $arr_arg;
}
}
- reset($methods[$key]['#args']);
+ reset($methods[$key]['args']);
}
// Allow auth module to alter the methods
@@ -553,7 +690,7 @@ function services_get_all($include_resources = TRUE) {
// Add resources if wanted
if ($include_resources) {
- $resources = services_get_all_resources(FALSE);
+ $resources = services_get_all_resources(FALSE, $reset);
// Include the file that has the necessary functions for translating
// resources to method calls.
@@ -562,7 +699,7 @@ function services_get_all($include_resources = TRUE) {
// Translate all resources
foreach ($resources as $name => $def) {
- foreach(_services_resource_as_services($def) as $method) {
+ foreach (_services_resource_as_services($def) as $method) {
$methods[] = $method;
}
}
@@ -582,11 +719,19 @@ function services_method_load($method) {
return isset($method) ? $method : FALSE;
}
+/**
+ * Get's the definition of a method.
+ *
+ * @param string $method_name
+ * The name of the method to get the definition for.
+ * @return array
+ * The method definition.
+ */
function services_method_get($method_name) {
static $method_cache;
if (!isset($method_cache[$method_name])) {
foreach (services_get_all() as $method) {
- if ($method_name == $method['#method']) {
+ if ($method_name == $method['method']) {
$method_cache[$method_name] = $method;
break;
}
@@ -596,7 +741,34 @@ function services_method_get($method_name) {
}
/**
- * Make any changes we might want to make to node.
+ * Cleanup function to remove unnecessary hashes from service definitions.
+ *
+ * @param array $array
+ * A service definition or an array of service definitions.
+ * @return void
+ */
+function services_strip_hashes(&$array) {
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ services_strip_hashes($array[$key]);
+ }
+ if (strpos($key, '#') === 0) {
+ $array[substr($key, 1)] = $array[$key];
+ unset($array[$key]);
+ }
+ }
+}
+
+/**
+ * Creates an object that only contains the specified attributes from the node
+ * object.
+ *
+ * @param object $node
+ * The node to get the attributes.
+ * @param array $fields
+ * An array containing the names of the attributes to get.
+ * @return object
+ * An object with the specified attributes.
*/
function services_node_load($node, $fields = array()) {
if (!isset($node->nid)) {
@@ -688,4 +860,4 @@ function services_session_unload($backup) {
*/
function services_access_menu() {
return TRUE;
-}
\ No newline at end of file
+}
diff --git a/services.resource-translation.inc b/services.resource-translation.inc
index 8b990eb..ecbbc45 100644
--- a/services.resource-translation.inc
+++ b/services.resource-translation.inc
@@ -1,73 +1,101 @@
'create',
- '#delete' => 'delete',
- '#retrieve' => 'retrieve',
- '#update' => 'update',
- '#index' => 'index',
+ 'create' => 'create',
+ 'delete' => 'delete',
+ 'retrieve' => 'retrieve',
+ 'update' => 'update',
+ 'index' => 'index',
), $subcontrollers = array(
- '#relationships' => 'related',
- '#targeted actions' => 'targeted_action',
+ 'relationships' => 'related',
+ 'targeted actions' => 'targeted_action',
);
$methods = array();
- $file = isset($resource['#file']) ? $resource['#file'] : array();
+ $file = isset($resource['file']) ? $resource['file'] : array();
foreach ($controllers as $attr => $name) {
if (isset($resource[$attr])) {
- $methods[] = _services_resource_controller_as_service($resource['#name'], $name, $resource[$attr], $file);
+ $methods[] = _services_resource_controller_as_service($resource['name'], $name, $resource[$attr], $file);
}
}
foreach ($subcontrollers as $attr => $name) {
if (isset($resource[$attr])) {
foreach ($resource[$attr] as $sc_name => $controller) {
- $methods[] = _services_resource_controller_as_service($resource['#name'], $name . '_' . $sc_name, $controller, $file);
+ $methods[] = _services_resource_controller_as_service($resource['name'], $name .'_'. $sc_name, $controller, $file);
}
}
}
- if (isset($resource['#actions'])) {
- foreach ($resource['#actions'] as $sc_name => $controller) {
- $methods[] = _services_resource_controller_as_service($resource['#name'], 'action_' . $sc_name, $controller, $file);
+ if (isset($resource['actions'])) {
+ foreach ($resource['actions'] as $sc_name => $controller) {
+ $methods[] = _services_resource_controller_as_service($resource['name'], 'action_'. $sc_name, $controller, $file);
}
}
return $methods;
}
+/**
+ * Helper function for _services_resource_as_services() that turns a resource
+ * controller into a service method.
+ */
function _services_resource_controller_as_service($resource, $name, $controller, $file) {
$method = array_merge($controller, array(
- '#method' => $resource . '_resource.' . $name,
+ 'method' => $resource .'_resource.'. $name,
));
- if (!empty($file) && !empty($method['#file'])) {
- $method['#file'] = $file;
+ if (!empty($file) && !empty($method['file'])) {
+ $method['file'] = $file;
}
return $method;
}
+/**
+ * Turns an array of services methods into resources where all methods are
+ * added as actions. A 'menu.get'-method would be added as a 'get'-action on
+ * the resource 'service_menu'.
+ *
+ * @param array $services
+ * An array of service methods.
+ * @return array
+ * An array of resource definitions.
+ */
function _services_services_as_resources($services) {
$resources = array();
foreach ($services as $service) {
- $signature = preg_split('/\./', $service['#method']);
+ $signature = preg_split('/\./', $service['method']);
$controller = $service;
- $controller['#args'] = array();
+ $controller['args'] = array();
- foreach($service['#args'] as $arg) {
- $arg['#source'] = array(
- 'data' => $arg['#name'],
+ foreach ($service['args'] as $arg) {
+ $arg['source'] = array(
+ 'data' => $arg['name'],
);
- $controller['#args'][] = $arg;
+ $controller['args'][] = $arg;
}
- $resources['service_' . $signature[0]]['#actions'][$signature[1]] = $controller;
+ $resources['service_'. $signature[0]]['actions'][$signature[1]] = $controller;
}
return $resources;
-}
\ No newline at end of file
+}
diff --git a/services/comment_service/comment_service.inc b/services/comment_service/comment_service.inc
index 06e15bf..4de7e57 100644
--- a/services/comment_service/comment_service.inc
+++ b/services/comment_service/comment_service.inc
@@ -1,7 +1,7 @@
cid then that comment is edited.
*
* @param $comment
- * An array matching the form values that would be submitted in the comment
+ * An array matching the form values that would be submitted in the comment
* edit form.
* @return
* Unique identifier for the comment (cid) or FALSE if there was a problem.
@@ -78,7 +78,7 @@ function comment_service_load_node_comments($nid, $count = 0, $start = 0) {
* @param $cid
* Unique identifier for the specified comment
* @return
- * The comment object
+ * The comment object
*/
function comment_service_load($cid) {
$cid = db_result(db_query("SELECT cid FROM {comments} WHERE cid = %d", $cid));
diff --git a/services/comment_service/comment_service.module b/services/comment_service/comment_service.module
index 4bed2d2..2538c95 100644
--- a/services/comment_service/comment_service.module
+++ b/services/comment_service/comment_service.module
@@ -1,7 +1,7 @@
'comment.save',
@@ -67,7 +67,7 @@ function comment_service_service() {
array(
'#name' => 'start',
'#type' => 'int',
- '#description' => t('If count is set to non-zero value, You can pass also non-zero value for start. For example to get comments from 5 to 15, pass count=10 and start=5.'),
+ '#description' => t('If count is set to non-zero value, you can pass also non-zero value for start. For example to get comments from 5 to 15, pass count=10 and start=5.'),
),
),
'#return' => 'array',
@@ -130,12 +130,4 @@ function comment_service_service() {
'#help' => t('This method returns the number of new comments on a given node since a given timestamp.'),
),
);
-}
-
-function comments_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function comments_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services/file_service/file_service.inc b/services/file_service/file_service.inc
index eb70646..bc7541e 100644
--- a/services/file_service/file_service.inc
+++ b/services/file_service/file_service.inc
@@ -1,7 +1,7 @@
file)) {
+ return FALSE;
+ }
+
+ // If the submitted file is an update, then set the update parameter for
+ // drupal_write_record(), indicating such. Otherwise we can just pass the
+ // object in and it will be treated as an insert.
+ $update = array();
+ if (!empty($file->fid)) {
+ $update = 'fid';
+ }
+
+ // Build the list of non-munged extensions.
+ // @todo: this should not be here. we need to figure out the right place.
+ // @todo: also isn't that repeated variable get a waste? I mean, I guess it
+ // is cached but still it is pretty ugly.
+ $extensions = '';
+ foreach ($user->roles as $rid => $name) {
+ $extensions .= ' '. variable_get("upload_extensions_$rid",
+ variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp'));
+ }
+
+ // Get the directory name for the location of the file:
+ $dir = dirname($file->filepath);
+ // Build the destination folder tree if it doesn't already exists.
+ if (!file_check_directory($dir, FILE_CREATE_DIRECTORY)) {
+ return services_error("Could not create destination directory for file.");
+ }
+
+ // Update file object as necessary
+ $file->filepath = file_destination(file_create_path($file->filepath), FILE_EXISTS_RENAME);
+ $file->filename = file_munge_filename(trim(basename($file->filepath), '.'), $extensions, TRUE);
+ $file->filemime = file_get_mimetype($file->filename);
+
+ // Rename potentially executable files, to help prevent exploits.
+ if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
+ $file->filemime = 'text/plain';
+ $file->filepath .= '.txt';
+ $file->filename .= '.txt';
+ }
+
+ // If the destination is not provided, or is not writable, error our
+ if (empty($file->filepath) || file_check_path($file->filepath) === FALSE) {
+ return services_error("Destintion directory does not exist or is not writeable.");
+ }
+
+ //The filepath that ends up in the node must contain the filename
+ $file->filepath .= '/'. $file->filename;
+
+ // Write the file
+ if (!file_save_data(base64_decode($file->file), $file->filepath)) {
+ return services_error("Could not write file to destination");
+ }
+
+ // If we made it this far it's safe to record this file in the database.
+ drupal_write_record('files', $file, $update);
+
+ // hook_file_insert() requires an object
+ if (empty($update)) {
+ foreach (module_implements('file_insert') as $module) {
+ $function = $module .'_file_insert';
+ $function($file);
+ }
+ }
+
+ // Return the fid
+ return $file->fid;
+}
+
/**
* Check if the user has permission to get a given file
*/
diff --git a/services/file_service/file_service.module b/services/file_service/file_service.module
index e28bd10..d4204a8 100644
--- a/services/file_service/file_service.module
+++ b/services/file_service/file_service.module
@@ -1,7 +1,6 @@
'array',
'#help' => t('Returns the files attached to a node.')
),
- );
-}
-
-function file_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-function file_service_enable() {
- cache_clear_all('services:methods', 'cache');
+ // file.save
+ array(
+ '#method' => 'file.save',
+ '#callback' => 'file_service_save',
+ '#access arguments' => 'save file information',
+ '#file' => array('file' => 'inc', 'module' => 'file_service'),
+ '#args' => array(
+ array(
+ '#name' => 'file',
+ '#type' => 'struct',
+ '#description' => t('An object representing a file.'),
+ ),
+ ),
+ '#return' => 'int',
+ '#help' => t('Saves information about a specific file. Note this does not save files themselves, just the information as stored in the files table. Returns the fid of the new/updated file.'),
+ ),
+ );
}
\ No newline at end of file
diff --git a/services/menu_service/menu_service.inc b/services/menu_service/menu_service.inc
index 150ecb3..221b1bf 100644
--- a/services/menu_service/menu_service.inc
+++ b/services/menu_service/menu_service.inc
@@ -1,5 +1,5 @@
path_alias = drupal_get_path_alias($tmp->link_path);
+ $tmp->path_alias = drupal_get_path_alias($item['link']['link_path']);
}
$tmp->children = menu_service_process($item['below'], $fields);
$out[] = $tmp;
diff --git a/services/menu_service/menu_service.module b/services/menu_service/menu_service.module
index cbe8db2..5186e06 100644
--- a/services/menu_service/menu_service.module
+++ b/services/menu_service/menu_service.module
@@ -1,5 +1,5 @@
type . '_node_form', $form_state, $node);
+ $ret = drupal_execute($node->type .'_node_form', $form_state, $node);
// Fetch $nid out of $form_state
$nid = $form_state['nid'];
@@ -54,7 +59,7 @@ function _node_resource_update($nid, $node) {
$form_state['values']['op'] = t('Save');
$form_state['node'] = (array)$old_node;
- drupal_execute($old_node->type . '_node_form', $form_state, $old_node);
+ drupal_execute($old_node->type .'_node_form', $form_state, $old_node);
if ($errors = form_get_errors()) {
return services_error(implode("\n", $errors), 406);
diff --git a/services/node_service/node_resource.models.inc b/services/node_service/node_resource.models.inc
index 40528aa..827b6ba 100644
--- a/services/node_service/node_resource.models.inc
+++ b/services/node_service/node_resource.models.inc
@@ -1,5 +1,10 @@
node->nid, array('absolute' => TRUE));
+ return url('node/'. $this->node->nid, array('absolute' => TRUE));
}
/**
diff --git a/services/node_service/node_resource.module b/services/node_service/node_resource.module
index 2e3ea64..fee6ea3 100644
--- a/services/node_service/node_resource.module
+++ b/services/node_service/node_resource.module
@@ -1,5 +1,10 @@
array(
- '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#retrieve' => array(
'#callback' => '_node_resource_retrieve',
+ '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#args' => array(
array(
'#name' => 'nid',
@@ -39,6 +44,7 @@ function node_resource_service_resource() {
),
'#create' => array(
'#callback' => '_node_resource_create',
+ '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#args' => array(
array(
'#name' => 'node',
@@ -54,6 +60,7 @@ function node_resource_service_resource() {
),
'#update' => array(
'#callback' => '_node_resource_update',
+ '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#args' => array(
array(
'#name' => 'node',
@@ -69,6 +76,7 @@ function node_resource_service_resource() {
),
'#delete' => array(
'#callback' => '_node_resource_delete',
+ '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#args' => array(
array(
'#name' => 'nid',
@@ -82,6 +90,7 @@ function node_resource_service_resource() {
),
'#index' => array(
'#callback' => '_node_resource_index',
+ '#file' => array('file' => 'inc', 'module' => 'node_resource'),
'#args' => array(
array(
'#name' => 'page',
diff --git a/services/node_service/node_service.inc b/services/node_service/node_service.inc
index 161dcbc..eea271c 100644
--- a/services/node_service/node_service.inc
+++ b/services/node_service/node_service.inc
@@ -1,7 +1,7 @@
t('A node ID.'))),
'#help' => t('Delete a node.')),
);
-}
-
-function node_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function node_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services/search_service/search_service.inc b/services/search_service/search_service.inc
index 67a2101..31ef4a8 100644
--- a/services/search_service/search_service.inc
+++ b/services/search_service/search_service.inc
@@ -1,7 +1,6 @@
'node'));
- watchdog('search_service', t('search.content invoked for !keys using hooks !hooks', array('!keys' => $keys, '!hooks' => implode($search_hooks, ', '))));
+ watchdog('search_service', t('search.content invoked for !keys using hooks !hooks', array('!keys' => $keys, '!hooks' => implode(', ', $search_hooks))));
// run through only select hook_search() as defined in /admin/settings/search_service
foreach ($search_hooks as $hook) {
diff --git a/services/search_service/search_service.module b/services/search_service/search_service.module
index 8b58a5e..dc95680 100644
--- a/services/search_service/search_service.module
+++ b/services/search_service/search_service.module
@@ -1,7 +1,6 @@
t('Searches users according to keys via hook_search.'),
)
);
-}
-
-function search_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function search_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services/system_service/system_service.inc b/services/system_service/system_service.inc
index db261d0..59549b2 100644
--- a/services/system_service/system_service.inc
+++ b/services/system_service/system_service.inc
@@ -1,7 +1,6 @@
'bool',
'#help' => t('Clear cache on remote site.'),
),
- );
-}
-function system_service_disable() {
- cache_clear_all('services:methods', 'cache');
+ // system.watchdog
+ array(
+ '#method' => 'system.watchdog',
+ '#callback' => 'system_service_watchdog_send',
+ '#access arguments' => array('log a system message from remote'),
+ '#file' => array('file' => 'inc', 'module' => 'system_service'),
+ '#args' => array(
+ array(
+ '#name' => 'type',
+ '#type' => 'string',
+ '#description' => t('The category to which this message belongs.')
+ ),
+ array(
+ '#name' => 'message',
+ '#type' => 'string',
+ '#description' => t('The message to store in the log. See t() for documentation on how $message and $variables interact. Keep $message translatable by not concatenating dynamic values into it!')
+ ),
+ array(
+ '#name' => 'variables',
+ '#type' => 'array',
+ '#optional' => TRUE,
+ '#description' => t('Array of variables to replace in the message on display or NULL if message is already translated or not possible to translate.')
+ ),
+ array(
+ '#name' => 'severity',
+ '#type' => 'int',
+ '#optional' => TRUE,
+ '#description' => t('The severity of the message, as per RFC 3164.')
+ ),
+ array(
+ '#name' => 'link',
+ '#type' => 'string',
+ '#optional' => TRUE,
+ '#description' => t('A link to associate with the message.')
+ ),
+ ),
+ '#return' => 'bool',
+ '#help' => t('Log a system message.'),
+ ),
+ );
}
-
-function system_service_enable() {
- cache_clear_all('services:methods', 'cache');
-}
\ No newline at end of file
diff --git a/services/taxonomy_service/taxonomy_service.inc b/services/taxonomy_service/taxonomy_service.inc
index 9dd2740..54b0286 100644
--- a/services/taxonomy_service/taxonomy_service.inc
+++ b/services/taxonomy_service/taxonomy_service.inc
@@ -1,7 +1,6 @@
'taxonomy.saveTerm',
'#callback' => 'taxonomy_service_save_term',
+ '#access arguments' => array('administer taxonomy from remote'),
'#file' => array('file' => 'inc', 'module' => 'taxonomy_service'),
'#args' => array(
array(
@@ -43,6 +50,7 @@ function taxonomy_service_service() {
array(
'#method' => 'taxonomy.saveVocabulary',
'#callback' => 'taxonomy_service_save_vocabulary',
+ '#access arguments' => array('administer taxonomy from remote'),
'#file' => array('file' => 'inc', 'module' => 'taxonomy_service'),
'#args' => array(
array(
@@ -129,12 +137,4 @@ function taxonomy_service_service() {
'#help' => t('Finds all nodes that match selected taxonomy conditions.')
),
);
-}
-
-function taxonomy_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function taxonomy_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services/user_service/user_service.inc b/services/user_service/user_service.inc
index 8f92e4d..1d9ff7a 100644
--- a/services/user_service/user_service.inc
+++ b/services/user_service/user_service.inc
@@ -1,7 +1,7 @@
uid) ? user_save($update,$account) : user_save('', $account);
- if (!$account) {
- return services_error(t('Error on saving the user.'), 500);
+ $form_state = array();
+ if (!isset($update->uid)) {
+ // register a new user
+ $form_state['values'] = $account;
+ $form_state['values']['pass'] = array(
+ 'pass1' => $account['pass'],
+ 'pass2' => $account['pass'],
+ );
+ $form_state['values']['op'] = t('Create new account');
+ $ret = drupal_execute('user_register', $form_state);
+ }
+ else {
+ // If a profile category was passed in, use it. Otherwise default
+ // to 'account' (for saving core user data.)
+ $category = 'account';
+ if (isset($account['category'])) {
+ $category = $account['category'];
+ unset($account['category']);
+ }
+
+ // Any logged in user is by default authenticated,
+ // and leaving this role set in the user's roles array
+ // causes big problems because of a FAPI hack that controls
+ // this checkbox. Therefore we just force it to 0 here.
+ if (isset($account['roles'][2])) {
+ $account['roles'][2] = 0;
+ }
+
+ // Drop any passed in values into the $account var. Anything
+ // unused by the form just gets ignored.
+ foreach ($account as $key => $value) {
+ $form_state['values'][$key] = $value;
+ }
+
+ $form_state['values']['op'] = 'Save';
+ $form_state['values']['_category'] = $category;
+ $form_state['values']['_account'] = $account;
+ $ret = drupal_execute('user_profile_form', $form_state, (object) $account, $category);
}
- // Everything went right.
- // Return the user ID
- return $account->uid;
+ // Error if needed.
+ if ($errors = form_get_errors()) {
+ return services_error(implode("\n", $errors), 401);
+ }
+ else {
+ return $form_state['user']->uid;
+ }
}
/**
diff --git a/services/user_service/user_service.module b/services/user_service/user_service.module
index f64a3a5..64a30e4 100644
--- a/services/user_service/user_service.module
+++ b/services/user_service/user_service.module
@@ -1,7 +1,6 @@
t('Save user details.')
),
);
-}
-
-function user_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function user_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services/views_service/views_service.inc b/services/views_service/views_service.inc
index a3d0dad..8514239 100644
--- a/services/views_service/views_service.inc
+++ b/services/views_service/views_service.inc
@@ -1,7 +1,6 @@
set_arguments($args, FALSE);
$view->set_offset($offset);
- $view->set_items_per_page($limit);
- $view->execute();
-
- // Get row plugin setting
- $row_plugin = $view->display[$view->current_display]->display_options['row_plugin'];
-
- $nodes = array();
- // If row plugin is node, then we must do a node_load
- if ($row_plugin == 'node') {
- foreach ($view->result as $node) {
- $nodes[] = services_node_load(node_load($node->nid), $fields);
- }
+ // If offset is set we can't have a user pager.
+ if (empty($offset)) {
+ $view->set_use_pager(TRUE);
+ $view->set_items_per_page($limit);
}
- // Otherwise, pass through the fields filter, just in case
else {
- foreach ($view->result as $node) {
- $nodes[] = services_node_load($node, $fields);
- }
+ // Disable the user pager.
+ $view->set_use_pager(FALSE);
}
-
- return $nodes;
+ if (!$format_output) {
+ $view->set_display($display_id);
+ $view->execute();
+ $result = $view->result;
+ }
+ else {
+ // We want to keep the result an array.
+ $result[] = $view->preview($display_id);
+ }
+ return $result;
}
/**
diff --git a/services/views_service/views_service.module b/services/views_service/views_service.module
index b5e1deb..71e5104 100644
--- a/services/views_service/views_service.module
+++ b/services/views_service/views_service.module
@@ -1,7 +1,6 @@
t('View name.')
),
array(
- '#name' => 'fields',
- '#type' => 'array',
+ '#name' => 'display_id',
+ '#type' => 'string',
'#optional' => TRUE,
- '#description' => t('A list of fields to return.')
+ '#description' => t('A display provided by the selected view.')
),
array(
'#name' => 'args',
@@ -51,13 +50,19 @@ function views_service_service() {
'#name' => 'offset',
'#type' => 'int',
'#optional' => TRUE,
- '#description' => t('An offset integer for paging.')
+ '#description' => t('An offset integer for paging. If this is set limit will be ignored.')
),
array(
'#name' => 'limit',
'#type' => 'int',
'#optional' => TRUE,
- '#description' => t('A limit integer for paging.')
+ '#description' => t('A limit integer for paging. If offset is set, this will be ignored.')
+ ),
+ array(
+ '#name' => 'format_output',
+ '#type' => 'boolean',
+ '#optional' => TRUE,
+ '#description' => t('TRUE if view should be formatted, or only the view result returned (FALSE by default).')
),
),
'#return' => 'array',
@@ -106,12 +111,4 @@ function views_service_service() {
'#help' => t('Imports a view through code, equivalent to using the Import tab in the views admin.'),
),
);
-}
-
-function views_service_disable() {
- cache_clear_all('services:methods', 'cache');
-}
-
-function views_service_enable() {
- cache_clear_all('services:methods', 'cache');
}
\ No newline at end of file
diff --git a/services_admin_browse.inc b/services_admin_browse.inc
index 393781d..59eea4a 100644
--- a/services_admin_browse.inc
+++ b/services_admin_browse.inc
@@ -1,13 +1,15 @@
';
foreach ($servers as $module) {
$info = module_invoke($module, 'server_info');
- $name = $info['#name'];
- $path = 'services/'. $info['#path'];
+ services_strip_hashes($info);
+
+ $name = $info['name'];
+ $path = 'services/'. $info['path'];
$output .= '
'. l($name .' - /'. $path, $path) .'';
}
$output .= '';
@@ -36,7 +40,7 @@ function services_admin_browse_index() {
// group namespaces
$services = array();
foreach ($methods as $method) {
- $namespace = drupal_substr($method['#method'], 0, strrpos($method['#method'], '.'));
+ $namespace = drupal_substr($method['method'], 0, strrpos($method['method'], '.'));
$services[$namespace][] = $method;
}
@@ -45,7 +49,7 @@ function services_admin_browse_index() {
$output .= ''. $namespace .'
';
$output .= '';
foreach ($methods as $method) {
- $output .= '- '. l($method['#method'], 'admin/build/services/browse/'. $method['#method']) .'
';
+ $output .= '- '. l($method['method'], 'admin/build/services/browse/'. $method['method']) .'
';
}
$output .= '
';
}
@@ -57,23 +61,31 @@ function services_admin_browse_index() {
return $output;
}
+/**
+ * Display a form for the testing of a single service method in the browser.
+ *
+ * @param $method
+ * The method to be tested
+ * @return
+ * Form for testing and method parameter info.
+ */
function services_admin_browse_method($method) {
global $_services_admin_browse_test_submit_result;
$output = '';
- $output .= ''. $method['#method'] .'
';
- $output .= ''. $method['#help'] .'
';
+ $output .= ''. $method['method'] .'
';
+ $output .= ''. $method['help'] .'
';
// List arguments.
- $output .= ''. t('Arguments') .' ('. count($method['#args']) .')
';
+ $output .= ''. t('Arguments') .' ('. count($method['args']) .')
';
$output .= '';
$count = 0;
- foreach ($method['#args'] as $arg) {
+ foreach ($method['args'] as $arg) {
$count++;
- $output .= '- '. $arg['#type'] .''.
- $arg['#name'] .' ('. (($arg['#optional']) ? t('optional') : t('required')) .')
';
- $output .= '- '. $arg['#description'] .'
';
+ $output .= '- '. $arg['type'] .''.
+ $arg['name'] .' ('. (($arg['optional']) ? t('optional') : t('required')) .')
';
+ $output .= '- '. $arg['description'] .'
';
}
$output .= '
';
@@ -93,6 +105,14 @@ function services_admin_browse_method($method) {
return $output;
}
+/**
+ * Build the form used for testing a service in the browser
+ *
+ * @return
+ * FAPI array
+ * @ingroup forms
+ * @see services_admin_browse_test_submit()
+ */
function services_admin_browse_test() {
$form = array();
$method = services_method_get(arg(4));
@@ -100,15 +120,15 @@ function services_admin_browse_test() {
$form['arg'] = array('#tree' => TRUE);
$form['format'] = array('#tree' => TRUE);
- foreach ($method['#args'] as $key => $arg) {
+ foreach ($method['args'] as $key => $arg) {
$form['name'][$key] = array(
- '#value' => $arg['#name']
+ '#value' => $arg['name']
);
$form['optional'][$key] = array(
- '#value' => ($arg['#optional']) ? t('optional') : t('required')
+ '#value' => ($arg['optional']) ? t('optional') : t('required')
);
- if (isset($arg['#size']) && $arg['#size'] == 'big') {
+ if (isset($arg['size']) && $arg['size'] == 'big') {
$form['arg'][$key] = array(
'#type' => 'textarea'
);
@@ -120,7 +140,7 @@ function services_admin_browse_test() {
}
$format_opt = array();
- switch ($arg['#type']) {
+ switch ($arg['type']) {
case 'array':
$format_opt['cdel'] = t('Comma delimited');
case 'struct':
@@ -153,13 +173,16 @@ function services_admin_browse_test() {
return $form;
}
+/**
+ * Submit callback for services_admin_browse_test().
+ */
function services_admin_browse_test_submit($form, $form_state) {
global $_services_admin_browse_test_submit_result;
$method = services_method_get(arg(4));
$args = services_admin_browse_test_unserialize_args($form_state['values']['arg'], $form_state['values']['format']);
// Allow the authorization module to handle submitted values.
services_auth_invoke('alter_browse_form_submit', $method, $args);
- $result = services_method_call($method['#method'], $args, TRUE);
+ $result = services_method_call($method['method'], $args, TRUE);
$_services_admin_browse_test_submit_result = ''. htmlspecialchars(print_r($result, TRUE)) .'
';
}
@@ -167,8 +190,8 @@ function services_admin_browse_test_unserialize_args($values, $formats) {
$method = services_method_get(arg(4));
$noskip = FALSE;
// Convert args
- for ($c = count($method['#args']) - 1; $c >= 0; $c--) {
- $arg = $method['#args'][$c];
+ for ($c = count($method['args']) - 1; $c >= 0; $c--) {
+ $arg = $method['args'][$c];
$value = $values[$c];
// Remove empty values from end of array
@@ -192,7 +215,7 @@ function services_admin_browse_test_unserialize_args($values, $formats) {
$return[$c] = NULL;
}
else {
- $return[$c] = json_decode($value, $arg['#type'] === 'array');
+ $return[$c] = json_decode($value, $arg['type'] === 'array');
}
break;
case 'sphp':
@@ -212,7 +235,9 @@ function services_admin_browse_test_unserialize_args($values, $formats) {
return $return;
}
-
+/**
+ * Implementation of hook_theme();
+ */
function theme_services_admin_browse_test($form) {
$output = '';
$output .= drupal_render($form['test']);
@@ -243,8 +268,13 @@ function theme_services_admin_browse_test($form) {
return $output;
}
-/*
- * Callback for admin page
+/**
+ * Build the admin settings form.
+ *
+ * @return
+ * FAPI array
+ * @ingroup forms
+ * @see services_admin_settings_submit()
*/
function services_admin_settings() {
$auth_modules = module_implements('authentication_info');
@@ -254,7 +284,9 @@ function services_admin_settings() {
$auth_options = array('' => t('-- Select a authorization module'));
foreach ($auth_modules as $module) {
$info = services_auth_info(NULL, $module);
- $auth_options[$info['#description']][$module] = $info['#title'];
+ services_strip_hashes($info);
+
+ $auth_options[$info['description']][$module] = $info['title'];
}
$form['security'] = array(
@@ -304,6 +336,9 @@ function services_admin_settings() {
return $form;
}
+/**
+ * Validate callback for services_admin_settings().
+ */
function services_admin_settings_validate($form, $form_state) {
// Invoke custom validation for the auth module
if (!empty($form_state['values']['auth_module'])) {
@@ -312,6 +347,9 @@ function services_admin_settings_validate($form, $form_state) {
}
}
+/**
+ * Submit callback for services_admin_settings().
+ */
function services_admin_settings_submit($form, $form_state) {
// Update the services oauth module variable *if needed*.
$old_auth = variable_get('services_auth_module', '');