Provide mechanism to alter fields with existing data.

Created on 25 July 2023, over 1 year ago
Updated 1 July 2024, 6 months ago

Problem/Motivation

Once there is data in the field tables, the field storage settings form is locked and no fields can be added/removed/updated. This is perhaps the biggest limitation currently of this module. Requirements change and we need to account for this in providing api to handle these updates efficiently and safely.

Steps to reproduce

Add custom field with one or more columns. Save an entity with value populated in custom field. Return to field storage settings form and acknowledge the form is locked from further editing until and unless the tables are empty.

Proposed resolution

Provide a service for our module that can be called in an update hook from .install file in custom module. Field api updates are tricky and particularly complicated with flexibility this module provides so lets start simple and provide ability to add/remove columns in our service. The ability to update column can be a later feature as there are more risk in data conversions and such depending on the update needed.

Remaining tasks

  1. Needs review
  2. We need Unit Tests!!
  3. Batch function provided for restoring data
  4. Document how to use api - need to update readme with instructions and examples.

User interface changes

None.

API changes

Provide new custom_field.update_manager service.

/**
   * Adds a new column to the specified field storage.
   *
   * @param string $entity_type_id
   *   The entity type ID.
   * @param string $field_name
   *   The field name.
   * @param string $new_property
   *   The new property name (column name).
   * @param string $data_type
   *   The data type to add. Allowed values such as: "integer", "boolean" etc.
   * @param array $options
   *   An array of options to set for new column.
   */
  public function addColumn(string $entity_type_id, string $field_name, string $new_property, string $data_type, array $options = []): void;
/**
   * Removes a column from the specified field storage.
   *
   * @param string $entity_type_id
   *   The entity type ID.
   * @param string $field_name
   *   The field name.
   * @param string $property
   *   The name of the column to remove.
   */
  public function removeColumn(string $entity_type_id, string $field_name, string $property): void;

How to use new api in update hooks

/**
 * Add a new column to custom_field.
 */
function my_module_update_9000(): void {
  /** @var \Drupal\custom_field\CustomFieldUpdateManagerInterface $update_manager */
  $update_manager = Drupal::service('custom_field.update_manager');
  $update_manager->addColumn('node', 'field_custom', 'test_decimal', 'decimal', ['scale' => 3, 'precision' => 6]);
}

/**
 * Remove a column from custom_field.
 */
function my_module_update_9001(): void {
  /** @var \Drupal\custom_field\CustomFieldUpdateManagerInterface $update_manager */
  $update_manager = Drupal::service('custom_field.update_manager');
  $update_manager->removeColumn('node', 'field_custom', 'test_string');
}

Data model changes

Provide a multi-purpose dataTypes function that returns an array of types keyed by data type that has values for label (can reuse for options list) and schema so we can set some defaults for the addColumn function.

✨ Feature request
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States apmsooner

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024