Soms moet je een veld van een content type aanpassen nadat het al gedefinieerd is en gebruikt wordt.
Als je dat via de admin pagina's doet, krijg je de foutmelding "Er zijn reeds gegevens voor dit veld in de database. De veldinstellingen kunnen niet meer gewijzigd worden.".
Het veld kan niet gewijzigd worden aangezien er al data in zit.
Een manier om het op te lossen is via een hook_update_N implementatie, in mijn geval om een veld van “Text (plain)” naar “Text (formatted, long)” aan te passen.
$entityType = 'node';
$fieldName = 'field_text';
$database = \Drupal::database();
$table = $entityType . '__' . $fieldName;
$currentRows = NULL;
$newFieldsList = [];
$fieldStorage = FieldStorageConfig::loadByName($entityType, $fieldName);
if (is_null($fieldStorage)) {
return;
}
if ($database->schema()->tableExists($table)) {
$currentRows = $database->select($table, 'n')
->fields('n')
->execute()
->fetchAll();
}
foreach ($fieldStorage->getBundles() as $bundle => $label) {
$field = FieldConfig::loadByName($entityType, $bundle, $fieldName);
$newField = $field->toArray();
$newField['field_type'] = 'text_long';
$newField['settings'] = [];
$newFieldsList[] = $newField;
}
$newFieldStorage = $fieldStorage->toArray();
$newFieldStorage['type'] = 'text_long';
$newFieldStorage['settings'] = [];
$fieldStorage->delete();
field_purge_batch(40);
$newFieldStorage = FieldStorageConfig::create($newFieldStorage);
$newFieldStorage->save();
foreach ($newFieldsList as $nfield) {
$nfieldConfig = FieldConfig::create($nfield);
$nfieldConfig->save();
}
if (!is_null($currentRows)) {
foreach ($currentRows as $row) {
$database->insert($table)
->fields((array) $row)
->execute();
}
}