/** * @covers ::calculateDependencies * @covers ::getDependencies * @covers ::onDependencyRemoval */ public function testCalculateDependenciesWithThirdPartySettings() { $this->entity = $this->getMockForAbstractClass('\\Drupal\\Core\\Config\\Entity\\ConfigEntityBase', array(array(), $this->entityTypeId)); $this->entity->setThirdPartySetting('test_provider', 'test', 'test'); $this->entity->setThirdPartySetting('test_provider2', 'test', 'test'); $this->entity->setThirdPartySetting($this->provider, 'test', 'test'); $this->assertEquals(array('test_provider', 'test_provider2'), $this->entity->calculateDependencies()->getDependencies()['module']); $changed = $this->entity->onDependencyRemoval(['module' => ['test_provider2']]); $this->assertTrue($changed, 'Calling onDependencyRemoval with an existing third party dependency provider returns TRUE.'); $changed = $this->entity->onDependencyRemoval(['module' => ['test_provider3']]); $this->assertFalse($changed, 'Calling onDependencyRemoval with a non-existing third party dependency provider returns FALSE.'); $this->assertEquals(array('test_provider'), $this->entity->calculateDependencies()->getDependencies()['module']); }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); $definition = $field_type_manager->getDefinition($this->getType()); if ($definition['class']::onDependencyRemoval($this, $dependencies)) { $changed = TRUE; } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); if (!isset($this->dependencies['enforced']['config'])) { return $changed; } $fix_deps = \Drupal::state()->get('config_test.fix_dependencies', array()); foreach ($dependencies['config'] as $entity) { if (in_array($entity->getConfigDependencyName(), $fix_deps)) { $key = array_search($entity->getConfigDependencyName(), $this->dependencies['enforced']['config']); if ($key !== FALSE) { $changed = TRUE; unset($this->dependencies['enforced']['config'][$key]); } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); $filters = $this->filters(); foreach ($filters as $filter) { // Remove disabled filters, so that this FilterFormat config entity can // continue to exist. if (!$filter->status && in_array($filter->provider, $dependencies['module'])) { $this->removeFilter($filter->getPluginId()); $changed = TRUE; } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); $all_plugins = $this->getAllPlugins(); $dependency_data = $this->getDependencyData(); // Make sure our dependency data has the exact same keys as $dependencies, // to simplify the subsequent code. $dependencies = array_filter($dependencies); $dependency_data = array_intersect_key($dependency_data, $dependencies); $dependency_data += array_fill_keys(array_keys($dependencies), array()); $call_on_removal = array(); foreach ($dependencies as $dependency_type => $dependency_objects) { // Annoyingly, modules and theme dependencies come not keyed by dependency // name here, while entities do. Flip the array for modules and themes to // make the code simpler. if (in_array($dependency_type, array('module', 'theme'))) { $dependency_objects = array_flip($dependency_objects); } $dependency_data[$dependency_type] = array_intersect_key($dependency_data[$dependency_type], $dependency_objects); foreach ($dependency_data[$dependency_type] as $name => $dependency_sources) { // We first remove all the "hard" dependencies. if (!empty($dependency_sources['always'])) { foreach ($dependency_sources['always'] as $plugin_type => $plugins) { // We can hardly remove the index itself. if ($plugin_type == 'index') { continue; } $all_plugins[$plugin_type] = array_diff_key($all_plugins[$plugin_type], $plugins); $changed = TRUE; } } // Then, collect all the optional ones. if (!empty($dependency_sources['optional'])) { // However this plays out, it will lead to a change. $changed = TRUE; foreach ($dependency_sources['optional'] as $plugin_type => $plugins) { // Deal with the index right away, since that dependency can only be // the server. if ($plugin_type == 'index') { $this->setServer(NULL); continue; } // Only include those plugins that have not already been removed. $plugins = array_intersect_key($plugins, $all_plugins[$plugin_type]); foreach ($plugins as $plugin_id => $plugin) { $call_on_removal[$plugin_type][$plugin_id][$dependency_type][$name] = $dependency_objects[$name]; } } } } } // Now for all plugins with optional dependencies (stored in // $call_on_removal, mapped to their removed dependencies) call their // onDependencyRemoval() methods. $updated_config = array(); foreach ($call_on_removal as $plugin_type => $plugins) { foreach ($plugins as $plugin_id => $plugin_dependencies) { $removal_successful = $all_plugins[$plugin_type][$plugin_id]->onDependencyRemoval($plugin_dependencies); // If the plugin was successfully changed to remove the dependency, // remember the new configuration to later set it. Otherwise, remove the // plugin from the index so the dependency still gets removed. if ($removal_successful) { $updated_config[$plugin_type][$plugin_id] = $all_plugins[$plugin_type][$plugin_id]->getConfiguration(); } else { unset($all_plugins[$plugin_type][$plugin_id]); } } } // The handling of how we translate plugin changes back to the index varies // according to plugin type, unfortunately. // First, remove plugins that need to be removed. $this->processor_settings = array_intersect_key($this->processor_settings, $all_plugins['processors']); $this->processorInstances = array_intersect_key($this->processorInstances, $all_plugins['processors']); $this->datasource_settings = array_intersect_key($this->datasource_settings, $all_plugins['datasources']); $this->datasourceInstances = array_intersect_key($this->datasourceInstances, $all_plugins['datasources']); // There always needs to be a tracker so reset it back to the default // tracker. if (empty($all_plugins['tracker'])) { $default_tracker_id = \Drupal::config('search_api.settings')->get('default_tracker'); $this->tracker_settings = array($default_tracker_id => array('plugin_id' => $default_tracker_id, 'settings' => array())); // Reset $trackerInstance so it will get newly loaded from our reset // settings when required. $this->trackerInstance = NULL; } // There also always needs to be a datasource, but here we have no easy way // out – if we had to remove all datasources, the operation fails. Return // FALSE to indicate this, which will cause the index to be deleted. if (!$this->datasource_settings) { return FALSE; } // Then, update configuration as necessary. foreach ($updated_config as $plugin_type => $plugin_configs) { foreach ($plugin_configs as $plugin_id => $plugin_config) { switch ($plugin_type) { case 'processors': $this->processor_settings[$plugin_id]['settings'] = $plugin_config; break; case 'datasources': $this->datasource_settings[$plugin_id]['settings'] = $plugin_config; break; case 'tracker': $this->tracker_settings[$plugin_id]['settings'] = $plugin_config; break; } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); foreach ($dependencies['config'] as $entity) { if ($entity->getEntityTypeId() == 'field_config') { // Remove components for fields that are being deleted. $this->removeComponent($entity->getName()); unset($this->hidden[$entity->getName()]); $changed = TRUE; } } foreach ($this->getComponents() as $name => $component) { if (isset($component['type']) && ($definition = $this->pluginManager->getDefinition($component['type'], FALSE))) { if (in_array($definition['provider'], $dependencies['module'])) { // Revert to the defaults if the plugin that supplies the widget or // formatter depends on a module that is being uninstalled. $this->setComponent($name); $changed = TRUE; } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); // @todo Also react sensibly when removing the dependency of a plugin or an // indexed field. See #2574633 and #2541206. foreach ($dependencies['config'] as $entity) { if ($entity instanceof EntityInterface && $entity->getEntityTypeId() == 'search_api_server') { // Remove this index from the deleted server (thus disabling it). $this->setServer(NULL); $this->setStatus(FALSE); $changed = TRUE; } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); if ($this->hasValidBackend()) { $removed_backend_dependencies = array(); $backend = $this->getBackend(); foreach ($backend->calculateDependencies() as $dependency_type => $list) { if (isset($dependencies[$dependency_type])) { $removed_backend_dependencies[$dependency_type] = array_intersect_key($dependencies[$dependency_type], array_flip($list)); } } $removed_backend_dependencies = array_filter($removed_backend_dependencies); if ($removed_backend_dependencies) { if ($backend->onDependencyRemoval($removed_backend_dependencies)) { $this->backend_config = $backend->getConfiguration(); $changed = TRUE; } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $changed = parent::onDependencyRemoval($dependencies); foreach ($dependencies['config'] as $entity) { if ($entity->getEntityTypeId() == 'field_config') { // Remove components for fields that are being deleted. $this->removeComponent($entity->getName()); unset($this->hidden[$entity->getName()]); $changed = TRUE; } } foreach ($this->getComponents() as $name => $component) { if ($renderer = $this->getRenderer($name)) { if (in_array($renderer->getPluginDefinition()['provider'], $dependencies['module'])) { // Revert to the defaults if the plugin that supplies the widget or // formatter depends on a module that is being uninstalled. $this->setComponent($name); $changed = TRUE; } // Give this component the opportunity to react on dependency removal. $component_removed_dependencies = $this->getPluginRemovedDependencies($renderer->calculateDependencies(), $dependencies); if ($component_removed_dependencies) { if ($renderer->onDependencyRemoval($component_removed_dependencies)) { // Update component settings to reflect changes. $component['settings'] = $renderer->getSettings(); $component['third_party_settings'] = []; foreach ($renderer->getThirdPartyProviders() as $module) { $component['third_party_settings'][$module] = $renderer->getThirdPartySettings($module); } $this->setComponent($name, $component); $changed = TRUE; } // If there are unresolved deleted dependencies left, disable this // component to avoid the removal of the entire display entity. if ($this->getPluginRemovedDependencies($renderer->calculateDependencies(), $dependencies)) { $this->removeComponent($name); $arguments = ['@display' => (string) $this->getEntityType()->getLabel(), '@id' => $this->id(), '@name' => $name]; $this->getLogger()->warning("@display '@id': Component '@name' was disabled because its settings depend on removed dependencies.", $arguments); $changed = TRUE; } } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { // Record which entities have this method called on. $called = \Drupal::state()->get('config_test.on_dependency_removal_called', []); $called[] = $this->id(); \Drupal::state()->set('config_test.on_dependency_removal_called', $called); $changed = parent::onDependencyRemoval($dependencies); if (!isset($this->dependencies['enforced']['config'])) { return $changed; } $fix_deps = \Drupal::state()->get('config_test.fix_dependencies', array()); foreach ($dependencies['config'] as $entity) { if (in_array($entity->getConfigDependencyName(), $fix_deps)) { $key = array_search($entity->getConfigDependencyName(), $this->dependencies['enforced']['config']); if ($key !== FALSE) { $changed = TRUE; unset($this->dependencies['enforced']['config'][$key]); } } } return $changed; }
/** * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { $parent = parent::onDependencyRemoval($dependencies); // If the dependency problems are not marked as fixed at this point they // should be related to the resource plugin and the config entity should // be deleted. $changed = $this->getRestResourceDependencies()->onDependencyRemoval($this, $dependencies); return $parent || $changed; }