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 @@ -273,6 +273,11 @@ // Ensure that the view is dependant on the module that implements the view. $this->addDependency('module', $this->module); + // For disabled views don't add any handler specific dependencies. + if (!$this->status()) { + return $this; + } + $executable = $this->getExecutable(); $executable->initDisplay(); $executable->initStyle(); @@ -473,7 +478,14 @@ * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { - $result = FALSE; + $changed = FALSE; + $disable = TRUE; + + // Don't intervene if the views module is removed. + if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) { + return FALSE; + } + $current_display = $this->getExecutable()->current_display; $handler_types = Views::getHandlerTypes(); @@ -488,21 +500,59 @@ 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 disable this View. unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]); - $result = TRUE; + $disable = FALSE; + $changed = TRUE; } } } } } - // When we had to make any kind of change, disable the view. - if ($result) { + // 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; + } + } + } + } + + // Disable the View if we made no changes or the handlers were not able to + // remove the dependencies. This will cause all handler dependencies to be + // ignored on dependency calculation. + if ($disable) { $this->disable(); + $arguments = [ + '@id' => $this->id(), + ]; + $this->getLogger()->warning("View '@id': View was disabled because its settings depend on removed dependencies.", $arguments); + $changed = TRUE; } $this->getExecutable()->setDisplay($current_display); - return $result; + return $disable || $changed; + } + + /** + * Provides the 'system' channel logger service. + * + * @return \Psr\Log\LoggerInterface + * The 'system' channel logger. + */ + protected function getLogger() { + return \Drupal::logger('system'); } } only in patch2: unchanged: --- a/core/modules/views/src/Plugin/views/field/EntityField.php +++ b/core/modules/views/src/Plugin/views/field/EntityField.php @@ -22,6 +22,7 @@ use Drupal\Core\TypedData\TypedDataInterface; use Drupal\views\FieldAPIHandlerTrait; use Drupal\views\Entity\Render\EntityFieldRenderer; +use Drupal\views\Plugin\DependentWithRemovalPluginInterface; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ResultRow; use Drupal\views\ViewExecutable; @@ -34,7 +35,7 @@ * * @ViewsField("field") */ -class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface { +class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface, DependentWithRemovalPluginInterface { use FieldAPIHandlerTrait; use PluginDependencyTrait; @@ -1070,4 +1071,21 @@ public function getValue(ResultRow $values, $field = NULL) { } } + /** + * {@inheritdoc} + */ + public function onDependencyRemoval(array $dependencies) { + $remove = FALSE; + $current_dependencies = $this->calculateDependencies(); + foreach ($current_dependencies as $group => $dependency_list) { + foreach ($dependency_list as $config_key) { + if (isset($dependencies[$group]) && array_key_exists($config_key, $dependencies[$group])) { + $remove = TRUE; + break 2; + } + } + } + return $remove; + } + }