diff --git a/access_unpublished.module b/access_unpublished.module index 09bbf0e..a4b19fa 100644 --- a/access_unpublished.module +++ b/access_unpublished.module @@ -86,3 +86,42 @@ function access_unpublished_form_alter(&$form, FormStateInterface $form_state, $ ->getInstanceFromDefinition(AccessUnpublishedForm::class) ->formAlter($form, $form_state, $form_id); } + +/** + * Implements hook_language_fallback_candidates_entity_view_alter(). + */ +function access_unpublished_language_fallback_candidates_entity_view_alter(&$candidates, $context) { + if (\Drupal::moduleHandler()->moduleExists('content_translation')) { + /** @var EntityInterface $entity */ + $entity = $context['data']; + $entity_type_id = $entity->getEntityTypeId(); + $permission = 'access_unpublished ' . $entity_type_id . ' ' . $entity->bundle(); + $current_user = \Drupal::currentUser(); + // If the current user does not have permission to access unpublished + // content via token, then allow content_translation to process fallback + // candidates. + // This is a bit incomplete since this is invoked during route parameter + // expansion, so we can't verify within the context of this callback whether + // or not we are specifically on the latest_version route, which is the only + // time we actually care about processing this. + if (!$current_user->hasPermission($permission)) { + content_translation_language_fallback_candidates_entity_view_alter($candidates, $context); + } + } +} + +/** + * Implements hook_module_implements_alter(). + */ +function access_unpublished_module_implements_alter(&$implementations, $hook) { + if ('language_fallback_candidates_entity_view_alter' == $hook) { + // Need to unset the content_translation implementation of this callback + // since it will always unset the current page's language as a valid + // translation callback if the translation is not published. Since this + // module is specifically meant to view unpublished content, we can't allow + // content_translation to do what it wants to do. + // See access_unpublished_language_fallback_candidates_entity_view_alter for + // further details. + unset($implementations['content_translation']); + } +}