diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index a38afd7..dbfff7b 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -164,8 +164,12 @@ function content_translation_entity_base_field_info(EntityTypeInterface $entity_ if ($manager->isSupported($entity_type_id)) { $definitions = $manager->getEntityTypeTranslationMetadata($entity_type)->getFieldDefinitions(); $installed_storage_definitions = \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($entity_type_id); - // @todo Consider removing field storage definitions if the entity type has - // no bundle enabled for translation once base field purging is supported. + // By returning already installed field definitions even when no bundle is + // enabled for translation anymore, translation can be enabled again later + // without translation metadata being lost meanwhile. + // @todo Re-evaluate this approach and consider removing field storage + // definitions and the related field data if the entity type has no bundle + // enabled for translation, once base field purging is supported. // See https://www.drupal.org/node/2282119. if (content_translation_enabled($entity_type_id) || array_intersect_key($definitions, $installed_storage_definitions)) { return $definitions; diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php index 2626d58..39f4c96 100644 --- a/core/modules/content_translation/src/ContentTranslationHandler.php +++ b/core/modules/content_translation/src/ContentTranslationHandler.php @@ -8,6 +8,7 @@ namespace Drupal\content_translation; use Drupal\Core\Access\AccessResult; +use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; @@ -22,6 +23,7 @@ * @ingroup entity_api */ class ContentTranslationHandler implements ContentTranslationHandlerInterface { + use DependencySerializationTrait; /** * The type of the entity being translated. @@ -38,11 +40,11 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface { protected $entityType; /** - * A content translation metadata handler instance. + * The content translation manager. * - * @var \Drupal\content_translation\ContentTranslationMetadataInterface + * @var \Drupal\content_translation\ContentTranslationManagerInterface */ - protected $metadata; + protected $manager; /** * Initializes an instance of the content translation controller. @@ -55,7 +57,7 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface { public function __construct(EntityTypeInterface $entity_type, ContentTranslationManagerInterface $manager) { $this->entityTypeId = $entity_type->id(); $this->entityType = $entity_type; - $this->metadata = $manager->getEntityTypeTranslationMetadata($entity_type); + $this->manager = $manager; } /** @@ -66,30 +68,12 @@ public static function createInstance(ContainerInterface $container, EntityTypeI } /** - * Returns the translation metadata for the specified translation. - * - * @param EntityInterface $translation - * The entity translation. - * - * @return ContentTranslationMetadataInterface - * The translation metadata. - */ - protected function getMetadata(EntityInterface $translation) { - // We need this metadata factory method to avoid storing the translation - // manager in the local state, as this would cause the DIC to be serialized - // as part of the entity manager state. - $metadata = clone $this->metadata; - $metadata->setTranslation($translation); - return $metadata; - } - - /** * {@inheritdoc} */ public function retranslate(EntityInterface $entity, $langcode = NULL) { $updated_langcode = !empty($langcode) ? $langcode : $entity->language()->getId(); foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $this->getMetadata($entity->getTranslation($langcode)) + $this->manager->getTranslationMetadata($entity->getTranslation($langcode)) ->setOutdated($langcode != $updated_langcode); } } @@ -234,7 +218,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En ); // A new translation is enabled by default. - $metadata = $this->getMetadata($entity); + $metadata = $this->manager->getTranslationMetadata($entity); $status = $new_translation || $metadata->isPublished(); // If there is only one published translation we cannot unpublish it, // since there would be nothing left to display. @@ -242,7 +226,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En if ($status) { $published = 0; foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $published += $this->getMetadata($entity->getTranslation($langcode)) + $published += $this->manager->getTranslationMetadata($entity->getTranslation($langcode)) ->isPublished(); } $enabled = $published > 1; @@ -422,7 +406,7 @@ public function entityFormEntityBuild($entity_type, EntityInterface $entity, arr $values['name'] = ''; } - $metadata = $this->getMetadata($entity); + $metadata = $this->manager->getTranslationMetadata($entity); $metadata->setAuthor(!empty($values['name']) && ($account = user_load_by_name($values['name'])) ? $account : User::load(0)); $metadata->setPublished(!empty($values['status'])); $metadata->setCreatedTime(!empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME); diff --git a/core/modules/content_translation/src/ContentTranslationManager.php b/core/modules/content_translation/src/ContentTranslationManager.php index b5d108c..66db0e4 100644 --- a/core/modules/content_translation/src/ContentTranslationManager.php +++ b/core/modules/content_translation/src/ContentTranslationManager.php @@ -37,7 +37,7 @@ public function __construct(EntityManagerInterface $manager) { * {@inheritdoc} */ public function getEntityTypeTranslationMetadata(EntityTypeInterface $entity_type) { - return $this->entityManager->getHandler($entity_type->id(), 'content_translation_metadata'); + return clone $this->entityManager->getHandler($entity_type->id(), 'content_translation_metadata'); } /** @@ -45,7 +45,7 @@ public function getEntityTypeTranslationMetadata(EntityTypeInterface $entity_typ */ public function getTranslationMetadata(EntityInterface $translation) { // We need a new instance of the metadata handler wrapping each translation. - $metadata = clone $this->getEntityTypeTranslationMetadata($translation->getEntityType()); + $metadata = $this->getEntityTypeTranslationMetadata($translation->getEntityType()); $metadata->setTranslation($translation); return $metadata; } diff --git a/core/modules/content_translation/src/ContentTranslationMetadata.php b/core/modules/content_translation/src/ContentTranslationMetadata.php index da25eed..99c9c0c 100644 --- a/core/modules/content_translation/src/ContentTranslationMetadata.php +++ b/core/modules/content_translation/src/ContentTranslationMetadata.php @@ -57,7 +57,7 @@ public function getFieldDefinitions() { ->setRevisionable(TRUE) ->setTranslatable(TRUE); - if (!$this->supportsNativeAuthor()) { + if (!$this->hasAuthor()) { $definitions['translation_uid'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Translation author')) ->setDescription(t('The author of this translation.')) @@ -67,7 +67,7 @@ public function getFieldDefinitions() { ->setTranslatable(TRUE); } - if (!$this->supportsNativePublishedStatus()) { + if (!$this->hasPublishedStatus()) { $definitions['translation_status'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Translation status')) ->setDescription(t('A boolean indicating whether the translation is visible to non-translators.')) @@ -76,7 +76,7 @@ public function getFieldDefinitions() { ->setTranslatable(TRUE); } - if (!$this->supportsNativeCreatedTime()) { + if (!$this->hasCreatedTime()) { $definitions['translation_created'] = BaseFieldDefinition::create('created') ->setLabel(t('Translation created time')) ->setDescription(t('The Unix timestamp when the translation was created.')) @@ -84,7 +84,7 @@ public function getFieldDefinitions() { ->setTranslatable(TRUE); } - if (!$this->supportsNativeChangedTime()) { + if (!$this->hasChangedTime()) { $definitions['translation_changed'] = BaseFieldDefinition::create('changed') ->setLabel(t('Translation changed time')) ->setDescription(t('The Unix timestamp when the translation was most recently saved.')) @@ -102,7 +102,7 @@ public function getFieldDefinitions() { * @return bool * TRUE if metadata is natively supported, FALSE otherwise. */ - protected function supportsNativeAuthor() { + protected function hasAuthor() { return is_subclass_of($this->entityType->getClass(), '\Drupal\user\EntityOwnerInterface'); } @@ -112,7 +112,7 @@ protected function supportsNativeAuthor() { * @return bool * TRUE if metadata is natively supported, FALSE otherwise. */ - protected function supportsNativePublishedStatus() { + protected function hasPublishedStatus() { return array_key_exists('status', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id())); } @@ -122,7 +122,7 @@ protected function supportsNativePublishedStatus() { * @return bool * TRUE if metadata is natively supported, FALSE otherwise. */ - protected function supportsNativeChangedTime() { + protected function hasChangedTime() { return is_subclass_of($this->entityType->getClass(), '\Drupal\Core\Entity\EntityChangedInterface'); } @@ -132,7 +132,7 @@ protected function supportsNativeChangedTime() { * @return bool * TRUE if metadata is natively supported, FALSE otherwise. */ - protected function supportsNativeCreatedTime() { + protected function hasCreatedTime() { return array_key_exists('created', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id())); } @@ -187,14 +187,14 @@ public function setOutdated($outdated) { * {@inheritdoc} */ public function getAuthor() { - return $this->supportsNativeAuthor() ? $this->translation->getOwner() : $this->translation->get('translation_uid')->entity; + return $this->hasAuthor() ? $this->translation->getOwner() : $this->translation->get('translation_uid')->entity; } /** * {@inheritdoc} */ public function setAuthor(UserInterface $account) { - if ($this->supportsNativeAuthor()) { + if ($this->hasAuthor()) { $this->translation->setOwner($account); } else { @@ -207,14 +207,14 @@ public function setAuthor(UserInterface $account) { * {@inheritdoc} */ public function isPublished() { - return (bool) $this->translation->get($this->supportsNativePublishedStatus() ? 'status' : 'translation_status')->value; + return (bool) $this->translation->get($this->hasPublishedStatus() ? 'status' : 'translation_status')->value; } /** * {@inheritdoc} */ public function setPublished($published) { - $this->translation->set($this->supportsNativePublishedStatus() ? 'status' : 'translation_status', $published); + $this->translation->set($this->hasPublishedStatus() ? 'status' : 'translation_status', $published); return $this; } @@ -222,14 +222,14 @@ public function setPublished($published) { * {@inheritdoc} */ public function getCreatedTime() { - return $this->translation->get($this->supportsNativeCreatedTime() ? 'created' : 'translation_created')->value; + return $this->translation->get($this->hasCreatedTime() ? 'created' : 'translation_created')->value; } /** * {@inheritdoc} */ public function setCreatedTime($timestamp) { - $this->translation->set($this->supportsNativeCreatedTime() ? 'created' : 'translation_created', $timestamp); + $this->translation->set($this->hasCreatedTime() ? 'created' : 'translation_created', $timestamp); return $this; } @@ -237,14 +237,14 @@ public function setCreatedTime($timestamp) { * {@inheritdoc} */ public function getChangedTime() { - return $this->supportsNativeChangedTime() ? $this->translation->getChangedTime() : $this->translation->get('translation_changed')->value; + return $this->hasChangedTime() ? $this->translation->getChangedTime() : $this->translation->get('translation_changed')->value; } /** * {@inheritdoc} */ public function setChangedTime($timestamp) { - $this->translation->set($this->supportsNativeChangedTime() ? 'changed' : 'translation_changed', $timestamp); + $this->translation->set($this->hasChangedTime() ? 'changed' : 'translation_changed', $timestamp); return $this; } diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php index 2c31c1e..10ea4ed 100644 --- a/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php +++ b/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php @@ -171,6 +171,7 @@ protected function enableTranslation() { drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); + \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /** diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index a043c36..904a3c0 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -36,7 +36,7 @@ * "register" = "Drupal\user\RegisterForm" * }, * "translation" = "Drupal\user\ProfileTranslationHandler", - * "content_translation_metadata" = "Drupal\user\ProfileTranslationMetadata" + * "content_translation_metadata" = "Drupal\user\UserTranslationMetadata" * }, * admin_permission = "administer user", * base_table = "users", diff --git a/core/modules/user/src/ProfileTranslationMetadata.php b/core/modules/user/src/UserTranslationMetadata.php similarity index 73% rename from core/modules/user/src/ProfileTranslationMetadata.php rename to core/modules/user/src/UserTranslationMetadata.php index 7d2c020..69a34d4 100644 --- a/core/modules/user/src/ProfileTranslationMetadata.php +++ b/core/modules/user/src/UserTranslationMetadata.php @@ -12,12 +12,12 @@ /** * Defines the content translation metadata handler for user profiles. */ -class ProfileTranslationMetadata extends ContentTranslationMetadata { +class UserTranslationMetadata extends ContentTranslationMetadata { /** * {@inheritdoc} */ - protected function supportsNativePublishedStatus() { + protected function hasPublishedStatus() { // User status has nothing to do with translations visibility. return FALSE; } @@ -25,7 +25,7 @@ protected function supportsNativePublishedStatus() { /** * {@inheritdoc} */ - protected function supportsNativeCreatedTime() { + protected function hasCreatedTime() { // User creation date has nothing to do with translation creation date. return FALSE; }