Skip to content
Snippets Groups Projects
Verified Commit da2c85be authored by Dave Long's avatar Dave Long
Browse files

Issue #3310170 by bradjones1, tstoeckler, smustgrave, thursday_bw: Use UUID as entity ID

parent 6e60f0b5
No related branches found
No related tags found
13 merge requests!11197Issue #3506427 by eduardo morales alberti: Remove responsive_image.ajax from hook,!11131[10.4.x-only-DO-NOT-MERGE]: Issue ##2842525 Ajax attached to Views exposed filter form does not trigger callbacks,!10786Issue #3490579 by shalini_jha, mstrelan: Add void return to all views...,!10210Issue #3487907: Drupal.displace() use getComputedStyle() for hidden chk.,!3878Removed unused condition head title for views,!3818Issue #2140179: $entity->original gets stale between updates,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3133core/modules/system/css/components/hidden.module.css,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2062Issue #3246454: Add weekly granularity to views date sort,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation
Pipeline #336452 failed
...@@ -176,7 +176,9 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st ...@@ -176,7 +176,9 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st
return $table_mapping->allowsSharedTableStorage($definition); return $table_mapping->allowsSharedTableStorage($definition);
}); });
$key_fields = array_values(array_filter([$id_key, $revision_key, $bundle_key, $uuid_key, $langcode_key])); // The ID and UUID key may point to the same field, so make sure the list is
// unique.
$key_fields = array_values(array_unique(array_filter([$id_key, $revision_key, $bundle_key, $uuid_key, $langcode_key])));
$all_fields = array_keys($shared_table_definitions); $all_fields = array_keys($shared_table_definitions);
$revisionable_fields = array_keys(array_filter($shared_table_definitions, function (FieldStorageDefinitionInterface $definition) { $revisionable_fields = array_keys(array_filter($shared_table_definitions, function (FieldStorageDefinitionInterface $definition) {
return $definition->isRevisionable(); return $definition->isRevisionable();
...@@ -206,10 +208,11 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st ...@@ -206,10 +208,11 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st
// whether they are translatable or not. The data table holds also a // whether they are translatable or not. The data table holds also a
// denormalized copy of the bundle field value to allow for more // denormalized copy of the bundle field value to allow for more
// performant queries. This means that only the UUID is not stored on // performant queries. This means that only the UUID is not stored on
// the data table. // the data table. Make sure the ID is always in the list, even if the ID
// key and the UUID key point to the same field.
$table_mapping $table_mapping
->setFieldNames($table_mapping->baseTable, $key_fields) ->setFieldNames($table_mapping->baseTable, $key_fields)
->setFieldNames($table_mapping->dataTable, array_values(array_diff($all_fields, [$uuid_key]))); ->setFieldNames($table_mapping->dataTable, array_values(array_unique(array_merge([$id_key], array_diff($all_fields, [$uuid_key])))));
} }
elseif ($revisionable && $translatable) { elseif ($revisionable && $translatable) {
// The revisionable multilingual layout stores key field values in the // The revisionable multilingual layout stores key field values in the
...@@ -224,7 +227,7 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st ...@@ -224,7 +227,7 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st
// Like in the multilingual, non-revisionable case the UUID is not // Like in the multilingual, non-revisionable case the UUID is not
// in the data table. Additionally, do not store revision metadata // in the data table. Additionally, do not store revision metadata
// fields in the data table. // fields in the data table.
$data_fields = array_values(array_diff($all_fields, [$uuid_key], $revision_metadata_fields)); $data_fields = array_values(array_unique(array_merge([$id_key], array_diff($all_fields, [$uuid_key], $revision_metadata_fields))));
$table_mapping->setFieldNames($table_mapping->dataTable, $data_fields); $table_mapping->setFieldNames($table_mapping->dataTable, $data_fields);
$revision_base_fields = array_merge([$id_key, $revision_key, $langcode_key], $revision_metadata_fields); $revision_base_fields = array_merge([$id_key, $revision_key, $langcode_key], $revision_metadata_fields);
......
...@@ -73,6 +73,7 @@ function entity_test_entity_types($filter = NULL) { ...@@ -73,6 +73,7 @@ function entity_test_entity_types($filter = NULL) {
if ($filter === ENTITY_TEST_TYPES_ROUTING) { if ($filter === ENTITY_TEST_TYPES_ROUTING) {
$types[] = 'entity_test_base_field_display'; $types[] = 'entity_test_base_field_display';
$types[] = 'entity_test_string_id'; $types[] = 'entity_test_string_id';
$types[] = 'entity_test_uuid_id';
$types[] = 'entity_test_no_id'; $types[] = 'entity_test_no_id';
$types[] = 'entity_test_mul_with_bundle'; $types[] = 'entity_test_mul_with_bundle';
} }
......
<?php
declare(strict_types=1);
namespace Drupal\entity_test\Entity;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Defines a test entity class with UUIDs as IDs.
*
* @ContentEntityType(
* id = "entity_test_uuid_id",
* label = @Translation("Test entity with UUIDs as IDs"),
* handlers = {
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
* "form" = {
* "default" = "Drupal\entity_test\EntityTestForm"
* },
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
* },
* },
* translatable = TRUE,
* base_table = "entity_test_uuid_id",
* data_table = "entity_test_uuid_id_data",
* admin_permission = "administer entity_test content",
* entity_keys = {
* "id" = "uuid",
* "uuid" = "uuid",
* "bundle" = "type",
* "langcode" = "langcode",
* "label" = "name",
* },
* links = {
* "canonical" = "/entity_test_uuid_id/manage/{entity_test_uuid_id}",
* "add-form" = "/entity_test_uuid_id/add",
* "edit-form" = "/entity_test_uuid_id/manage/{entity_test_uuid_id}/edit",
* },
* )
*/
class EntityTestUuidId extends EntityTest {
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
// Configure a string field to match the UUID field configuration and use it
// for both the ID and the UUID key. The UUID field type cannot be used
// because it would add a unique key to the data table.
$fields[$entity_type->getKey('uuid')] = BaseFieldDefinition::create('string')
->setLabel(new TranslatableMarkup('UUID'))
/* @see \Drupal\Core\Field\Plugin\Field\FieldType\UuidItem::defaultStorageSettings() */
->setSetting('max_length', 128)
->setSetting('is_ascii', TRUE)
/* @see \Drupal\Core\Field\Plugin\Field\FieldType\UuidItem::applyDefaultValue() */
->setDefaultValueCallback(static::class . '::generateUuid');
return $fields;
}
/**
* Statically generates a UUID.
*
* @return string
* A newly generated UUID.
*/
public static function generateUuid(): string {
$uuid = \Drupal::service('uuid');
assert($uuid instanceof UuidInterface);
return $uuid->generate();
}
}
<?php
declare(strict_types=1);
namespace Drupal\FunctionalTests\Entity;
use Drupal\Component\Uuid\Uuid;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\content_translation\Traits\ContentTranslationTestTrait;
/**
* Tests that an entity with a UUID as ID can be managed.
*
* @group Entity
*/
class EntityUuidIdTest extends BrowserTestBase {
use ContentTranslationTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = ['block', 'content_translation', 'entity_test'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->createLanguageFromLangcode('af');
$this->enableContentTranslation('entity_test_uuid_id', 'entity_test_uuid_id');
$this->drupalPlaceBlock('page_title_block');
$this->drupalPlaceBlock('local_tasks_block');
}
/**
* Tests the user interface for the test entity.
*/
public function testUi(): void {
$this->drupalLogin($this->createUser([
'administer entity_test content',
'create content translations',
'translate entity_test_uuid_id',
'view test entity',
]));
// Test adding an entity.
$this->drupalGet('/entity_test_uuid_id/add');
$this->submitForm([
'Name' => 'Test entity with UUID ID',
], 'Save');
$this->assertSession()->elementTextEquals('css', 'h1', 'Edit Test entity with UUID ID');
$this->assertSession()->addressMatches('#^/entity_test_uuid_id/manage/' . Uuid::VALID_PATTERN . '/edit$#');
// Test translating an entity.
$this->clickLink('Translate');
$this->clickLink('Add');
$this->submitForm([
'Name' => 'Afrikaans translation of test entity with UUID ID',
], 'Save');
$this->assertSession()->elementTextEquals('css', 'h1', 'Afrikaans translation of test entity with UUID ID [Afrikaans translation]');
$this->assertSession()->addressMatches('#^/af/entity_test_uuid_id/manage/' . Uuid::VALID_PATTERN . '/edit$#');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment