X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fcontent_translation%2Fsrc%2FController%2FContentTranslationController.php;h=e5af1c31f43c0b309c600abcc26eba34b84c76ed;hb=9424afc6c1f518c301bf87a23c047d1873435d05;hp=c18eab395a098cb02c81c127ef9ed143c5922975;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;p=yaffs-website diff --git a/web/core/modules/content_translation/src/Controller/ContentTranslationController.php b/web/core/modules/content_translation/src/Controller/ContentTranslationController.php index c18eab395..e5af1c31f 100644 --- a/web/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/web/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -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,37 +126,33 @@ class ContentTranslationController extends ControllerBase { $language_name = $language->getName(); $langcode = $language->getId(); - $add_url = new Url( - "entity.$entity_type_id.content_translation_add", - [ - 'source' => $original, - 'target' => $language->getId(), - $entity_type_id => $entity->id(), - ], - [ - 'language' => $language, - ] - ); - $edit_url = new Url( - "entity.$entity_type_id.content_translation_edit", - [ - 'language' => $language->getId(), - $entity_type_id => $entity->id(), - ], - [ - 'language' => $language, - ] - ); - $delete_url = new Url( - "entity.$entity_type_id.content_translation_delete", - [ - 'language' => $language->getId(), - $entity_type_id => $entity->id(), - ], - [ - 'language' => $language, - ] - ); + // 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(); + } + + $options = ['language' => $language]; + $add_url = $entity->toUrl('drupal:content-translation-add', $options) + ->setRouteParameter('source', $original) + ->setRouteParameter('target', $language->getId()); + $edit_url = $entity->toUrl('drupal:content-translation-edit', $options) + ->setRouteParameter('language', $language->getId()); + $delete_url = $entity->toUrl('drupal:content-translation-delete', $options) + ->setRouteParameter('language', $language->getId()); $operations = [ 'data' => [ '#type' => 'operations', @@ -196,38 +197,50 @@ class ContentTranslationController extends ControllerBase { if (isset($links['edit'])) { $links['edit']['title'] = $this->t('Edit'); } - $status = ['data' => [ - '#type' => 'inline_template', - '#template' => '{% if status %}{{ "Published"|t }}{% else %}{{ "Not published"|t }}{% endif %}{% if outdated %} {{ "outdated"|t }}{% endif %}', - '#context' => [ - 'status' => $metadata->isPublished(), - 'outdated' => $metadata->isOutdated(), + $status = [ + 'data' => [ + '#type' => 'inline_template', + '#template' => '{% if status %}{{ "Published"|t }}{% else %}{{ "Not published"|t }}{% endif %}{% if outdated %} {{ "outdated"|t }}{% endif %}', + '#context' => [ + 'status' => $metadata->isPublished(), + 'outdated' => $metadata->isOutdated(), + ], ], - ]]; + ]; if ($is_original) { $language_name = $this->t('@language_name (Original language)', ['@language_name' => $language_name]); $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); } } } @@ -328,8 +341,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);