From 5ba2a02bcf49b50e3717e1489f2c1b32914fe9c2 Mon Sep 17 00:00:00 2001 From: Carsten Logemann <C_Logemann.dev@nodegard.com> Date: Fri, 14 Feb 2025 15:25:22 +0100 Subject: [PATCH] Issue #3506678 by c-logemann: Remove Entity Reference UUID dependency --- composer.json | 3 - grant.info.yml | 1 - grant.install | 47 +++++++++ grant.views.inc | 40 +++++++- modules/grant_base/grant_base.info.yml | 2 +- src/Entity/Grant.php | 14 +-- .../views/relationship/GrantStandardUuid.php | 97 +++++++++++++++++++ 7 files changed, 190 insertions(+), 14 deletions(-) create mode 100644 grant.install create mode 100644 src/Plugin/views/relationship/GrantStandardUuid.php diff --git a/composer.json b/composer.json index 69f6d01..424456f 100644 --- a/composer.json +++ b/composer.json @@ -15,8 +15,5 @@ "support": { "issues": "https://www.drupal.org/project/issues/grant", "source": "http://cgit.drupalcode.org/grant" - }, - "require": { - "drupal/entity_reference_uuid": "^2.0" } } diff --git a/grant.info.yml b/grant.info.yml index 2ffb0aa..4fc1704 100644 --- a/grant.info.yml +++ b/grant.info.yml @@ -4,4 +4,3 @@ description: Grant allows role assignments to entities based on mail addresses. core_version_requirement: ^10.4 || ^11.1 dependencies: - grant:grant_base - - entity_reference_uuid:entity_reference_uuid diff --git a/grant.install b/grant.install new file mode 100644 index 0000000..d5e6302 --- /dev/null +++ b/grant.install @@ -0,0 +1,47 @@ +<?php + +/** + * @file + * Install, update and uninstall functions for the Grant module. + */ + +use Drupal\Core\Field\BaseFieldDefinition; + +/** + * Implements hook_update_N(). + */ +function grant_update_10001() { + $database = \Drupal::database(); + $transaction = $database->startTransaction(); + $definition_manager = \Drupal::entityDefinitionUpdateManager(); + + // Store the existing values. + $values = $database->select('grant')->fields('grant', ['uuid', 'user', 'assignee'])->execute()->fetchAll(); + + // Clear out the values. + $database->update('grant')->fields(['user' => NULL, 'assignee' => NULL])->execute(); + + // Uninstall the fields. + $field_storage_definition = $definition_manager->getFieldStorageDefinition('user', 'grant'); + $definition_manager->uninstallFieldStorageDefinition($field_storage_definition); + $field_storage_definition = $definition_manager->getFieldStorageDefinition('assignee', 'grant'); + $definition_manager->uninstallFieldStorageDefinition($field_storage_definition); + + // Create new field definitions. + $new_user_field = BaseFieldDefinition::create('string')->setLabel(t('User'))->setSetting('max_length', 128); + $new_assignee_field = BaseFieldDefinition::create('string')->setLabel(t('Assignee'))->setSetting('max_length', 128); + + // Install the new definitions. + $definition_manager->installFieldStorageDefinition('user', 'grant', 'grant', $new_user_field); + $definition_manager->installFieldStorageDefinition('assignee', 'grant', 'grant', $new_assignee_field); + + // Restore the values. + foreach ($values as $value) { + $database->update('grant')->fields(['user' => $value->user, 'assignee' => $value->assignee]) + ->condition('uuid', $value->uuid)->execute(); + } + + // Commit transaction. + unset($transaction); + return t('All grants updated.'); +} diff --git a/grant.views.inc b/grant.views.inc index 9571025..de1c1c3 100644 --- a/grant.views.inc +++ b/grant.views.inc @@ -1,7 +1,5 @@ <?php -declare(strict_types=1); - /** * @file * Views hooks for the Grant module. @@ -23,4 +21,42 @@ function grant_views_data_alter(array &$data) { 'id' => 'grant_role_label', ]; + $args = [ + '@label' => 'account', + '@field_name' => 'grant user field', + ]; + $data['grant']['user']['relationship'] = [ + 'title' => t('@label referenced from @field_name', $args), + 'label' => t('@field_name: @label', $args), + 'group' => 'grant', + 'help' => t('Appears in each grant'), + // @see \Drupal\views\Plugin\views\relationship\Standard + 'id' => 'grant_standard_uuid', + 'base' => 'users_field_data', + 'entity base table' => 'users', + 'entity uuid field' => 'uuid', + 'entity type' => 'user', + 'base field' => 'uid', + 'relationship field' => 'user', + ]; + + $args = [ + '@label' => 'account', + '@field_name' => 'grant assignee field', + ]; + $data['grant']['assignee']['relationship'] = [ + 'title' => t('@label referenced from @field_name', $args), + 'label' => t('@field_name: @label', $args), + 'group' => 'grant', + 'help' => t('Appears in each grant'), + // @see \Drupal\views\Plugin\views\relationship\Standard + 'id' => 'grant_standard_uuid', + 'base' => 'users_field_data', + 'entity base table' => 'users', + 'entity uuid field' => 'uuid', + 'entity type' => 'user', + 'base field' => 'uid', + 'relationship field' => 'assignee', + ]; + } diff --git a/modules/grant_base/grant_base.info.yml b/modules/grant_base/grant_base.info.yml index a666454..900f68b 100644 --- a/modules/grant_base/grant_base.info.yml +++ b/modules/grant_base/grant_base.info.yml @@ -1,4 +1,4 @@ name: Grant base type: module description: 'Grant basic functionality can be used without role assignments.' -core_version_requirement: ^9 || ^10 +core_version_requirement: ^10 || ^11 diff --git a/src/Entity/Grant.php b/src/Entity/Grant.php index f278272..089c5b3 100644 --- a/src/Entity/Grant.php +++ b/src/Entity/Grant.php @@ -110,23 +110,23 @@ class Grant extends ContentEntityBase implements GrantInterface { ->setLabel(t('Changed')) ->setDescription(t('The time that the grant was last edited.')); - $fields['user'] = BaseFieldDefinition::create('entity_reference_uuid') + $fields['user'] = BaseFieldDefinition::create('string') ->setLabel(t('Grant user')) - ->setSetting('target_type', 'user') + ->setSetting('max_length', 128) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('form', [ - 'type' => 'entity_reference_autocomplete', + 'type' => 'string_textfield', 'weight' => 0, ]) ->setDisplayConfigurable('view', TRUE); - $fields['assignee'] = BaseFieldDefinition::create('entity_reference_uuid') + $fields['assignee'] = BaseFieldDefinition::create('string') ->setLabel(t('Assignee')) - ->setSetting('target_type', 'user') + ->setSetting('max_length', 128) ->setDisplayConfigurable('form', TRUE) ->setDisplayOptions('form', [ - 'type' => 'entity_reference_autocomplete', - 'weight' => 0, + 'type' => 'string_textfield', + 'weight' => 1, ]) ->setDisplayConfigurable('view', TRUE); diff --git a/src/Plugin/views/relationship/GrantStandardUuid.php b/src/Plugin/views/relationship/GrantStandardUuid.php new file mode 100644 index 0000000..bc080cf --- /dev/null +++ b/src/Plugin/views/relationship/GrantStandardUuid.php @@ -0,0 +1,97 @@ +<?php + +namespace Drupal\grant\Plugin\views\relationship; + +use Drupal\views\Plugin\views\relationship\Standard; +use Drupal\views\Views; + +/** + * Implementation of a relationship plugin for UUID. + * + * @ingroup views_relationship_handlers + * + * @ViewsRelationship("grant_standard_uuid") + */ +class GrantStandardUuid extends Standard { + + /** + * {@inheritdoc} + */ + public function query() { + + // Figure out what base table this relationship brings to the party. + $table_data = Views::viewsData()->get($this->definition['base']); + $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; + + // Unset provider to avoid duplicates. + unset($table_data['table']['provider']); + + $this->ensureMyTable(); + + $def = $this->definition; + + // The 'entity base table' is e.g. {node}. + $def['table'] = $this->definition['entity base table']; + // The 'entity uuid field' is e.g. {node}.uuid. + $def['field'] = $this->definition['entity uuid field']; + // This is the entity_reference_uuid field table like {node__field_foo}. + $def['left_table'] = $this->table; + // This is the 'relationship field' like field_foo_target_uuid. + $def['left_field'] = $this->realField; + if (!empty($this->options['required'])) { + $def['type'] = 'INNER'; + } + if (!empty($def['join_id'])) { + $id = $def['join_id']; + } + else { + $id = 'standard'; + } + if (!empty($this->definition['extra'])) { + $def['extra'] = $this->definition['extra']; + } + // Join first from e.g. {node__field_foo}.field_foo_target_uuid to + // {node}.uuid. + $l_join = Views::pluginManager('join')->createInstance($id, $def); + + // Use a short alias for this: + $first_alias = $this->definition['entity base table'] . '_' . $this->table . '_' . $this->realField; + // And now add our table, using the new relationship if one was used. + $alias = $this->query->addTable($this->definition['entity base table'], $this->relationship, $l_join, $first_alias); + + // If there is no data table, the next join is not needed. + if ($this->definition['base'] !== $this->definition['entity base table']) { + $def = $this->definition; + // The data table e.g. {node_field_data}. + $def['table'] = $this->definition['base']; + // The entity ID field e.g. {node_field_data}.nid. + $def['field'] = $base_field; + // The alias from the first join to the entity base table e.g. {node}. + $def['left_table'] = $alias; + // We again use the base field to connect the base and data tables. + $def['left_field'] = $base_field; + $def['adjusted'] = TRUE; + if (!empty($this->options['required'])) { + $def['type'] = 'INNER'; + } + // Join next from e.g. {node}.nid to {node_field_data}.nid. This is needed + // since uuid is not in the data table. + $join = Views::pluginManager('join')->createInstance($id, $def); + + // Use a short alias for this: + $alias = $def['table'] . '_' . $this->table . '_' . $this->realField; + } + else { + $join = $l_join; + } + + $this->alias = $this->query->addRelationship($alias, $join, $this->definition['base'], $this->relationship); + + // Add access tags if the base table provide it. + if (empty($this->query->options['disable_sql_rewrite']) && isset($table_data['table']['base']['access query tag'])) { + $access_tag = $table_data['table']['base']['access query tag']; + $this->query->addTag($access_tag); + } + } + +} -- GitLab