0

In an update function, I'm trying to change the target_type of an entity reference field, following the approach outlined on https://www.drupal.org/node/2535476). The previously used target entity type (its class) has been removed from my site (I'm removing it as part of the update).

Something like this in the update function:

$field_storage_config = FieldStorageConfig::loadByName('entity_type', 'field_name');
$field_storage_config->setSetting('target_type', 'new_entity_type');
$field_storage_config->save();

When I call $field_storage_config->save(), I get a fatal error saying the previously used target type (the one that's been removed) no longer exists. It seems that the save() method eventually calls \Drupal\Core\Entity\EntityTypeManager::getDefinition for the removed entity type, leading to the fatal error.

Any way to get around this, so I can switch the target type from the removed entity type to an existing one in my update function?

1
  • 1
    Pleas post your relevant code here.
    – sonfd
    Mar 27, 2019 at 21:14

1 Answer 1

1

I dealt with this issue a few months back in the jQuery Colorpicker module. I was converting all fields of one type (jquery_colorpicker), to fields of an entirely different type (colorapi_color). With the update of the module from 8.x-1.x to 8.x-2.x, I intended to remove the the original type/plugin (jquery_colorpicker). Then in the update script I intended to loop through each field on every entity type, and if it was jquery_colorpicker, change it to colorapi_color. However deleting the plugin led to the same issue you are running into, where I was getting an error about mistting the field type that I had removed.

In the end to get around this problem, I took a different approach altogether. I left the definition plugin file for the jquery_colorpicker field in the file system, but marked it as deprecated:

/**
 * Provides the Color field.
 *
 * @FieldType(
 *   id = "jquery_colorpicker",
 *   label = @Translation("Color (deprecated)"),
 *   default_formatter = "colorapi_color_display",
 *   default_widget = "colorapi_color_widget",
 * )
 *
 * @deprecated as of Jquery Colorpicker update 8200. Will be removed in Jquery
 *   Colorpicker 8.x-3.x, and/or 9.x-1.x. Running
 *   jquery_colorpicker_update_8200() requires the existence of this field type,
 *   however the field type is obsolete after that update has been run. As such,
 *   if the schema version is equal to or above 8200, the field type is removed
 *   from the list of field types in jquery_colorpicker_field_info_alter().
 */

Link: https://cgit.drupalcode.org/jquery_colorpicker/tree/src/Plugin/Field/FieldType/JqueryColorpickerColorItem.php#n9

Then I set the system to remove the field type from Drupal's list of field types when the current installed version of the module is 8200+:

/**
 * Implements hook_field_info_alter().
 *
 * @deprecated as of Jquery Colorpicker update 8200. Will be removed in Jquery
 *   Colorpicker 8.x-3.x, and/or 9.x-1.x.
 *
 * @see jquery_colorpicker_update_8200()
 */
function jquery_colorpicker_field_info_alter(&$info) {
  // Running jquery_colorpicker_update_8200() requires the existence of the
  // jquery_colorpicker field type, however the field type is obsolete after
  // that update has been run. As such, if the schema version is equal to or
  // above 8200, the field type is removed from the list of field types.
  if (drupal_get_installed_schema_version('jquery_colorpicker') >= 8200) {
    unset($info['jquery_colorpicker']);
  }
}

Link: https://cgit.drupalcode.org/jquery_colorpicker/tree/jquery_colorpicker.module#n45

With the above code, before the update is run, the version will be less than 8200. Any time the system builds the list of field types, the jquery_colorpicker field type is available, meaning that when the update script is run, the field type is still available, so you won't get the error about it missing.

After the update has been run, the version will be 8200 (or greater), and therefore the jquery_colorpicker field type should no longer be available. Therefore it is removed from the list of field types.

If/when version 8.x-3.x of the module is released, I will remove the jquery_colorpicker plugin file altogether. For now, it's still in the codebase, but deprecated and unused.

3
  • Thanks @Jaypan! I was hoping to avoid a 2-step solution, since it has the potential of breaking sites (if people skip a version), but I can't think of another way of doing this. We'd have to make sure to warn people to follow the correct upgrade path - maybe even checking the schema version in the next update hook if that's possible. I'm surprised that this doesn't seem to be supported, since it seems like a thing that happens sometimes (removing an entity type, and changing references to that removed entity type during an update). Wondering if this should be a bug report/feature request.
    – brunodbo
    Mar 29, 2019 at 1:18
  • Yeah I get that. I felt the same. That’s why I won’t remove the deprecated file until the 8.x-3.x version. A person would have to skip from 1.x - 3.x without going through 2.x to hit the error, and I would hope someone would have taken a backup before trying to make a double jump!
    – Jaypan
    Mar 29, 2019 at 1:23
  • Created an issue about this here: drupal.org/project/drupal/issues/3044463
    – brunodbo
    Apr 5, 2019 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.