diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 00c9d73..4e8a190 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -345,15 +345,17 @@ protected function buildBaseFieldDefinitions($entity_type_id) { // Invoke alter hook. $this->moduleHandler->alter('entity_base_field_info', $base_field_definitions, $entity_type); - // Ensure all basic fields are not defined as translatable. - $keys = array_intersect_key(array_filter($entity_type->getKeys()), array_flip(array('id', 'revision', 'uuid', 'bundle'))); - $untranslatable_fields = array_flip(array('langcode') + $keys); - foreach ($base_field_definitions as $field_name => $definition) { - if (isset($untranslatable_fields[$field_name]) && $definition->isTranslatable()) { - throw new \LogicException(String::format('The @field field cannot be translatable.', array('@field' => $definition->getLabel()))); + // Ensure defined entity keys are there and have proper revisionable and + // translatable values. + $keys = array_filter($entity_type->getKeys() + array('langcode' => 'langcode')); + foreach ($keys as $key => $field_name) { + if (isset($base_field_definitions[$field_name]) && in_array($key, array('id', 'revision', 'uuid', 'bundle')) && $base_field_definitions[$field_name]->isRevisionable()) { + throw new \LogicException(String::format('The @field field cannot be revisionable as it is used as @key entity key.', array('@field' => $base_field_definitions[$field_name]->getLabel(), '@key' => $key))); + } + if (isset($base_field_definitions[$field_name]) && in_array($key, array('id', 'revision', 'uuid', 'bundle', 'langcode')) && $base_field_definitions[$field_name]->isTranslatable()) { + throw new \LogicException(String::format('The @field field cannot be translatable as it is used as @key entity key.', array('@field' => $base_field_definitions[$field_name]->getLabel(), '@key' => $key))); } } - return $base_field_definitions; } diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php index 3968624..b5a2c10 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinition.php +++ b/core/lib/Drupal/Core/Field/FieldDefinition.php @@ -161,7 +161,7 @@ public function isTranslatable() { * @param bool $translatable * Whether the field is translatable. * - * @return static + * @return $this * The object itself for chaining. */ public function setTranslatable($translatable) { @@ -172,6 +172,27 @@ public function setTranslatable($translatable) { /** * {@inheritdoc} */ + public function isRevisionable() { + return !empty($this->definition['revisionable']); + } + + /** + * Sets whether the field is revisionable. + * + * @param bool $revisionable + * Whether the field is revisionable. + * + * @return $this + * The object itself for chaining. + */ + public function setRevisionable($revisionable) { + $this->definition['revisionable'] = $revisionable; + return $this; + } + + /** + * {@inheritdoc} + */ public function getCardinality() { // @todo: Allow to control this. return isset($this->definition['cardinality']) ? $this->definition['cardinality'] : 1; diff --git a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php index 06de3c6..1a89c64 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php +++ b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php @@ -112,6 +112,14 @@ public function getSetting($setting_name); public function isTranslatable(); /** + * Returns whether the field is revisionable. + * + * @return bool + * TRUE if the field is revisionable. + */ + public function isRevisionable(); + + /** * Returns whether the display for the field can be configured. * * @param string $display_context diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php index ae8d4fc..2a7d5e5 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php @@ -561,6 +561,14 @@ public function isTranslatable() { } /** + * {@inheritdoc} + */ + public function isRevisionable() { + // All configurable fields are revisionable. + return TRUE; + } + + /** * Sets whether the field is translatable. * * @param bool $translatable diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php index 35bef11..349bd79 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php @@ -508,6 +508,13 @@ public function isTranslatable() { /** * {@inheritdoc} */ + public function isRevisionable() { + return $this->field->isRevisionable(); + } + + /** + * {@inheritdoc} + */ protected function linkTemplates() { $link_templates = parent::linkTemplates(); if (\Drupal::moduleHandler()->moduleExists('field_ui')) { diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index da4b174..bac1cb0 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -362,6 +362,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The title of this node, always treated as non-markup plain text.')) ->setRequired(TRUE) ->setTranslatable(TRUE) + ->setRevisionable(TRUE) ->setSettings(array( 'default_value' => '', 'max_length' => 255, @@ -380,6 +381,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['uid'] = FieldDefinition::create('entity_reference') ->setLabel(t('User ID')) ->setDescription(t('The user ID of the node author.')) + ->setRevisionable(TRUE) ->setSettings(array( 'target_type' => 'user', 'default_value' => 0, @@ -387,38 +389,46 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['status'] = FieldDefinition::create('boolean') ->setLabel(t('Publishing status')) - ->setDescription(t('A boolean indicating whether the node is published.')); + ->setDescription(t('A boolean indicating whether the node is published.')) + ->setRevisionable(TRUE); $fields['created'] = FieldDefinition::create('created') ->setLabel(t('Created')) - ->setDescription(t('The time that the node was created.')); + ->setDescription(t('The time that the node was created.')) + ->setRevisionable(TRUE); $fields['changed'] = FieldDefinition::create('changed') ->setLabel(t('Changed')) - ->setDescription(t('The time that the node was last edited.')); + ->setDescription(t('The time that the node was last edited.')) + ->setRevisionable(TRUE); $fields['promote'] = FieldDefinition::create('boolean') ->setLabel(t('Promote')) - ->setDescription(t('A boolean indicating whether the node should be displayed on the front page.')); + ->setDescription(t('A boolean indicating whether the node should be displayed on the front page.')) + ->setRevisionable(TRUE); $fields['sticky'] = FieldDefinition::create('boolean') ->setLabel(t('Sticky')) - ->setDescription(t('A boolean indicating whether the node should be displayed at the top of lists in which it appears.')); + ->setDescription(t('A boolean indicating whether the node should be displayed at the top of lists in which it appears.')) + ->setRevisionable(TRUE); $fields['revision_timestamp'] = FieldDefinition::create('timestamp') ->setLabel(t('Revision timestamp')) ->setDescription(t('The time that the current revision was created.')) - ->setQueryable(FALSE); + ->setQueryable(FALSE) + ->setRevisionable(TRUE); $fields['revision_uid'] = FieldDefinition::create('entity_reference') ->setLabel(t('Revision user ID')) ->setDescription(t('The user ID of the author of the current revision.')) ->setSettings(array('target_type' => 'user')) - ->setQueryable(FALSE); + ->setQueryable(FALSE) + ->setRevisionable(TRUE); $fields['log'] = FieldDefinition::create('string') ->setLabel(t('Log')) - ->setDescription(t('The log entry explaining the changes in this revision.')); + ->setDescription(t('The log entry explaining the changes in this revision.')) + ->setRevisionable(TRUE); return $fields; } diff --git a/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php b/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php index 5ddd924..a5e0f6f 100644 --- a/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/FieldDefinitionTest.php @@ -171,6 +171,18 @@ public function testFieldTranslatable() { } /** + * Tests field revisionable methods. + */ + public function testFieldRevisionable() { + $definition = FieldDefinition::create($this->fieldType); + $this->assertFalse($definition->isRevisionable()); + $definition->setRevisionable(TRUE); + $this->assertTrue($definition->isRevisionable()); + $definition->setRevisionable(FALSE); + $this->assertFalse($definition->isRevisionable()); + } + + /** * Tests field cardinality. */ public function testFieldCardinality() {