You are here

function restful_menu_process_callback in RESTful 7

Same name and namespace in other branches
  1. 7.2 restful.module \restful_menu_process_callback()

Page callback; Return the response for an API call.

Parameters

$resource_name: The name of the resource (e.g. "articles").

$version: The version, prefixed with v (e.g. v1, v2.2).

Return value

string JSON output with the result of the API call.

Throws

RestfulServiceUnavailable

See also

http://tools.ietf.org/html/draft-nottingham-http-problem-06

2 string references to 'restful_menu_process_callback'
restful_get_restful_handler_for_path in ./restful.module
Helper function to get the restful handler for the selected path.
restful_menu in ./restful.module
Implements hook_menu().

File

./restful.module, line 468

Code

function restful_menu_process_callback($resource_name, $version = NULL) {
  list($major_version, $minor_version) = \RestfulBase::getVersionFromRequest();
  $handler = restful_get_restful_handler($resource_name, $major_version, $minor_version);
  if (!$handler instanceof \RestfulDataProviderInterface) {
    throw new \RestfulServiceUnavailable(format_string('The selected plugin (@plugin) does not implement \\RestfulDataProviderInterface.', array(
      '@plugin' => $resource_name . ' v' . $major_version . '.' . $minor_version,
    )));
  }

  // Vary the response with the presence of the X-API-Version or Accept headers.
  $headers = $handler
    ->getHttpHeaders();
  $additional_variations = empty($headers['Vary']) ? array(
    'Accept',
  ) : array(
    $headers['Vary'],
    'Accept',
  );
  if (\RestfulManager::getRequestHttpHeader('X-API-Version')) {
    $additional_variations[] = 'X-API-Version';
  }
  if ($additional_variations) {
    $handler
      ->setHttpHeaders('Vary', implode(',', $additional_variations));
  }

  // Always add the allow origin if configured.
  if ($allowed_origin = $handler
    ->getPluginKey('allow_origin')) {
    $handler
      ->setHttpHeaders('Access-Control-Allow-Origin', $allowed_origin);
  }
  $method = strtoupper($_SERVER['REQUEST_METHOD']);
  if ($method == \RestfulInterface::POST && \RestfulManager::getRequestHttpHeader('X-HTTP-Method-Override')) {
    $method = \RestfulManager::getRequestHttpHeader('X-HTTP-Method-Override');
  }
  $method = strtolower($method);
  $path = func_get_args();
  array_shift($path);
  if (preg_match('/^v\\d+(\\.\\d+)?$/', $version)) {
    array_shift($path);
  }
  $path = implode('/', $path);
  $request = restful_parse_request();
  try {
    if (!\RestfulBase::isValidMethod($method, FALSE)) {
      throw new RestfulBadRequestException(format_string('Unsupported method @method.', array(
        '@method' => $method,
      )));
    }
    return $handler
      ->{$method}($path, $request);
  } catch (RestfulException $e) {
    $result = array(
      'type' => $e
        ->getType(),
      'title' => $e
        ->getMessage(),
      'status' => $e
        ->getCode(),
      'detail' => $e
        ->getDescription(),
    );
    if ($instance = $e
      ->getInstance()) {
      $result['instance'] = $instance;
    }
    if ($errors = $e
      ->getFieldErrors()) {
      $result['errors'] = $errors;
    }
    foreach ($e
      ->getHeaders() as $header_name => $header_value) {
      drupal_add_http_header($header_name, $header_value);
    }
    if ($e
      ->getCode() < 500) {

      // Even though it's an exception, it's in fact not a server error - it
      // might be just access denied, or a bad request, so we just want to log
      // it, but without marking it as an actual exception.
      watchdog('restful', $e
        ->getMessage());
    }
    else {

      // This one should really be considered as an error.
      watchdog_exception('restful', $e);
    }
  } catch (Exception $e) {
    $result = array(
      'type' => 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1',
      'title' => $e
        ->getMessage(),
      'status' => 500,
    );
    watchdog_exception('restful', $e);
  }

  // Adhere to the API Problem draft proposal.
  drupal_add_http_header('Status', $result['status']);
  drupal_add_http_header('Content-Type', 'application/problem+json; charset=utf-8');
  return $result;
}