diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 82b578b48956d0bddb02517b5b0e6b58c8061b7a..51aaec9996dd36f5c3b74a80f44c0deb560238a3 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -207,3 +207,16 @@ function comment_update_8600() { $field_storage_definition->setDefaultValueCallback(Comment::class . '::getDefaultHostname'); $entity_definition_update_manager->updateFieldStorageDefinition($field_storage_definition); } + +/** + * Set the 'owner' entity key and update the field. + */ +function comment_update_8601() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('comment'); + $keys = $entity_type->getKeys(); + $keys['owner'] = 'uid'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); + $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'comment')); +} diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 98562717614c0428e89bf90ebcd155eb7127e4e2..58e4229b1a4e82ae61073cc0dbfa704521495977 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -13,7 +13,7 @@ use Drupal\Core\Field\BaseFieldDefinition; use Drupal\field\Entity\FieldStorageConfig; use Drupal\user\Entity\User; -use Drupal\user\UserInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the comment entity class. @@ -52,6 +52,7 @@ * "langcode" = "langcode", * "uuid" = "uuid", * "published" = "status", + * "owner" = "uid", * }, * links = { * "canonical" = "/comment/{comment}", @@ -70,6 +71,7 @@ class Comment extends ContentEntityBase implements CommentInterface { use EntityChangedTrait; + use EntityOwnerTrait; use EntityPublishedTrait; /** @@ -221,6 +223,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ $fields = parent::baseFieldDefinitions($entity_type); $fields += static::publishedBaseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); $fields['cid']->setLabel(t('Comment ID')) ->setDescription(t('The comment ID.')); @@ -256,12 +259,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ]) ->setDisplayConfigurable('form', TRUE); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('User ID')) - ->setDescription(t('The user ID of the comment author.')) - ->setTranslatable(TRUE) - ->setSetting('target_type', 'user') - ->setDefaultValue(0); + $fields['uid'] + ->setDescription(t('The user ID of the comment author.')); $fields['name'] = BaseFieldDefinition::create('string') ->setLabel(t('Name')) @@ -320,6 +319,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { return $fields; } + /** + * {@inheritdoc} + */ + public static function getDefaultEntityOwner() { + return 0; + } + /** * {@inheritdoc} */ @@ -524,29 +530,6 @@ public function getOwner() { return $user; } - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->get('uid')->target_id; - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->set('uid', $account->id()); - return $this; - } - /** * Get the comment type ID for this comment. * diff --git a/core/modules/comment/tests/src/Functional/Hal/CommentHalJsonTestBase.php b/core/modules/comment/tests/src/Functional/Hal/CommentHalJsonTestBase.php index a9cf1c24256fd66610b6fc7224ed9fff779df0f7..ca19d31cf527a59f9d2ab59544a94a2001ac33e9 100644 --- a/core/modules/comment/tests/src/Functional/Hal/CommentHalJsonTestBase.php +++ b/core/modules/comment/tests/src/Functional/Hal/CommentHalJsonTestBase.php @@ -42,8 +42,8 @@ abstract class CommentHalJsonTestBase extends CommentResourceTestBase { 'thread' => NULL, 'entity_type' => NULL, 'field_name' => NULL, - 'entity_id' => NULL, 'uid' => "The 'administer comments' permission is required.", + 'entity_id' => NULL, ]; /** diff --git a/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php b/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php index 7d1abdbb680536aca73af637529e33edb17f66af..6752634151055aa5e60694c154891e7e25f8ce1e 100644 --- a/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php +++ b/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php @@ -31,9 +31,9 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase { */ protected static $patchProtectedFieldNames = [ 'status' => "The 'administer comments' permission is required.", + 'uid' => "The 'administer comments' permission is required.", 'pid' => NULL, 'entity_id' => NULL, - 'uid' => "The 'administer comments' permission is required.", 'name' => "The 'administer comments' permission is required.", 'homepage' => "The 'administer comments' permission is required.", 'created' => "The 'administer comments' permission is required.", diff --git a/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php b/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php index d68b1e540cad94ae468abb4d5cbd78bd536f3d74..45c2115f92a983a141eb38449ce556f74827c07b 100644 --- a/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php +++ b/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php @@ -72,4 +72,22 @@ public function testPublishedEntityKey() { $this->assertTrue(\Drupal::database()->schema()->indexExists('comment_field_data', 'comment__status_comment_type')); } + /** + * Tests that the comment entity type has an 'owner' entity key. + * + * @see comment_update_8600() + */ + public function testOwnerEntityKey() { + // Check that the 'owner' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('comment'); + $this->assertFalse($entity_type->getKey('owner')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('comment'); + $this->assertEquals('uid', $entity_type->getKey('owner')); + } + } diff --git a/core/modules/content_moderation/content_moderation.install b/core/modules/content_moderation/content_moderation.install index ddeecb5624eef13378e20263dd5c546c2c7a92d5..e60fc59927ced6324a4b747cf51b488d7b7a7254 100644 --- a/core/modules/content_moderation/content_moderation.install +++ b/core/modules/content_moderation/content_moderation.install @@ -29,3 +29,16 @@ function content_moderation_update_8401() { $database_schema->dropTable('content_revision_tracker'); } } + +/** + * Set the 'owner' entity key and update the field. + */ +function content_moderation_update_8600() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('content_moderation_state'); + $keys = $entity_type->getKeys(); + $keys['owner'] = 'uid'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); + $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'content_moderation_state')); +} diff --git a/core/modules/content_moderation/src/Entity/ContentModerationState.php b/core/modules/content_moderation/src/Entity/ContentModerationState.php index abb92eb8411ebedef8196d35f17e676dc1133cc3..48fde7b0f70000716e611725ca8b36e5ce4fe238 100644 --- a/core/modules/content_moderation/src/Entity/ContentModerationState.php +++ b/core/modules/content_moderation/src/Entity/ContentModerationState.php @@ -7,7 +7,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\TypedData\TranslatableInterface; -use Drupal\user\UserInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the Content moderation state entity. @@ -37,6 +37,7 @@ * "revision" = "revision_id", * "uuid" = "uuid", * "uid" = "uid", + * "owner" = "uid", * "langcode" = "langcode", * } * ) @@ -48,18 +49,18 @@ */ class ContentModerationState extends ContentEntityBase implements ContentModerationStateInterface { + use EntityOwnerTrait; + /** * {@inheritdoc} */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') + $fields['uid'] ->setLabel(t('User')) ->setDescription(t('The username of the entity creator.')) - ->setSetting('target_type', 'user') - ->setDefaultValueCallback('Drupal\content_moderation\Entity\ContentModerationState::getCurrentUserId') - ->setTranslatable(TRUE) ->setRevisionable(TRUE); $fields['workflow'] = BaseFieldDefinition::create('entity_reference') @@ -98,36 +99,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { return $fields; } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->getEntityKey('uid'); - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->set('uid', $account->id()); - return $this; - } - /** * Creates or updates an entity's moderation state whilst saving that entity. * @@ -185,10 +156,14 @@ public static function loadFromModeratedEntity(EntityInterface $entity) { * * @see \Drupal\content_moderation\Entity\ContentModerationState::baseFieldDefinitions() * + * @deprecated The ::getCurrentUserId method is deprecated in 8.6.x and will + * be removed before 9.0.0. + * * @return array * An array of default values. */ public static function getCurrentUserId() { + @trigger_error('The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0.', E_USER_DEPRECATED); return [\Drupal::currentUser()->id()]; } diff --git a/core/modules/content_moderation/tests/src/Functional/Update/ContentModerationUpdateTest.php b/core/modules/content_moderation/tests/src/Functional/Update/ContentModerationUpdateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..02b15e8703d0165694a64c542bf378571d9b2f59 --- /dev/null +++ b/core/modules/content_moderation/tests/src/Functional/Update/ContentModerationUpdateTest.php @@ -0,0 +1,43 @@ +<?php + +namespace Drupal\Tests\content_moderation\Functional\Update; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; + +/** + * Tests that content moderation settings are updated during database updates. + * + * @group content_moderation + * @group legacy + */ +class ContentModerationUpdateTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.4.0-content_moderation_installed.php', + ]; + } + + /** + * Tests that the content moderation state entity has an 'owner' entity key. + * + * @see content_moderation_update_8600() + */ + public function testOwnerEntityKey() { + // Check that the 'owner' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('content_moderation_state'); + $this->assertFalse($entity_type->getKey('owner')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('content_moderation_state'); + $this->assertEquals('uid', $entity_type->getKey('owner')); + } + +} diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php index 8574ad6a171b4c60ce082132835b0b084090e862..c32b1ae70ad055ded6cc8174910dde7f0ebf21f6 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php @@ -616,6 +616,16 @@ public function testRevisionDefaultState($entity_type_id) { $this->assertEquals($entity->getLoadedRevisionId(), $cms_entity->get('content_entity_revision_id')->value); } + /** + * Tests the legacy method used as the default entity owner. + * + * @group legacy + * @expectedDeprecation The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0. + */ + public function testGetCurrentUserId() { + $this->assertEquals(['0'], ContentModerationState::getCurrentUserId()); + } + /** * Creates an entity. * diff --git a/core/modules/file/file.install b/core/modules/file/file.install index 6274efc7c912f52ffe9697085ce4b45e3a8dc8f9..cca8249a8f7526b9ec841bf4083bb0514fdbf29f 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -164,3 +164,16 @@ function file_update_8001() { } } } + +/** + * Set the 'owner' entity key and update the field. + */ +function file_update_8600() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('file'); + $keys = $entity_type->getKeys(); + $keys['owner'] = 'uid'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); + $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'file')); +} diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php index 33f6d744cc2b36e980a6ea4588aad9d74c403aaa..92aa436423eafbe6470d32a889e4201f0ad894b7 100644 --- a/core/modules/file/src/Entity/File.php +++ b/core/modules/file/src/Entity/File.php @@ -8,7 +8,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\file\FileInterface; -use Drupal\user\UserInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the file entity class. @@ -36,13 +36,15 @@ * "id" = "fid", * "label" = "filename", * "langcode" = "langcode", - * "uuid" = "uuid" + * "uuid" = "uuid", + * "owner" = "uid", * } * ) */ class File extends ContentEntityBase implements FileInterface { use EntityChangedTrait; + use EntityOwnerTrait; /** * {@inheritdoc} @@ -116,36 +118,6 @@ public function getCreatedTime() { return $this->get('created')->value; } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->get('uid')->target_id; - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->set('uid', $account->id()); - return $this; - } - /** * {@inheritdoc} */ @@ -232,6 +204,7 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); $fields['fid']->setLabel(t('File ID')) ->setDescription(t('The file ID.')); @@ -241,10 +214,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['langcode']->setLabel(t('Language code')) ->setDescription(t('The file language code.')); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('User ID')) - ->setDescription(t('The user ID of the file.')) - ->setSetting('target_type', 'user'); + $fields['uid'] + ->setDescription(t('The user ID of the file.')); $fields['filename'] = BaseFieldDefinition::create('string') ->setLabel(t('Filename')) @@ -284,4 +255,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { return $fields; } + /** + * {@inheritdoc} + */ + public static function getDefaultEntityOwner() { + return NULL; + } + } diff --git a/core/modules/file/src/FileStorageSchema.php b/core/modules/file/src/FileStorageSchema.php index 17e909ab22200d282dd015e9fa7e39de826e21d4..f03d4520295652928194cf41d06265c2b46c9999 100644 --- a/core/modules/file/src/FileStorageSchema.php +++ b/core/modules/file/src/FileStorageSchema.php @@ -26,6 +26,11 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st break; } } + // Entity keys automatically have not null assigned to TRUE, but for the + // file entity, NULL is a valid value for uid. + if ($field_name === 'uid') { + $schema['fields']['uid']['not null'] = FALSE; + } return $schema; } diff --git a/core/modules/file/tests/src/Functional/Update/FileUpdateTest.php b/core/modules/file/tests/src/Functional/Update/FileUpdateTest.php index 5a35d63693f6467746f3b360bb80900ddbf37089..974ec63da66e32be7347e3a2dfaf3e7126bd8e4e 100644 --- a/core/modules/file/tests/src/Functional/Update/FileUpdateTest.php +++ b/core/modules/file/tests/src/Functional/Update/FileUpdateTest.php @@ -56,4 +56,22 @@ public function testPostUpdate8001() { $this->assertEqual($formatter_settings, ['use_description_as_link_text' => FALSE]); } + /** + * Tests that the file entity type has an 'owner' entity key. + * + * @see file_update_8600() + */ + public function testOwnerEntityKey() { + // Check that the 'owner' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('file'); + $this->assertFalse($entity_type->getKey('owner')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('file'); + $this->assertEqual('uid', $entity_type->getKey('owner')); + } + } diff --git a/core/modules/media/media.install b/core/modules/media/media.install index d3386ea35a77564b99955b53a040516f15170924..58c8677f4f32b053f3e7832a854b449deb187afe 100644 --- a/core/modules/media/media.install +++ b/core/modules/media/media.install @@ -163,3 +163,16 @@ function media_update_8600() { ->set('oembed_providers_url', 'https://oembed.com/providers.json') ->save(TRUE); } + +/** + * Set the 'owner' entity key and update the field. + */ +function media_update_8601() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('media'); + $keys = $entity_type->getKeys(); + $keys['owner'] = 'uid'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); + $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'media')); +} diff --git a/core/modules/media/src/Entity/Media.php b/core/modules/media/src/Entity/Media.php index 1bbaf0881d22d4dad8e8dfd54a86ca00b4e192a1..ab1f070a1a9214845f7577a36fab420a1c8f52a0 100644 --- a/core/modules/media/src/Entity/Media.php +++ b/core/modules/media/src/Entity/Media.php @@ -10,7 +10,7 @@ use Drupal\media\MediaInterface; use Drupal\media\MediaSourceEntityConstraintsInterface; use Drupal\media\MediaSourceFieldConstraintsInterface; -use Drupal\user\UserInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the media entity class. @@ -60,6 +60,7 @@ * "langcode" = "langcode", * "uuid" = "uuid", * "published" = "status", + * "owner" = "uid", * }, * revision_metadata_keys = { * "revision_user" = "revision_user", @@ -85,6 +86,7 @@ */ class Media extends EditorialContentEntityBase implements MediaInterface { + use EntityOwnerTrait; use StringTranslationTrait; /** @@ -130,34 +132,6 @@ public function setCreatedTime($timestamp) { return $this->set('created', $timestamp); } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - return $this->set('uid', $account->id()); - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->get('uid')->target_id; - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - return $this->set('uid', $uid); - } - /** * {@inheritdoc} */ @@ -453,6 +427,7 @@ public function validate() { */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); $fields['name'] = BaseFieldDefinition::create('string') ->setLabel(t('Name')) @@ -484,13 +459,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDisplayConfigurable('view', TRUE) ->setReadOnly(TRUE); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') + $fields['uid'] ->setLabel(t('Authored by')) ->setDescription(t('The user ID of the author.')) ->setRevisionable(TRUE) - ->setDefaultValueCallback(static::class . '::getCurrentUserId') - ->setSetting('target_type', 'user') - ->setTranslatable(TRUE) ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, @@ -551,10 +523,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { * * @see ::baseFieldDefinitions() * + * @deprecated The ::getCurrentUserId method is deprecated in 8.6.x and will + * be removed before 9.0.0. + * * @return int[] * An array of default values. */ public static function getCurrentUserId() { + @trigger_error('The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0.', E_USER_DEPRECATED); return [\Drupal::currentUser()->id()]; } diff --git a/core/modules/media/tests/src/Functional/Update/MediaUpdateTest.php b/core/modules/media/tests/src/Functional/Update/MediaUpdateTest.php index 4d4c3ea76f45f6000f7a396d47077da1e051598f..655ff658502b85344264ccde77c03e71ddaf843f 100644 --- a/core/modules/media/tests/src/Functional/Update/MediaUpdateTest.php +++ b/core/modules/media/tests/src/Functional/Update/MediaUpdateTest.php @@ -62,4 +62,22 @@ public function testOEmbedConfig() { $this->assertSame('', $config->get('iframe_domain')); } + /** + * Tests that the media entity type has an 'owner' entity key. + * + * @see media_update_8600() + */ + public function testOwnerEntityKey() { + // Check that the 'owner' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('media'); + $this->assertFalse($entity_type->getKey('owner')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('media'); + $this->assertEquals('uid', $entity_type->getKey('owner')); + } + } diff --git a/core/modules/media/tests/src/Kernel/MediaTest.php b/core/modules/media/tests/src/Kernel/MediaTest.php index 9c7ca28eef9a3ec4a222a1dc653904151e0b60f7..4997bb67fa25ccab19bfe81dc27bcf41069d85d5 100644 --- a/core/modules/media/tests/src/Kernel/MediaTest.php +++ b/core/modules/media/tests/src/Kernel/MediaTest.php @@ -34,4 +34,14 @@ public function testNameBaseField() { $this->assertSame($field_definitions['name']->getDisplayOptions('view'), ['region' => 'hidden']); } + /** + * Tests the legacy method used as the default entity owner. + * + * @group legacy + * @expectedDeprecation The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0. + */ + public function testGetCurrentUserId() { + $this->assertEquals(['1'], Media::getCurrentUserId()); + } + } diff --git a/core/modules/node/node.install b/core/modules/node/node.install index 9b0cda8e56777fd4731613fc12f85334340a743e..2463b21646ff3a8d03750ff87c4c9de61082ed4d 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -267,3 +267,16 @@ function node_update_8401() { node_access_needs_rebuild(TRUE); } } + +/** + * Set the 'owner' entity key and update the field. + */ +function node_update_8600() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('node'); + $keys = $entity_type->getKeys(); + $keys['owner'] = 'uid'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); + $definition_update_manager->updateFieldStorageDefinition($definition_update_manager->getFieldStorageDefinition('uid', 'node')); +} diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index 827c459f724e8a3a5bf6c9af603ef2e608efff0a..b3d19d4e89ee647d7098b7729425b40cff79b536 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -8,7 +8,7 @@ use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Session\AccountInterface; use Drupal\node\NodeInterface; -use Drupal\user\UserInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the node entity class. @@ -59,6 +59,7 @@ * "status" = "status", * "published" = "status", * "uid" = "uid", + * "owner" = "uid", * }, * revision_metadata_keys = { * "revision_user" = "revision_uid", @@ -82,6 +83,8 @@ */ class Node extends EditorialContentEntityBase implements NodeInterface { + use EntityOwnerTrait; + /** * Whether the node is being previewed or not. * @@ -250,36 +253,6 @@ public function setSticky($sticky) { return $this; } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->getEntityKey('uid'); - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->set('uid', $account->id()); - return $this; - } - /** * {@inheritdoc} */ @@ -300,6 +273,7 @@ public function setRevisionAuthorId($uid) { */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); $fields['title'] = BaseFieldDefinition::create('string') ->setLabel(t('Title')) @@ -318,13 +292,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ]) ->setDisplayConfigurable('form', TRUE); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') + $fields['uid'] ->setLabel(t('Authored by')) ->setDescription(t('The username of the content author.')) ->setRevisionable(TRUE) - ->setSetting('target_type', 'user') - ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId') - ->setTranslatable(TRUE) ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', @@ -409,10 +380,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { * * @see ::baseFieldDefinitions() * + * @deprecated The ::getCurrentUserId method is deprecated in 8.6.x and will + * be removed before 9.0.0. + * * @return array * An array of default values. */ public static function getCurrentUserId() { + @trigger_error('The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0.', E_USER_DEPRECATED); return [\Drupal::currentUser()->id()]; } diff --git a/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php b/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php index 8f53f9b628066f19ef22e1ba330f7f01131adfd9..180215b8fb24922f98905499dfd4f43b2d833f2d 100644 --- a/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php +++ b/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php @@ -65,4 +65,22 @@ public function testStatusCheckbox() { } } + /** + * Tests that the node entity type has an 'owner' entity key. + * + * @see node_update_8600() + */ + public function testOwnerEntityKey() { + // Check that the 'owner' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node'); + $this->assertFalse($entity_type->getKey('owner')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node'); + $this->assertEquals('uid', $entity_type->getKey('owner')); + } + } diff --git a/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php b/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php index 7c7bc03348846276e714f0ee6aa52e7b9def7610..1d781c6f56026a5f0d90d15176842120ce42d653 100644 --- a/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php +++ b/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php @@ -53,7 +53,7 @@ public function testFieldOverrides() { $uid_field = \Drupal::entityManager()->getBaseFieldDefinitions('node')['uid']; $config = $uid_field->getConfig('ponies'); $config->save(); - $this->assertEqual($config->get('default_value_callback'), 'Drupal\node\Entity\Node::getCurrentUserId'); + $this->assertEquals($config->get('default_value_callback'), 'Drupal\node\Entity\Node::getDefaultEntityOwner'); /** @var \Drupal\node\NodeInterface $node */ $node = Node::create(['type' => 'ponies']); $owner = $node->getOwner(); diff --git a/core/modules/node/tests/src/Kernel/NodeOwnerTest.php b/core/modules/node/tests/src/Kernel/NodeOwnerTest.php index c12f3115c1601e4b755064af156296e097c3f1cf..7d54d98012d015d1acef7375c53a11d919c6a2d5 100644 --- a/core/modules/node/tests/src/Kernel/NodeOwnerTest.php +++ b/core/modules/node/tests/src/Kernel/NodeOwnerTest.php @@ -6,6 +6,7 @@ use Drupal\language\Entity\ConfigurableLanguage; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; +use Drupal\user\Entity\User; /** * Tests node owner functionality. @@ -75,4 +76,36 @@ public function testOwner() { $this->assertEqual(0, $italian->getOwnerId()); } + /** + * Test an unsaved node owner. + */ + public function testUnsavedNodeOwner() { + $user = User::create([ + 'name' => 'foo', + ]); + $node = Node::create([ + 'type' => 'page', + 'title' => $this->randomMachineName(), + ]); + // Set the node owner while the user is unsaved and then immediately save + // the user and node. + $node->setOwner($user); + $user->save(); + $node->save(); + + // The ID assigned to the newly saved user will now be the owner ID of the + // node. + $this->assertEquals($user->id(), $node->getOwnerId()); + } + + /** + * Tests the legacy method used as the default entity owner. + * + * @group legacy + * @expectedDeprecation The ::getCurrentUserId method is deprecated in 8.6.x and will be removed before 9.0.0. + */ + public function testGetCurrentUserId() { + $this->assertEquals(['0'], Node::getCurrentUserId()); + } + } diff --git a/core/modules/user/src/EntityOwnerTrait.php b/core/modules/user/src/EntityOwnerTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..ad55d0f3dc37ed82fd0687e2298e082a0c3cb2aa --- /dev/null +++ b/core/modules/user/src/EntityOwnerTrait.php @@ -0,0 +1,90 @@ +<?php + +namespace Drupal\user; + +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Provides a trait for entities that have an owner. + */ +trait EntityOwnerTrait { + + /** + * Returns an array of base field definitions for entity owners. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * The entity type to add the owner field to. + * + * @return \Drupal\Core\Field\BaseFieldDefinition[] + * An array of base field definitions. + * + * @throws \Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException + * Thrown when the entity type does not implement EntityOwnerInterface or + * if it does not have an "owner" entity key. + */ + public static function ownerBaseFieldDefinitions(EntityTypeInterface $entity_type) { + if (!is_subclass_of($entity_type->getClass(), EntityOwnerInterface::class)) { + throw new UnsupportedEntityTypeDefinitionException('The entity type ' . $entity_type->id() . ' does not implement \Drupal\user\EntityOwnerInterface.'); + } + if (!$entity_type->hasKey('owner')) { + throw new UnsupportedEntityTypeDefinitionException('The entity type ' . $entity_type->id() . ' does not have an "owner" entity key.'); + } + + return [ + $entity_type->getKey('owner') => BaseFieldDefinition::create('entity_reference') + ->setLabel(new TranslatableMarkup('User ID')) + ->setSetting('target_type', 'user') + ->setTranslatable($entity_type->isTranslatable()) + ->setDefaultValueCallback(static::class . '::getDefaultEntityOwner'), + ]; + } + + /** + * {@inheritdoc} + */ + public function getOwnerId() { + return $this->getEntityKey('owner'); + } + + /** + * {@inheritdoc} + */ + public function setOwnerId($uid) { + $key = $this->getEntityType()->getKey('owner'); + $this->set($key, $uid); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getOwner() { + $key = $this->getEntityType()->getKey('owner'); + return $this->get($key)->entity; + } + + /** + * {@inheritdoc} + */ + public function setOwner(UserInterface $account) { + $key = $this->getEntityType()->getKey('owner'); + $this->set($key, $account); + + return $this; + } + + /** + * Default value callback for 'owner' base field. + * + * @return mixed + * A default value for the owner field. + */ + public static function getDefaultEntityOwner() { + return \Drupal::currentUser()->id(); + } + +}