You are here

public function RouterPathTranslatorSubscriber::onPathTranslation in Decoupled Router 8

Same name and namespace in other branches
  1. 2.x src/EventSubscriber/RouterPathTranslatorSubscriber.php \Drupal\decoupled_router\EventSubscriber\RouterPathTranslatorSubscriber::onPathTranslation()

Processes a path translation request.

1 call to RouterPathTranslatorSubscriber::onPathTranslation()
RedirectPathTranslatorSubscriber::onPathTranslation in src/EventSubscriber/RedirectPathTranslatorSubscriber.php
Processes a path translation request.
1 method overrides RouterPathTranslatorSubscriber::onPathTranslation()
RedirectPathTranslatorSubscriber::onPathTranslation in src/EventSubscriber/RedirectPathTranslatorSubscriber.php
Processes a path translation request.

File

src/EventSubscriber/RouterPathTranslatorSubscriber.php, line 110

Class

RouterPathTranslatorSubscriber
Event subscriber that processes a path translation with the router info.

Namespace

Drupal\decoupled_router\EventSubscriber

Code

public function onPathTranslation(PathTranslatorEvent $event) {
  $response = $event
    ->getResponse();
  if (!$response instanceof CacheableJsonResponse) {
    $this->logger
      ->error('Unable to get the response object for the decoupled router event.');
    return;
  }
  $path = $event
    ->getPath();
  $path = $this
    ->cleanSubdirInPath($path, $event
    ->getRequest());
  try {
    $match_info = $this->router
      ->match($path);
  } catch (ResourceNotFoundException $exception) {

    // If URL is external, we won't perform checks for content in Drupal,
    // but assume that it's working.
    if (UrlHelper::isExternal($path)) {
      $response
        ->setStatusCode(200);
      $response
        ->setData(array(
        'resolved' => $path,
      ));
    }
    return;
  } catch (MethodNotAllowedException $exception) {
    $response
      ->setStatusCode(403);
    return;
  }

  /** @var \Drupal\Core\Entity\EntityInterface $entity */

  /** @var bool $param_uses_uuid */
  list($entity, $param_uses_uuid, $route_parameter_entity_key) = $this
    ->findEntityAndKeys($match_info);
  if (!$entity) {
    $this->logger
      ->notice('A route has been found but it has no entity information.');
    return;
  }
  $response
    ->addCacheableDependency($entity);
  $can_view = $entity
    ->access('view', NULL, TRUE);
  if (!$can_view
    ->isAllowed()) {
    $response
      ->setData([
      'message' => 'Access denied for entity.',
      'details' => 'This user does not have access to view the resolved entity. Please authenticate and try again.',
    ]);
    $response
      ->setStatusCode(403);
    $response
      ->addCacheableDependency($can_view);
    return;
  }
  $entity_type_id = $entity
    ->getEntityTypeId();
  $canonical_url = NULL;
  try {
    $canonical_url = $entity
      ->toUrl('canonical', [
      'absolute' => TRUE,
    ])
      ->toString(TRUE);
  } catch (EntityMalformedException $e) {
    $response
      ->setData([
      'message' => 'Unable to build entity URL.',
      'details' => 'A valid entity was found but it was impossible to generate a valid canonical URL for it.',
    ]);
    $response
      ->setStatusCode(500);
    watchdog_exception('decoupled_router', $e);
    return;
  }
  $entity_param = $param_uses_uuid ? $entity
    ->id() : $entity
    ->uuid();
  $resolved_url = Url::fromRoute($match_info[RouteObjectInterface::ROUTE_NAME], [
    $route_parameter_entity_key => $entity_param,
  ], [
    'absolute' => TRUE,
  ])
    ->toString(TRUE);
  $response
    ->addCacheableDependency($canonical_url);
  $response
    ->addCacheableDependency($resolved_url);
  $is_home_path = $this
    ->resolvedPathIsHomePath($resolved_url
    ->getGeneratedUrl());
  $response
    ->addCacheableDependency((new CacheableMetadata())
    ->setCacheContexts([
    'url.path.is_front',
  ]));
  $label_accessible = $entity
    ->access('view label', NULL, TRUE);
  $response
    ->addCacheableDependency($label_accessible);
  $output = [
    'resolved' => $resolved_url
      ->getGeneratedUrl(),
    'isHomePath' => $is_home_path,
    'entity' => [
      'canonical' => $canonical_url
        ->getGeneratedUrl(),
      'type' => $entity_type_id,
      'bundle' => $entity
        ->bundle(),
      'id' => $entity
        ->id(),
      'uuid' => $entity
        ->uuid(),
    ],
  ];
  if ($label_accessible
    ->isAllowed()) {
    $output['label'] = $entity
      ->label();
  }

  // If the route is JSON API, it means that JSON API is installed and its
  // services can be used.
  if ($this->moduleHandler
    ->moduleExists('jsonapi')) {

    /** @var \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $rt_repo */
    $rt_repo = $this->container
      ->get('jsonapi.resource_type.repository');
    $rt = $rt_repo
      ->get($entity_type_id, $entity
      ->bundle());
    $type_name = $rt
      ->getTypeName();
    $jsonapi_base_path = $this->container
      ->getParameter('jsonapi.base_path');
    $entry_point_url = Url::fromRoute('jsonapi.resource_list', [], [
      'absolute' => TRUE,
    ])
      ->toString(TRUE);
    $route_name = sprintf('jsonapi.%s.individual', $type_name);
    $individual = Url::fromRoute($route_name, [
      static::getEntityRouteParameterName($route_name, $entity_type_id) => $entity
        ->uuid(),
    ], [
      'absolute' => TRUE,
    ])
      ->toString(TRUE);
    $response
      ->addCacheableDependency($entry_point_url);
    $response
      ->addCacheableDependency($individual);
    $output['jsonapi'] = [
      'individual' => $individual
        ->getGeneratedUrl(),
      'resourceName' => $type_name,
      'pathPrefix' => trim($jsonapi_base_path, '/'),
      'basePath' => $jsonapi_base_path,
      'entryPoint' => $entry_point_url
        ->getGeneratedUrl(),
    ];
    $deprecation_message = 'This property has been deprecated and will be removed in the next version of Decoupled Router. Use @alternative instead.';
    $output['meta'] = [
      'deprecated' => [
        'jsonapi.pathPrefix' => $this
          ->t($deprecation_message, [
          '@alternative' => 'basePath',
        ]),
      ],
    ];
  }
  $response
    ->addCacheableDependency($entity);
  $response
    ->setStatusCode(200);
  $response
    ->setData($output);
  $event
    ->stopPropagation();
}