You are here

protected function JsonApiRequestValidator::validateQueryParams in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php \Drupal\jsonapi\EventSubscriber\JsonApiRequestValidator::validateQueryParams()
  2. 9 core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php \Drupal\jsonapi\EventSubscriber\JsonApiRequestValidator::validateQueryParams()

Validates custom (implementation-specific) query parameter names.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The request for which to validate JSON:API query parameters.

Return value

\Drupal\jsonapi\ResourceResponse|null A JSON:API resource response.

See also

http://jsonapi.org/format/#query-parameters

File

core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php, line 50

Class

JsonApiRequestValidator
Request subscriber that validates a JSON:API request.

Namespace

Drupal\jsonapi\EventSubscriber

Code

protected function validateQueryParams(Request $request) {
  $invalid_query_params = [];
  foreach (array_keys($request->query
    ->all()) as $query_parameter_name) {

    // Ignore reserved (official) query parameters.
    if (in_array($query_parameter_name, JsonApiSpec::getReservedQueryParameters())) {
      continue;
    }
    if (!JsonApiSpec::isValidCustomQueryParameter($query_parameter_name)) {
      $invalid_query_params[] = $query_parameter_name;
    }
  }

  // Drupal uses the `_format` query parameter for Content-Type negotiation.
  // Using it violates the JSON:API spec. Nudge people nicely in the correct
  // direction. (This is special cased because using it is pretty common.)
  if (in_array('_format', $invalid_query_params, TRUE)) {
    $uri_without_query_string = $request
      ->getSchemeAndHttpHost() . $request
      ->getBaseUrl() . $request
      ->getPathInfo();
    $exception = new CacheableBadRequestHttpException((new CacheableMetadata())
      ->addCacheContexts([
      'url.query_args:_format',
    ]), 'JSON:API does not need that ugly \'_format\' query string! 🤘 Use the URL provided in \'links\' 🙏');
    $exception
      ->setHeaders([
      'Link' => $uri_without_query_string,
    ]);
    throw $exception;
  }
  if (empty($invalid_query_params)) {
    return NULL;
  }
  $message = sprintf('The following query parameters violate the JSON:API spec: \'%s\'.', implode("', '", $invalid_query_params));
  $exception = new CacheableBadRequestHttpException((new CacheableMetadata())
    ->addCacheContexts([
    'url.query_args',
  ]), $message);
  $exception
    ->setHeaders([
    'Link' => 'http://jsonapi.org/format/#query-parameters',
  ]);
  throw $exception;
}