diff -u b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php --- b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php +++ b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php @@ -95,14 +95,10 @@ $this->assertText(t('The listed configuration will be updated.')); $this->assertText(t('View')); $this->assertText('test_view_field_delete'); - // Test that the View isn't deleted and is still enabled. - $view = View::load('test_view_field_delete'); - $this->assertNotNull($view); - $this->assertTrue($view->status()); $xml = $this->cssSelect('#edit-entity-deletes'); // Test that nothing is scheduled for deletion. - $this->assertFalse(isset($xml[0]), 'The currently being deleted field is not shown in the entity deletions.'); + $this->assertFalse(isset($xml[0]), 'The field currently being deleted is not shown in the entity deletions.'); // Delete the second field. $this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$field_name", $field_label, $type_name2); @@ -111,6 +107,11 @@ $this->assertNull(FieldConfig::loadByName('node', $type_name2, $field_name), 'Field was deleted.'); // Check that the field storage was deleted too. $this->assertNull(FieldStorageConfig::loadByName('node', $field_name), 'Field storage was deleted.'); + + // Test that the View isn't deleted and has been disabled. + $view = View::load('test_view_field_delete'); + $this->assertNotNull($view); + $this->assertFalse($view->status()); } } diff -u b/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php --- b/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -492,35 +492,54 @@ $current_display = $this->getExecutable()->current_display; $handler_types = Views::getHandlerTypes(); - // Find all the handlers and check whether they want to do something on - // dependency removal. - foreach ($this->display as $display_id => $display_plugin_base) { - $this->getExecutable()->setDisplay($display_id); - $display = $this->getExecutable()->getDisplay(); - - foreach (array_keys($handler_types) as $handler_type) { - $handlers = $display->getHandlers($handler_type); - foreach ($handlers as $handler_id => $handler) { - if ($handler instanceof DependentWithRemovalPluginInterface) { - if ($handler->onDependencyRemoval($dependencies)) { - // Remove the handler and indicate we made changes and maybe don't - // need to delete this View. - unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]); - $changed = TRUE; - } + // Check if the handlers have resolved all removed dependencies. + if ($changed) { + // Force the displays to be reinitialised to use the changed settings. + $this->getExecutable()->current_display = NULL; + $this->calculateDependencies(); + $new_dependencies = $this->getDependencies(); + foreach ($dependencies as $group => $dependency_list) { + foreach ($dependency_list as $config_key) { + if (isset($new_dependencies[$group]) && array_key_exists($config_key, $new_dependencies[$group])) { + // If any of the dependencies still exist in the new dependencies we + // will disable the view. + $disable = TRUE; + break 2; } } } } - // If we made changes make sure the new dependencies are calculated. + // Disable and log a message that the View was disabled if made changes and + // if we have resolved all dependencies. + // @todo https://www.drupal.org/node/2832558 Give better feedback for + // disabled config. if ($changed) { + $disable = TRUE; + // If any of the dependencies still exist, the View will be deleted so + // there is no need to disable the View or log a message. $this->getExecutable()->current_display = NULL; $this->calculateDependencies(); - - $this->getExecutable()->setDisplay($current_display); + $new_dependencies = $this->getDependencies(); + foreach ($dependencies as $group => $dependency_list) { + foreach ($dependency_list as $config_key) { + if (isset($new_dependencies[$group]) && array_key_exists($config_key, $new_dependencies[$group])) { + $disable = FALSE; + break 2; + } + } + } + if ($disable) { + $this->disable(); + $arguments = [ + '@id' => $this->id(), + ]; + $this->getLogger() + ->warning("View '@id': View was disabled because its settings depend on removed dependencies.", $arguments); + } } + $this->getExecutable()->setDisplay($current_display); return $changed; } diff -u b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php --- b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php @@ -89,6 +89,8 @@ $display = $view->getDisplay('default'); $this->assertFalse(isset($display['display_options']['fields']['bar'])); + // Checks that the view has been disabled. + $this->assertFalse($view->status()); } /** @@ -132,9 +134,9 @@ } /** - * Tests uninstalling a module providing a Views base table. + * Tests uninstalling a module that provides a base table for a View. */ - public function testConfigRemovalBasetable() { + public function testConfigRemovalBaseTable() { // Find all the entity types provided by the entity_test module and install // the schema for them so we can uninstall them. $entities = \Drupal::entityTypeManager()->getDefinitions();