/**
  * @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']);
 }
Example #2
0
 /**
  * {@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;
 }
Example #3
0
 /**
  * {@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;
 }
Example #4
0
 /**
  * {@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;
 }
Example #5
0
 /**
  * {@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;
 }
Example #6
0
 /**
  * {@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;
 }
Example #7
0
  /**
   * {@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;
  }
Example #8
0
 /**
  * {@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;
 }
Example #9
0
 /**
  * {@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;
 }
Example #10
0
 /**
  * {@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;
 }
Example #11
0
 /**
  * {@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;
 }