entity_definition_update
Provides the ability to update entity type definitions in your database in a safe way via regular update hooks. This module is an alternative to the Entity Type Definition Update Manager from Drupal core.
Let's keep entity definition updates fairly easy
If you don't have any existing fields in your entity type, which you like to update, but you have just new fields which you want to install:
<?php
declare(strict_types=1);
/**
* Implements hook_install().
*/
function my_easy_module_install($is_syncing) {
/**
* @var EntityDefinitionUpdateManager $entityDefinitionUpdate
*/
$entityDefinitionUpdate = \Drupal::service('entity_definition_update.entity_definition_update_manager');
$entityDefinitionUpdate->applyUpdates();
}
Et voilĂ ! Your entity definitions from code are in sync with the ones in your database.
Complex example usage within a example_module.install file
This approach can be followed, if you have already data for existing fields, which you want to update. Then you must migrate data for preserving it. The entity definition update process is split into five steps:
- Backing up the date into a temporary database table
- Truncating the old database table
- Updating the entity definition
- Restoring the data into the database table, with the updated entity definition
- Deleting the temporary created database table with the old structure, for backing up the data
<?php declare(strict_types=1);
use Drupal\Core\Database\Database;
use Drupal\entity_definition_update\EntityDefinitionUpdateManager;
/**
* Update entity type definitions in your database, to reflect the definitions in the entity type code.
*/
function example_module_update_9001(): void {
$database = \Drupal::database();
$tables = [
'announcement' => 'announcement__temp',
];
// Create a full copy of source tables.
foreach ($tables as $originalTableName => $tempTableName) {
$database->query("CREATE TABLE $tempTableName LIKE $originalTableName");
$database->query("INSERT INTO $tempTableName SELECT * FROM $originalTableName");
$database->truncate($originalTableName)->execute();
}
/**
* @var EntityDefinitionUpdateManager $entityDefinitionUpdate
*/
$entityDefinitionUpdate = \Drupal::service('entity_definition_update.entity_definition_update_manager');
$entityDefinitionUpdate->applyUpdates();
$schema = Database::getConnection()->schema();
$schema->changeField('announcement', 'contracted_company_other_information__value', 'contracted_company_other_information__value', [
'not null' => FALSE,
'type' => 'text',
]);
\Drupal::logger('entity_definition_update')->notice('Updated field storage config.');
foreach ($tables as $originalTableName => $tempTableName) {
// Method 1: copy back everything into a table with "changed" database columns
$database->query("INSERT INTO $originalTableName (
id,
langcode,
uid,
contracted_company_other_information__value
)
SELECT
id,
langcode,
uid,
contracted_company_other_information
FROM $tempTableName");
if ($originalTableName === 'table_with_same_structure')
// Method 2: copy back everything into a table with "same" database columns
$database->query("INSERT INTO $originalTableName SELECT * FROM $tempTableName");
}
$database->query("DROP TABLE $tempTableName");
\Drupal::logger('entity_definition_update')->notice("Dropped table $tempTableName");
}
}
Using the Entity Definition Update Manager from Drupal core
For applying field updates for an existing entity type definition, the Entity Definition Update Manager from Drupal core can be also an option. See an example below:
function your_module_update_8001() {
// First we need to get update manager.
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
// Load the storage definition of the field.
$field_storage = $definition_update_manager->getFieldStorageDefinition('field_name',
'node');
// Set a new list of options for the list field.
$field_storage->setSettings([
'allowed_values' => [
'link' => 'Link',
'posts' => 'Posts',
'events' => 'Events',
'page' => 'Page',
],
]);
// Update the field storage definition.
$definition_update_manager->updateFieldStorageDefinition($field_storage);
}