Skip to content

Commit

Permalink
fix: make it possible to preview draft-only translations
Browse files Browse the repository at this point in the history
  • Loading branch information
Leksat committed Jan 14, 2025
1 parent ccbe4ef commit f2e7476
Showing 1 changed file with 57 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ public static function getSubscribedEvents() {
}

public function onKernelRequest(RequestEvent $event): void {
$redirect = $this->getMissingDefaultRevisionRedirect($event)
?? $this->getMissingTranslationRedirect($event);
if ($redirect) {
// Add the necessary cache contexts to the response, as redirect
// responses are cached as well.
$metadata = new CacheableMetadata();
$metadata->addCacheContexts([
'languages:language_interface',
'url.query_args',
'user',
]);
$redirect->addCacheableDependency($metadata);
if ($this->routeMatch->getRouteName() === 'entity.node.canonical') {
$node = $this->routeMatch->getCurrentRouteMatch()->getParameter('node');
$redirect->addCacheableDependency($node);
}

$event->setResponse($redirect);
}
}

private function getMissingTranslationRedirect(RequestEvent $event): ?TrustedRedirectResponse {
// In case the user tries to access a node in a language entity is not
// translated to, we redirect to the entity in the original language and
// display a warning message.
Expand All @@ -57,16 +79,43 @@ public function onKernelRequest(RequestEvent $event): void {
}
$urlString = $url->toString() . '?' . $queryString . 'content_language_not_available=true&requested_language=' . $requestedLanguageId;

// Add the necessary cache contexts to the response, as redirect
// responses are cached as well.
$metadata = new CacheableMetadata();
$metadata->addCacheContexts(['languages:language_interface', 'url.query_args']);
$response = new TrustedRedirectResponse($urlString);
$response->addCacheableDependency($entity);
$response->addCacheableDependency($metadata);
return new TrustedRedirectResponse($urlString);
}
}

$event->setResponse($response);
return NULL;
}

private function getMissingDefaultRevisionRedirect(RequestEvent $event): ?TrustedRedirectResponse {
// This spaghetti code detects if user is trying to view a translation that
// is a draft only and does not have a published revision on the canonical
// route.
// Why do we do it: The content translation overview page links to
// `/{lang}/node/{nid}`, but in the case mentioned above, the canonical
// route displays the content in the original language. Which is quite
// confusing.
if ($this->routeMatch->getRouteName() === 'entity.node.canonical') {
$entity = $this->routeMatch->getCurrentRouteMatch()->getParameter('node');
$requestedLanguageId = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
if ($entity->language()->getId() != $requestedLanguageId) {
$storage = \Drupal::entityTypeManager()->getStorage('node');
$latestRevisionId = $storage->getLatestTranslationAffectedRevisionId($entity->id(), $requestedLanguageId);
if ($latestRevisionId) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $latestRevision */
$latestRevision = $storage->loadRevision($latestRevisionId);
$translations = $latestRevision->getTranslationLanguages();
if (array_key_exists($requestedLanguageId, $translations)) {
$latestRevision = $latestRevision->getTranslation($requestedLanguageId);
// Bingo! We found the target case. Redirect to the latest revision.
if ($latestRevision->access('view')) {
$url = $latestRevision->toUrl('latest-version')->toString();
return new TrustedRedirectResponse($url);
}
}
}
}
}
return NULL;
}

}

0 comments on commit f2e7476

Please sign in to comment.