Skip to content

Commit

Permalink
[#15] Added support for path translator base class.
Browse files Browse the repository at this point in the history
  • Loading branch information
Decipher committed Dec 13, 2020
1 parent c69b800 commit f5906b7
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 204 deletions.
114 changes: 17 additions & 97 deletions src/EventSubscriber/ContactPathTranslatorSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,27 @@
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Url;
use Drupal\decoupled_router\EventSubscriber\RouterPathTranslatorSubscriber;
use Drupal\decoupled_router\EventSubscriber\PathTranslatorBase;
use Drupal\decoupled_router\PathTranslatorEvent;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

/**
* Event subscriber that processes a path translation with the router info.
*/
class ContactPathTranslatorSubscriber extends RouterPathTranslatorSubscriber {
class ContactPathTranslatorSubscriber extends PathTranslatorBase {

/**
* {@inheritdoc}
* {@inheritDoc}
*/
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;
}
if (!$this->moduleHandler->moduleExists('contact')) {
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([
'resolved' => $path,
]);
}
return;
}
catch (MethodNotAllowedException $exception) {
$response->setStatusCode(403);
return;
}
public function getDependencies() {
return ['contact'];
}

/**
* {@inheritDoc}
*/
protected function findEntityAndKeys(array $match_info) {
if ($match_info['_route'] !== 'contact.site_page') {
return;
}
Expand All @@ -58,71 +35,14 @@ public function onPathTranslation(PathTranslatorEvent $event) {
$contact_storage = $entity_type_manager->getStorage('contact_form');
$contact_form = $contact_storage->load($config->get('default_form'));

$route = $match_info[RouteObjectInterface::ROUTE_OBJECT];
$resolved_url = Url::fromRoute($route, [], ['absolute' => TRUE])->toString(TRUE);
$response->addCacheableDependency($resolved_url);

$is_home_path = $this->resolvedPathIsHomePath($resolved_url->getGeneratedUrl());
$response->addCacheableDependency(
(new CacheableMetadata())->setCacheContexts(['url.path.is_front'])
);

$output = [
'resolved' => $resolved_url->getGeneratedUrl(),
'isHomePath' => $is_home_path,
'entity' => [
'canonical' => $resolved_url->getGeneratedUrl(),
'type' => $contact_form->getEntityTypeId(),
'bundle' => $contact_form->bundle(),
'id' => $contact_form->id(),
'uuid' => $contact_form->get('uuid'),
],
'label' => $match_info['_title'],
];

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

/** @var \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $rt_repo */
$rt_repo = $this->container->get('jsonapi.resource_type.repository');
$rt = $rt_repo->get($contact_form_type_id, $contact_form->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, $contact_form_type_id) => $contact_form->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' => [
//phpcs:disable
'jsonapi.pathPrefix' => $this->t($deprecation_message, ['@alternative' => 'basePath']),
],
];
}

$response->addCacheableDependency($contact_form);
$response->setStatusCode(200);
$response->setData($output);
return [$contact_form];
}

$event->stopPropagation();
/**
* {@inheritDoc}
*/
protected function getCanonicalUrl($entity) {
return Url::fromRoute('contact.site_page', [], ['absolute' => TRUE])->toString(TRUE);
}

}
138 changes: 31 additions & 107 deletions src/EventSubscriber/ViewsPathTranslatorSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,133 +5,57 @@
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Url;
use Drupal\decoupled_router\EventSubscriber\RouterPathTranslatorSubscriber;
use Drupal\decoupled_router\EventSubscriber\PathTranslatorBase;
use Drupal\decoupled_router\PathTranslatorEvent;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

/**
* Event subscriber that processes a path translation with the router info.
*/
class ViewsPathTranslatorSubscriber extends RouterPathTranslatorSubscriber {
class ViewsPathTranslatorSubscriber extends PathTranslatorBase {

protected $display;

/**
* {@inheritdoc}
* {@inheritDoc}
*/
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;
}
if (!$this->moduleHandler->moduleExists('jsonapi_views')) {
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([
'resolved' => $path,
]);
}
return;
}
catch (MethodNotAllowedException $exception) {
$response->setStatusCode(403);
return;
protected function findEntityAndKeys(array $match_info) {
if (!$match_info['view_id']) {
return [false];
}

$entity_type_manager = $this->container->get('entity_type.manager');
$views_storage = $entity_type_manager->getStorage('view');
$view = $views_storage->load($match_info['view_id']);

$route = $match_info[RouteObjectInterface::ROUTE_OBJECT];
$resolved_url = Url::fromRoute($route, [], ['absolute' => TRUE])->toString(TRUE);
$response->addCacheableDependency($resolved_url);
$this->display = $view->getDisplay($match_info['display_id']);

$resolved_url = Url::fromRoute($route, [], ['absolute' => TRUE])->toString(TRUE);
$response->addCacheableDependency($resolved_url);

$is_home_path = $this->resolvedPathIsHomePath($resolved_url->getGeneratedUrl());
$response->addCacheableDependency(
(new CacheableMetadata())->setCacheContexts(['url.path.is_front'])
);

$output = [
'resolved' => $resolved_url->getGeneratedUrl(),
'isHomePath' => $is_home_path,
'view' => [
'uuid' => $view->get('uuid'),
'view_id' => $match_info['view_id'],
'display_id' => $match_info['display_id'],
],
'label' => $match_info['_title'],
];

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

/** @var \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface $rt_repo */
$rt_repo = $this->container->get('jsonapi.resource_type.repository');
$rt = $rt_repo->get($view_type_id, $view->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, $view_type_id) => $view->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' => [
//phpcs:disable
'jsonapi.pathPrefix' => $this->t($deprecation_message, ['@alternative' => 'basePath']),
],
];
}

if ($this->moduleHandler->moduleExists('jsonapi_views')) {
$parts = [
'jsonapi_views',
$match_info['view_id'],
$match_info['display_id'],
];
$jsonapi_views_route = implode('.', $parts);
$resolved_jsonapi_views_url = Url::fromRoute($jsonapi_views_route, [], ['absolute' => TRUE])->toString(TRUE);
$response->addCacheableDependency($resolved_jsonapi_views_url);
return [$view, true, null];
}

$output['jsonapi_views'] = $resolved_jsonapi_views_url->getGeneratedUrl();
}
/**
* {@inheritDoc}
*/
protected function getCanonicalUrl() {
return Url::fromUri("internal:/{$this->display['display_options']['path']}", ['absolute' => TRUE])->toString(TRUE);
}

$response->addCacheableDependency($view);
$response->setStatusCode(200);
$response->setData($output);
/**
* {@inheritDoc}
*/
public function getDependencies() {
return ['views'];
}

$event->stopPropagation();
/**
* {@inheritDoc}
*/
protected function getJsonOutput() {
return parent::getJsonOutput() + ['view' => [
'view_id' => $this->matchInfo['view_id'],
'display_id' => $this->matchInfo['display_id'],
]];
}

}

0 comments on commit f5906b7

Please sign in to comment.