'. t('Servers') .'';
if (!empty($servers)) {
$output .= '
';
foreach ($servers as $module) {
$info = module_invoke($module, 'server_info');
$name = $info['#name'];
$path = 'services/'. $info['#path'];
$output .= '- '. l($name .' - /'. $path, $path) .'
';
}
$output .= '
';
}
else {
$output .= ''. t('You must enable at least one server module to be able to connect remotely. Visit the modules page to enable server modules.', array('@url' => url('admin/build/modules'))) .'
';
}
$output .= ''. t('Services') .'
';
// group namespaces
$services = array();
foreach ($methods as $method) {
$namespace = drupal_substr($method['#method'], 0, strrpos($method['#method'], '.'));
$services[$namespace][] = $method;
}
if (count($services)) {
foreach ($services as $namespace => $methods) {
$output .= ''. $namespace .'
';
$output .= '';
foreach ($methods as $method) {
$output .= '- '. l($method['#method'], 'admin/build/services/browse/'. $method['#method']) .'
';
}
$output .= '
';
}
}
else {
$output .= t('No services have been enabled.');
}
return $output;
}
function services_admin_browse_method($method) {
global $_services_admin_browse_test_submit_result;
$output = '';
$output .= ''. $method['#method'] .'
';
$output .= ''. $method['#help'] .'
';
// List arguments.
$output .= ''. t('Arguments') .' ('. count($method['#args']) .')
';
$output .= '';
$count = 0;
foreach ($method['#args'] as $arg) {
$count++;
$output .= '- '. $arg['#type'] .''.
$arg['#name'] .' ('. (($arg['#optional']) ? t('optional') : t('required')) .')
';
$output .= '- '. $arg['#description'] .'
';
}
$output .= '
';
// Allow testing of methods
$output .= ''. t('Call method') .'
';
$output .= drupal_get_form('services_admin_browse_test');
// Display results
if ($_services_admin_browse_test_submit_result) {
$output .= '';
$output .= '
'. t('Result') .'
';
$output .= ''. $_services_admin_browse_test_submit_result .'
';
$output .= '';
}
return $output;
}
function services_admin_browse_test() {
$form = array();
$method = services_method_get(arg(4));
$form['arg'] = array('#tree' => TRUE);
$timestamp = time();
$nonce = user_password();
foreach ($method['#args'] as $key => $arg) {
$form['name'][$key] = array(
'#value' => $arg['#name']
);
$form['optional'][$key] = array(
'#value' => ($arg['#optional']) ? t('optional') : t('required')
);
switch ($arg['#name']) {
case 'hash':
$form['arg'][$key] = array(
'#title' => 'Hash',
'#type' => 'textfield',
'#default_value' => hash_hmac('sha256', $timestamp .';'. $_SERVER['HTTP_HOST'] .';'. $nonce .';'. arg(4), services_admin_browse_get_first_key())
);
break;
case 'sessid':
$form['arg'][$key] = array(
'#title' => 'Session id',
'#type' => 'textfield',
'#default_value' => session_id()
);
break;
case 'domain_name':
$form['arg'][$key] = array(
'#title' => 'Domain name',
'#type' => 'textfield',
'#default_value' => $_SERVER['HTTP_HOST']
);
break;
case 'domain_time_stamp':
$form['arg'][$key] = array(
'#title' => 'Timestamp',
'#type' => 'textfield',
'#default_value' => $timestamp
);
break;
case 'nonce':
$form['arg'][$key] = array(
'#title' => 'Nonce',
'#type' => 'textfield',
'#default_value' => $nonce
);
break;
default:
if ($arg['#size'] == 'big') {
$form['arg'][$key] = array(
'#type' => 'textarea'
);
}
else {
$form['arg'][$key] = array(
'#type' => 'textfield'
);
}
break;
}
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Call method')
);
$form['#redirect'] = FALSE;
return $form;
}
function services_admin_browse_get_first_key() {
$keys = services_get_keys();
foreach ($keys as $kid => $key) {
return $kid;
}
}
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']);
$result = services_method_call($method['#method'], $args);
$_services_admin_browse_test_submit_result = ''. htmlspecialchars(print_r($result, TRUE)) .'
';
}
function services_admin_browse_test_unserialize_args($values) {
$method = services_method_get(arg(4));
$noskip = FALSE;
// Convert args
for ($c = count($method['#args']) - 1; $c >= 0; $c--) {
$arg = $method['#args'][$c];
$value = $values[$c];
// Remove empty values from end of array
// Once we find a value, we can no longer skip
if (!is_numeric($value) and empty($value) and !$noskip) {
continue;
}
$noskip = TRUE;
switch ($arg['#type']) {
case 'array' :
if (empty($value)) {
$return[$c] = NULL;
}
else {
$return[$c] = explode(',', $value);
}
break;
default :
$return[$c] = $value;
}
}
if ($return) ksort($return);
return $return;
}
function theme_services_admin_browse_test($form) {
$output = '';
$output .= drupal_render($form['test']);
$header = array(t('Name'), t('Required'), t('Value'));
$rows = array();
foreach (element_children($form['name']) as $key => $type) {
$row = array();
if (isset($form['arg'][$key]['#title'])) {
$row[] = $form['arg'][$key]['#title'];
unset($form['arg'][$key]['#title']);
unset($form['name'][$key]);
}
else {
$row[] = drupal_render($form['name'][$key]);
}
$row[] = drupal_render($form['optional'][$key]);
$row[] = drupal_render($form['arg'][$key]);
$rows[] = $row;
}
$output .= theme('table', $header, $rows);
$output .= drupal_render($form['submit']);
$output .= drupal_render($form);
return $output;
}
/*
* Callback for admin page
*/
function services_admin_settings() {
$node_types = node_get_types('names');
$defaults = isset($node_types['blog']) ? array('blog' => 1) : array();
$form['security'] = array(
'#title' => t('Security'),
'#type' => 'fieldset',
'#description' => t('Changing security settings will require you to adjust all method calls. This will affect all applications using site services.'),
);
$form['security']['services_use_key'] = array(
'#type' => '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.'),
);
$form['security']['services_key_expiry'] = array(
'#type' => 'textfield',
'#prefix' => "",
'#suffix' => "
",
'#title' => t('Token expiry time'),
'#default_value' => variable_get('services_key_expiry', 30),
'#description' => t('The time frame for which the token will be valid. Default is 30 secs'),
);
$form['security']['services_use_sessid'] = array(
'#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.')
);
services_admin_js($form);
return system_settings_form($form);
}
/**
* UI enhancement for services page
*/
function services_admin_js($form) {
$out = <<