diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php index dc5607a..d91d286 100644 --- a/core/modules/field/src/Entity/FieldConfig.php +++ b/core/modules/field/src/Entity/FieldConfig.php @@ -182,6 +182,7 @@ public function calculateDependencies() { public static function preDelete(EntityStorageInterface $storage, array $fields) { $state = \Drupal::state(); + parent::preDelete($storage, $fields); // Keep the field definitions in the state storage so we can use them // later during field_purge_batch(). $deleted_fields = $state->get('field.field.deleted') ?: array(); @@ -222,7 +223,7 @@ public static function postDelete(EntityStorageInterface $storage, array $fields $storages_to_delete = array(); foreach ($fields as $field) { $storage_definition = $field->getFieldStorageDefinition(); - if (!$field->deleted && empty($field->noFieldDelete) && !$field->isUninstalling() && $storage_definition->isDeletable()) { + if (!$field->deleted && !$field->isUninstalling() && $storage_definition->isDeletable()) { // Key by field UUID to avoid deleting the same storage twice. $storages_to_delete[$storage_definition->uuid()] = $storage_definition; } @@ -230,29 +231,6 @@ public static function postDelete(EntityStorageInterface $storage, array $fields if ($storages_to_delete) { \Drupal::entityManager()->getStorage('field_storage_config')->delete($storages_to_delete); } - - // Cleanup entity displays. - $displays_to_update = array(); - foreach ($fields as $field) { - if (!$field->deleted) { - $view_modes = \Drupal::entityManager()->getViewModeOptions($field->entity_type, TRUE); - foreach (array_keys($view_modes) as $mode) { - $displays_to_update['entity_view_display'][$field->entity_type . '.' . $field->bundle . '.' . $mode][] = $field->getName(); - } - $form_modes = \Drupal::entityManager()->getFormModeOptions($field->entity_type, TRUE); - foreach (array_keys($form_modes) as $mode) { - $displays_to_update['entity_form_display'][$field->entity_type . '.' . $field->bundle . '.' . $mode][] = $field->getName(); - } - } - } - foreach ($displays_to_update as $type => $ids) { - foreach (entity_load_multiple($type, array_keys($ids)) as $id => $display) { - foreach ($ids[$id] as $field_name) { - $display->removeComponent($field_name); - } - $display->save(); - } - } } /** diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php index 829aeef..203b961 100644 --- a/core/modules/field/src/Entity/FieldStorageConfig.php +++ b/core/modules/field/src/Entity/FieldStorageConfig.php @@ -198,6 +198,13 @@ class FieldStorageConfig extends ConfigEntityBase implements FieldStorageConfigI protected $propertyDefinitions; /** + * Static flag set to prevent recursion during field deletes. + * + * @var bool + */ + protected static $in_deletion = FALSE; + + /** * Constructs a FieldStorageConfig object. * * @param array $values @@ -374,27 +381,13 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { */ public static function preDelete(EntityStorageInterface $storage, array $field_storages) { $state = \Drupal::state(); - $field_config_storage = \Drupal::entityManager()->getStorage('field_config'); - // Delete fields first. Note: when deleting a field storage through - // FieldConfig::postDelete(), the fields have been deleted already, so - // no fields will be found here. - $field_ids = array(); - foreach ($field_storages as $field_storage) { - if (!$field_storage->deleted) { - foreach ($field_storage->getBundles() as $bundle) { - $field_ids[] = "{$field_storage->entity_type}.$bundle.{$field_storage->field_name}"; - } - } - } - if ($field_ids) { - $fields = $field_config_storage->loadMultiple($field_ids); - // Tag the objects to preserve recursive deletion of the field. - foreach ($fields as $field) { - $field->noFieldDelete = TRUE; - } - $field_config_storage->delete($fields); - } + // Set the static flag so that we don't delete field storages whilst + // deleting fields. + self::$in_deletion = TRUE; + + // Delete or fix any configuration that is dependent, for example, fields. + parent::preDelete($storage, $field_storages); // Keep the field definitions in the state storage so we can use them later // during field_purge_batch(). @@ -422,6 +415,8 @@ public static function postDelete(EntityStorageInterface $storage, array $fields $field->deleted = TRUE; } } + // Unset static flag. + self::$in_deletion = FALSE; } /** @@ -745,7 +740,7 @@ public static function loadByName($entity_type_id, $field_name) { public function isDeletable() { // The field storage is not deleted, is configured to be removed when there // are no fields and the field storage has no bundles. - return !$this->deleted && !$this->persist_with_no_fields && count($this->getBundles()) == 0; + return !$this->deleted && !$this->persist_with_no_fields && count($this->getBundles()) == 0 && !self::$in_deletion; } }