You are here

function services_controller_execute in Services 6.3

Same name and namespace in other branches
  1. 7.3 includes/services.runtime.inc \services_controller_execute()

Performs access checks and executes a services controller. This method is called by server implementations.

Parameters

array $controller: An array containing information about the controller

array $args: The arguments that should be passed to the controller.

array $auth_args: The arguments that should be passed to the authentication module.

array $options: Options for the execution. Use 'skip_authentication'=>TRUE to skip the services-specific authentication checks. Access checks will always be made.

2 calls to services_controller_execute()
RESTServer::handle in servers/rest_server/includes/RESTServer.inc
Handles the call to the REST server
xmlrpc_server_call_wrapper in servers/xmlrpc_server/xmlrpc_server.module
Pass XMLRPC server requests to the appropriate services method.

File

./services.runtime.inc, line 97
Contains functions that only are necessary when a service call is made. This has broken out so that this code isn't loaded for every page load.

Code

function services_controller_execute($controller, $args = array(), $options = array()) {
  global $user;

  // Check for missing arguments.
  $server_info = services_server_info_object();
  if ($server_info->debug) {
    watchdog('services', 'Controller: <pre>@controller</pre>', array(
      '@controller' => print_r($controller, TRUE),
    ), WATCHDOG_DEBUG);
    watchdog('services', 'Passed arguments: <pre>@arguments</pre>', array(
      '@arguments' => print_r($args, TRUE),
    ), WATCHDOG_DEBUG);
  }
  $original_user = $user;
  if (strpos($controller['callback'], 'login') !== FALSE && strpos($controller['callback'], 'logout') !== FALSE) {
    $old_state = session_save_session();
    session_save_session(FALSE);
  }
  $user = drupal_anonymous_user();
  $user->timestamp = time();
  services_set_server_info('original_user', $original_user);

  // Check authentication.
  if (!isset($options['skip_authentication']) || !$options['skip_authentication']) {
    $endpoint_name = services_get_server_info('endpoint');
    $endpoint = services_endpoint_load($endpoint_name);
    foreach ($endpoint->authentication as $auth_module => $settings) {
      if (isset($settings) && ($auth_error = services_auth_invoke($auth_module, 'authenticate_call', $settings, $controller, $args))) {
        return services_error($auth_error, 401);
      }
    }
  }

  // Load the proper file.
  if (!empty($controller['file']) && ($file = $controller['file'])) {
    module_load_include($file['type'], $file['module'], isset($file['name']) ? $file['name'] : NULL);
  }

  // Construct access arguments array.
  if (isset($controller['access arguments'])) {
    $access_arguments = $controller['access arguments'];
    if (isset($controller['access arguments append']) && $controller['access arguments append']) {
      $access_arguments[] = $args;
    }
  }
  else {

    // Just use the arguments array if no access arguments have been specified
    $access_arguments = $args;
  }

  // Load the proper file for the access callback.
  if (!empty($controller['access callback file']) && ($access_cb_file = $controller['access callback file'])) {
    $access_cb_file_name = isset($access_cb_file['name']) ? $access_cb_file['name'] : NULL;
    module_load_include($access_cb_file['type'], $access_cb_file['module'], $access_cb_file_name);
  }

  // Call default or custom access callback.
  if (call_user_func_array($controller['access callback'], $access_arguments) != TRUE) {
    return services_error(t('Access denied for user !uid "@user"', array(
      '!uid' => $user->uid,
      '@user' => isset($user->name) ? $user->name : 'anonymous',
    )), 401);
  }

  // Preprocess controller and arguments.
  $controller['__drupal_alter_by_ref'] = array(
    &$args,
  );
  drupal_alter('services_request_preprocess', $controller, $args, $options);

  // Execute the controller callback.
  $result = call_user_func_array($controller['callback'], $args);
  if (isset($server_root) && $server_root) {
    chdir($server_root);
  }

  // Postprocess controller, arguments and result.
  $controller['__drupal_alter_by_ref'] = array(
    &$args,
    &$result,
  );
  drupal_alter('services_request_postprocess', $controller);
  if (strpos($controller['callback'], 'login') !== FALSE && strpos($controller['callback'], 'logout') !== FALSE) {
    session_save_session($old_state);
  }
  if ($server_info->debug) {
    watchdog('services', 'results: <pre>@results</pre>', array(
      '@results' => print_r($result, TRUE),
    ), WATCHDOG_DEBUG);
  }
  return $result;
}