Commit 8e871302 authored by catch's avatar catch

Revert "Issue #2468045 by Lendude, geertvd, vaplas, tim.plunkett, dawehner,...

Revert "Issue #2468045 by Lendude, geertvd, vaplas, tim.plunkett, dawehner, xjm, cilefen, Berdir, catch: When deleting a content type field, users do not realize the related View also is deleted"

This reverts commit 917ed83e.
parent 917ed83e
<?php
namespace Drupal\Core\Plugin;
/**
* Provides an interface for a plugin that has dependencies that can be removed.
*
* @ingroup plugin_api
*/
interface DependentWithRemovalPluginInterface {
/**
* Allows a plugin to define whether it should be removed.
*
* If this method returns TRUE then the plugin should be removed.
*
* @param array $dependencies
* An array of dependencies that will be deleted keyed by dependency type.
* Dependency types are, for example, entity, module and theme.
*
* @return bool
* TRUE if the plugin instance should be removed.
*
* @see \Drupal\Core\Config\Entity\ConfigDependencyManager
* @see \Drupal\Core\Config\ConfigEntityBase::preDelete()
* @see \Drupal\Core\Config\ConfigManager::uninstall()
* @see \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval()
*/
public function onDependencyRemoval(array $dependencies);
}
......@@ -5,7 +5,6 @@
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\simpletest\WebTestBase;
use Drupal\views\Entity\View;
use Drupal\views\Tests\ViewTestData;
/**
......@@ -92,13 +91,13 @@ public function testDeleteField() {
// Check the config dependencies of the first field.
$this->drupalGet("$bundle_path2/fields/node.$type_name2.$field_name/delete");
$this->assertText(t('The listed configuration will be updated.'));
$this->assertText(t('The listed configuration will be deleted.'));
$this->assertText(t('View'));
$this->assertText('test_view_field_delete');
$xml = $this->cssSelect('#edit-entity-deletes');
// Test that nothing is scheduled for deletion.
$this->assertFalse(isset($xml[0]), 'The field currently being deleted is not shown in the entity deletions.');
// Remove the wrapping HTML.
$this->assertIdentical(FALSE, strpos($xml[0]->asXml(), $field_label), 'The currently being deleted field is not shown in the entity deletions.');
// Delete the second field.
$this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$field_name", $field_label, $type_name2);
......@@ -107,11 +106,6 @@ public function testDeleteField() {
$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());
}
}
......@@ -9,7 +9,6 @@
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\DependentWithRemovalPluginInterface;
use Drupal\views\Views;
use Drupal\views\ViewEntityInterface;
......@@ -513,61 +512,4 @@ public function invalidateCaches() {
\Drupal::service('cache_tags.invalidator')->invalidateTags($tags);
}
/**
* {@inheritdoc}
*/
public function onDependencyRemoval(array $dependencies) {
$changed = FALSE;
// Don't intervene if the views module is removed.
if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) {
return FALSE;
}
// If the base table for the View is provided by a module being removed, we
// delete the View because this is not something that can be fixed manually.
$views_data = Views::viewsData();
$base_table = $this->get('base_table');
$base_table_data = $views_data->get($base_table);
if (!empty($base_table_data['table']['provider']) && in_array($base_table_data['table']['provider'], $dependencies['module'])) {
return FALSE;
}
$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.
unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]);
$changed = TRUE;
}
}
}
}
}
// Disable the View if we made changes.
// @todo https://www.drupal.org/node/2832558 Give better feedback for
// disabled config.
if ($changed) {
// Force a recalculation of the dependencies if we made changes.
$this->getExecutable()->current_display = NULL;
$this->calculateDependencies();
$this->disable();
}
$this->getExecutable()->setDisplay($current_display);
return $changed;
}
}
......@@ -14,7 +14,6 @@
use Drupal\Core\Form\FormHelper;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\DependentWithRemovalPluginInterface;
use Drupal\Core\Plugin\PluginDependencyTrait;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
......@@ -35,7 +34,7 @@
*
* @ViewsField("field")
*/
class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface, DependentWithRemovalPluginInterface {
class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface {
use FieldAPIHandlerTrait;
use PluginDependencyTrait;
......@@ -1078,29 +1077,4 @@ public function getValue(ResultRow $values, $field = NULL) {
}
}
/**
* {@inheritdoc}
*/
public function onDependencyRemoval(array $dependencies) {
// See if this handler is responsible for any of the dependencies being
// removed. If this is the case, indicate that this handler needs to be
// removed from the View.
$remove = FALSE;
// Get all the current dependencies for this handler.
$current_dependencies = $this->calculateDependencies();
foreach ($current_dependencies as $group => $dependency_list) {
// Check if any of the handler dependencies match the dependencies being
// removed.
foreach ($dependency_list as $config_key) {
if (isset($dependencies[$group]) && array_key_exists($config_key, $dependencies[$group])) {
// This handlers dependency matches a dependency being removed,
// indicate that this handler needs to be removed.
$remove = TRUE;
break 2;
}
}
}
return $remove;
}
}
......@@ -5,7 +5,6 @@
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\image\Entity\ImageStyle;
use Drupal\user\Entity\Role;
use Drupal\views\Entity\View;
/**
......@@ -18,23 +17,13 @@ class ViewsConfigDependenciesIntegrationTest extends ViewsKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'file', 'image', 'entity_test', 'user', 'text'];
public static $modules = ['field', 'file', 'image', 'entity_test'];
/**
* {@inheritdoc}
*/
public static $testViews = ['entity_test_fields'];
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
$this->installEntitySchema('user');
$this->installSchema('user', ['users_data']);
}
/**
* Tests integration with image module.
*/
......@@ -80,77 +69,7 @@ public function testImage() {
// Delete the 'foo' image style.
$style->delete();
$view = View::load('entity_test_fields');
// Checks that the view has not been deleted too.
$this->assertNotNull(View::load('entity_test_fields'));
// Checks that the image field was removed from the View.
$display = $view->getDisplay('default');
$this->assertFalse(isset($display['display_options']['fields']['bar']));
// Checks that the view has been disabled.
$this->assertFalse($view->status());
}
/**
* Tests removing a config dependency that deletes the View.
*/
public function testConfigRemovalRole() {
// Create a role we can add to the View and delete.
$role = Role::create([
'id' => 'dummy',
'label' => 'dummy',
]);
$role->save();
/** @var \Drupal\views\ViewEntityInterface $view */
$view = View::load('entity_test_fields');
$display = &$view->getDisplay('default');
// Set the access to be restricted by the dummy role.
$display['display_options']['access'] = [
'type' => 'role',
'options' => [
'role' => [
$role->id() => $role->id(),
],
],
];
$view->save();
// Check that the View now has a dependency on the Role.
$dependencies = $view->getDependencies() + ['config' => []];
$this->assertTrue(in_array('user.role.dummy', $dependencies['config']));
// Delete the role.
$role->delete();
$view = View::load('entity_test_fields');
// Checks that the view has been deleted too.
$this->assertNull($view);
}
/**
* Tests uninstalling a module that provides a base table for a View.
*/
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();
foreach ($entities as $entity_type_id => $definition) {
if ($definition->getProvider() == 'entity_test') {
$this->installEntitySchema($entity_type_id);
};
}
// Check that removing the module that provides the base table for a View,
// deletes the View.
$this->assertNotNull(View::load('entity_test_fields'));
$this->container->get('module_installer')->uninstall(['entity_test']);
// Check that the View has been deleted.
$this->assertNull(View::load('entity_test_fields'));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment