You are here

function restws_page_callback in RESTful Web Services 7

Same name and namespace in other branches
  1. 7.2 restws.module \restws_page_callback()

Menu page callback.

Parameters

string $resource: The name of the resource.

string $page_callback: The page callback to pass through when the request is not handled by this module. If no other pre-existing callback is used, 'drupal_not_found' should be passed explicitly.

mixed $arg1,...: Further arguments that are passed through to the given page callback.

1 string reference to 'restws_page_callback'
restws_menu_alter in ./restws.module
Implements hook_menu_alter().

File

./restws.module, line 238
RESTful web services module.

Code

function restws_page_callback($resource, $page_callback) {
  $id_arg = arg(1);
  $format = FALSE;
  if (($pos = strpos($id_arg, '.')) && ($format_name = substr($id_arg, $pos + 1))) {
    $id = substr($id_arg, 0, $pos);
    $format = restws_format($format_name);
  }
  else {
    $id = $id_arg;
    switch ($_SERVER['REQUEST_METHOD']) {
      case 'PUT':
      case 'POST':

        // Get format MIME type form HTTP Content type header.
        $parts = explode(';', $_SERVER['CONTENT_TYPE'], 2);
        $format = restws_format_mimetype($parts[0]);
        break;
      case 'DELETE':
        if (isset($_SERVER['HTTP_ACCEPT'])) {
          $parts = explode(',', $_SERVER['HTTP_ACCEPT'], 2);
          $format = restws_format_mimetype($parts[0]);
        }
        if (!$format) {

          // We don't care about the format, just pick JSON.
          $format = restws_format('json');
        }
        break;
      default:

        // Get the format MIME type form the HTTP Accept header.
        // Ignore requests from web browsers that accept HTML.
        if (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'html') === FALSE) {

          // Use the first MIME type.
          $parts = explode(',', $_SERVER['HTTP_ACCEPT'], 2);
          $format = restws_format_mimetype($parts[0]);
        }

        // Consumers should not use this URL if page caching is enabled.
        // Drupal's page cache IDs are only determined by URL path, so this
        // could poison the HTML page cache. A browser request to /node/1 could
        // suddenly return JSON if the cache was primed with this RESTWS
        // response.
        if ($format && !isset($_COOKIE[session_name()]) && variable_get('cache')) {

          // Redirect to the URL path containing the format name instead.
          drupal_goto($_GET['q'] . '.' . $format
            ->getName(), array(), 301);
        }
    }
  }
  if ($format) {
    switch ($_SERVER['REQUEST_METHOD']) {
      case 'PUT':
        $op = 'create';
        break;
      case 'POST':
        $op = 'update';
        break;
      case 'DELETE':
        $op = 'delete';
        break;
      default:
        $op = 'view';
    }

    // CSRF protection on write operations.
    if (!in_array($_SERVER['REQUEST_METHOD'], array(
      'GET',
      'HEAD',
      'OPTIONS',
      'TRACE',
    )) && !restws_csrf_validation()) {
      echo '403 Access Denied: CSRF validation failed';
      drupal_add_http_header('Status', '403 Forbidden');
      drupal_page_footer();
      exit;
    }
    $payload = file_get_contents('php://input');
    if ($file = variable_get('restws_debug_log')) {
      $log = date(DATE_ISO8601) . "\n";
      $log .= 'Resource: ' . $resource . "\n";
      $log .= 'Operation: ' . $op . "\n";
      $log .= 'Format: ' . $format
        ->mimeType() . "\n";
      $log .= 'Id: ' . $id . "\n";
      $log .= 'Payload: ' . $payload . "\n";
      $log .= "----------------------------------------------------------------\n";
      file_put_contents($file, $log, FILE_APPEND);
    }
    restws_handle_request($op, $format, $resource, $id, $payload);
  }

  // @todo: Determine human readable URIs and redirect, if there is no
  // page callback.
  // Fall back to the passed $page_callback and pass through more arguments.
  $args = func_get_args();
  return call_user_func_array($page_callback, array_slice($args, 2));
}