Change the text field maximum length in Drupal 8
Once a text field has data stored, it is not very easy or obvious how to change its maximum length. In the UI there is a message warning you that the field cannot be changed, because there is existing data. Sometimes it is necessary to change these values. It seems that there are a few ways and some resources to do this in Drupal 7, but I could not find a way to do this in Drupal 8. I decided to create a small function to do it:
Caution: Any change in the database needs to be done carefully. Before you continue please create a backup of your database.
/**
* Update the length of a text field which already contains data.
*
* @param string $entity_type_id
* @param string $field_name
* @param integer $new_length
*/
function _module_change_text_field_max_length ($entity_type_id, $field_name, $new_length) {
$name = 'field.storage.' . $entity_type_id . "." . $field_name;
// Get the current settings
$result = \Drupal::database()->query(
'SELECT data FROM {config} WHERE name = :name',
[':name' => $name]
)->fetchField();
$data = unserialize($result);
$data['settings']['max_length'] = $new_length;
// Write settings back to the database.
\Drupal::database()->update('config')
->fields(array( 'data' => serialize($data)))
->condition('name', $name)
->execute();
// Update the value column in both the _data and _revision tables for the field
$table = $entity_type_id . "__" . $field_name;
$table_revision = $entity_type_id . "_revision__" . $field_name;
$new_field = ['type' => 'varchar', 'length' => $new_length];
$col_name = $field_name . '_value';
\Drupal::database()->schema()->changeField($table, $col_name, $col_name, $new_field);
\Drupal::database()->schema()->changeField($table_revision, $col_name, $col_name, $new_field);
// Flush the caches.
drupal_flush_all_caches();
}
This method needs the name of the entity, the name of the field, and the name and the new length.
And we can use it like this:
_module_change_text_field_max_length('node', 'field_text', 280);
Usually, this code should be placed in (or called from) a hook_update so it will be executed automatically in the update.
And if the new length is too long to be placed in a regular input area, you can use the Textarea widget for text fields which will allow you to use the larger text area form element for text fields.