Expanding the character limit of a text field

3 minutes

In some online articles, this topic is explained, even in the Drupal documentation, but the truth is that they don't work and in some cases, they even delete the temporal field data temporarily and then reload it, a process that is unnecessary for this particular case.

Also, it's important to understand that this process cannot be done through the Drupal administration when the field already has data, you will see it disabled with a message as follows:

Field Length disabled

The code for this should be put in a file with an extension of .install, which according to the name of your module would be like name-of-the-module.install.

At the end, I will show you how the content of this file looks like, which I understand the things that good in some code examples and improving it to produce the correct result we need.

get($storage_key);
  foreach ($field_schemas as &$field_schema) {
    $field_schema['fields'][$field_name . '_value']['length'] = $new_length;
  }
  $storage_schema->set($storage_key, $field_schemas);

  // Updating db fields.
  $db = Drupal::database();
  foreach ($field_schemas as $table_name => $table_schema) {
    $db->schema()->changeField($table_name, $field_name . '_value', $field_name . '_value', $table_schema['fields'][$field_name . '_value']);
  }

  // Update field configuration.
  $config = \Drupal::configFactory()->getEditable('field.storage.' . $entity_type_id . '.' . $field_name);
  $config->set('settings.max_length', $new_length);
  $config->save(TRUE);

  // Update field storage configuration.
  FieldStorageConfig::loadByName($entity_type_id, $field_name)->save();
}

Now comes the explanation of what's happening here.

Using the hook_update_N

This is the hook that is used to update parts of the site using code, and each update is numbered incrementally. For this example, we assume it is the first update made by this module, so we use the number 9001, the standard for this numbering is explained here drupal.org.

The only thing we're doing in this hook is using the function <em>db_change_varchar_field</em> that takes care of updating the field, which as you can see in this case is one called field_caption in the entity type media, and increasing it to support up to 500 characters.

To apply these updates to your site, you need to use the following command:

drush updatedb

Updating the schema

// Update Storage Schema.
$storage_key = $entity_type_id . '.field_schema_data.' . $field_name;
$storage_schema = \Drupal::keyValue('entity.storage_schema.sql');
$field_schemas = $storage_schema->get($storage_key);
foreach ($field_schemas as &$field_schema) {
  $field_schema['fields'][$field_name . '_value']['length'] = $new_length;
}
$storage_schema->set($storage_key, $field_schemas);

The schema in which the field was created is stored in the Drupal database using the KeyValue API, this information is used by some services and what we are doing here is updating the length of the column that contains the values.

Updating the database columns

// Updating db fields.
$db = Drupal::database();
foreach ($field_schemas as $table_name => $table_schema) {
  $db->schema()->changeField($table_name, $field_name . '_value', $field_name . '_value', $table_schema['fields'][$field_name . '_value']);
}

Now, we update the database and I'm referring to columns because in many cases, fields have revisions and this generates a table as well, so we update the column that contains the existing values in both tables.

Updating the field configuration

// Update field configuration.
$config = \Drupal::configFactory()->getEditable('field.storage.' . $entity_type_id . '.' . $field_name);
$config->set('settings.max_length', $new_length);
$config->save(TRUE);

// Update field storage configuration.
FieldStorageConfig::loadByName($entity_type_id, $field_name)->save();

Since Drupal 8, the definition of each field is an entity configuration, so that you can replicate the structure of your content types in other environments. What we are doing here is updating that configuration and in the last line, we save it so that Drupal updates everywhere that configuration is used.

Exporting the configuration

Finally, what you need to do is export the configuration, so you can move these changes to other environments and also because if not, you will lose part of the work when trying to import from another environment.

Conclusion

Although this process seems very complex, I hope I have explained it in a simple way and that this will also serve as a starting point for other types of updates, remember to test this code first in a local environment having made a copy of your database.

Jidrone Drupal Developer
J. Ivan Duarte
Drupal Senior Developer

Share