Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / content_translation / src / Controller / ContentTranslationController.php
index 190778d42c4bfdd819f771afbbbcdda845e39e7a..3f5891b73a8514ffed987bb71e382c24c32c8c14 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Drupal\content_translation\Controller;
 
+use Drupal\content_translation\ContentTranslationManager;
 use Drupal\content_translation\ContentTranslationManagerInterface;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Controller\ControllerBase;
@@ -87,6 +88,7 @@ class ContentTranslationController extends ControllerBase {
     $handler = $this->entityManager()->getHandler($entity_type_id, 'translation');
     $manager = $this->manager;
     $entity_type = $entity->getEntityType();
+    $use_latest_revisions = $entity_type->isRevisionable() && ContentTranslationManager::isPendingRevisionSupportEnabled($entity_type_id, $entity->bundle());
 
     // Start collecting the cacheability metadata, starting with the entity and
     // later merge in the access result cacheability metadata.
@@ -99,6 +101,9 @@ class ContentTranslationController extends ControllerBase {
 
     $rows = [];
     $show_source_column = FALSE;
+    /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
+    $storage = $this->entityTypeManager()->getStorage($entity_type_id);
+    $default_revision = $storage->load($entity->id());
 
     if ($this->languageManager()->isMultilingual()) {
       // Determine whether the current entity is translatable.
@@ -121,6 +126,25 @@ class ContentTranslationController extends ControllerBase {
         $language_name = $language->getName();
         $langcode = $language->getId();
 
+        // If the entity type is revisionable, we may have pending revisions
+        // with translations not available yet in the default revision. Thus we
+        // need to load the latest translation-affecting revision for each
+        // language to be sure we are listing all available translations.
+        if ($use_latest_revisions) {
+          $entity = $default_revision;
+          $latest_revision_id = $storage->getLatestTranslationAffectedRevisionId($entity->id(), $langcode);
+          if ($latest_revision_id) {
+            /** @var \Drupal\Core\Entity\ContentEntityInterface $latest_revision */
+            $latest_revision = $storage->loadRevision($latest_revision_id);
+            // Make sure we do not list removed translations, i.e. translations
+            // that have been part of a default revision but no longer are.
+            if (!$latest_revision->wasDefaultRevision() || $default_revision->hasTranslation($langcode)) {
+              $entity = $latest_revision;
+            }
+          }
+          $translations = $entity->getTranslationLanguages();
+        }
+
         $add_url = new Url(
           "entity.$entity_type_id.content_translation_add",
           [
@@ -212,24 +236,34 @@ class ContentTranslationController extends ControllerBase {
             $source_name = $this->t('n/a');
           }
           else {
-            $source_name = isset($languages[$source]) ? $languages[$source]->getName() : $this->t('n/a');
-            $delete_access = $entity->access('delete', NULL, TRUE);
-            $translation_access = $handler->getTranslationAccess($entity, 'delete');
-            $cacheability = $cacheability
-              ->merge(CacheableMetadata::createFromObject($delete_access))
-              ->merge(CacheableMetadata::createFromObject($translation_access));
-            if ($entity->access('delete') && $entity_type->hasLinkTemplate('delete-form')) {
-              $links['delete'] = [
-                'title' => $this->t('Delete'),
-                'url' => $entity->urlInfo('delete-form'),
-                'language' => $language,
-              ];
+            /** @var \Drupal\Core\Access\AccessResultInterface $delete_route_access */
+            $delete_route_access = \Drupal::service('content_translation.delete_access')->checkAccess($translation);
+            $cacheability->addCacheableDependency($delete_route_access);
+
+            if ($delete_route_access->isAllowed()) {
+              $source_name = isset($languages[$source]) ? $languages[$source]->getName() : $this->t('n/a');
+              $delete_access = $entity->access('delete', NULL, TRUE);
+              $translation_access = $handler->getTranslationAccess($entity, 'delete');
+              $cacheability
+                ->addCacheableDependency($delete_access)
+                ->addCacheableDependency($translation_access);
+
+              if ($delete_access->isAllowed() && $entity_type->hasLinkTemplate('delete-form')) {
+                $links['delete'] = [
+                  'title' => $this->t('Delete'),
+                  'url' => $entity->urlInfo('delete-form'),
+                  'language' => $language,
+                ];
+              }
+              elseif ($translation_access->isAllowed()) {
+                $links['delete'] = [
+                  'title' => $this->t('Delete'),
+                  'url' => $delete_url,
+                ];
+              }
             }
-            elseif ($translation_access->isAllowed()) {
-              $links['delete'] = [
-                'title' => $this->t('Delete'),
-                'url' => $delete_url,
-              ];
+            else {
+              $this->messenger()->addWarning($this->t('The "Delete translation" action is only available for published translations.'), FALSE);
             }
           }
         }
@@ -330,8 +364,21 @@ class ContentTranslationController extends ControllerBase {
    *   A processed form array ready to be rendered.
    */
   public function add(LanguageInterface $source, LanguageInterface $target, RouteMatchInterface $route_match, $entity_type_id = NULL) {
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
     $entity = $route_match->getParameter($entity_type_id);
 
+    // In case of a pending revision, make sure we load the latest
+    // translation-affecting revision for the source language, otherwise the
+    // initial form values may not be up-to-date.
+    if (!$entity->isDefaultRevision() && ContentTranslationManager::isPendingRevisionSupportEnabled($entity_type_id, $entity->bundle())) {
+      /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
+      $storage = $this->entityTypeManager()->getStorage($entity->getEntityTypeId());
+      $revision_id = $storage->getLatestTranslationAffectedRevisionId($entity->id(), $source->getId());
+      if ($revision_id != $entity->getRevisionId()) {
+        $entity = $storage->loadRevision($revision_id);
+      }
+    }
+
     // @todo Exploit the upcoming hook_entity_prepare() when available.
     // See https://www.drupal.org/node/1810394.
     $this->prepareTranslation($entity, $source, $target);