Unverified Commit 7c964eeb authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2579743 by yched, sam152, claudiu.cristea, tim.plunkett, godotislate,...

Issue #2579743 by yched, sam152, claudiu.cristea, tim.plunkett, godotislate, alexpott, nicxvan: Config entities implementing EntityWithPluginCollectionInterface should ask the plugins to react when their dependencies are removed
parent 02eea477
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ interface DependentPluginInterface {
   *
   * @see \Drupal\Core\Config\Entity\ConfigDependencyManager
   * @see \Drupal\Core\Entity\EntityInterface::getConfigDependencyName()
   * @see \Drupal\Core\Plugin\RemovableDependentPluginInterface
   */
  public function calculateDependencies();

+17 −0
Original line number Diff line number Diff line
@@ -12,7 +12,9 @@
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
use Drupal\Core\Entity\SynchronizableEntityTrait;
use Drupal\Core\Plugin\RemovableDependentPluginInterface;
use Drupal\Core\Plugin\PluginDependencyTrait;
use Drupal\Core\Plugin\RemovableDependentPluginReturn;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
@@ -480,6 +482,21 @@ public function onDependencyRemoval(array $dependencies) {
      $this->third_party_settings = array_diff_key($this->third_party_settings, array_flip($dependencies['module']));
      $changed = $old_count != count($this->third_party_settings);
    }
    if ($this instanceof EntityWithPluginCollectionInterface) {
      // Allow associated plugins to recalculate their dependencies and update
      // settings on dependency removal.
      foreach ($this->getPluginCollections() as $plugin_collection) {
        foreach ($plugin_collection as $id => $instance) {
          if ($instance instanceof RemovableDependentPluginInterface) {
            $changed = match ($instance->onCollectionDependencyRemoval($dependencies)) {
              RemovableDependentPluginReturn::Remove => $plugin_collection->removeInstanceId($id) || TRUE,
              RemovableDependentPluginReturn::Changed => TRUE,
              RemovableDependentPluginReturn::Unchanged => $changed,
            };
          }
        }
      }
    }
    return $changed;
  }

+38 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Plugin;

use Drupal\Component\Plugin\DependentPluginInterface;

/**
 * Provides an interface for plugins that react when dependencies are removed.
 *
 * @ingroup plugin_api
 */
interface RemovableDependentPluginInterface extends DependentPluginInterface {

  /**
   * Informs the plugin in a collection to act on removal of dependencies.
   *
   * This method allows a plugin instance in a collection to remove dependencies
   * from their configuration. For example, if a plugin integrates with a
   * specific module, it should remove that module from its own configuration
   * when the module is uninstalled.
   *
   * @param array<string, list<string>> $dependencies
   *   An array of dependencies that will be deleted keyed by dependency type.
   *   Dependency types are, for example, entity, module and theme.
   *
   * @return \Drupal\Core\Plugin\RemovableDependentPluginReturn
   *   - RemovableDependentPluginReturn::Changed if the configuration of the
   *     plugin instance has changed
   *   - RemovableDependentPluginReturn::Remove if the plugin instance should be
   *     removed from the plugin collection
   *   - RemovableDependentPluginReturn::Unchanged if the configuration of the
   *     plugin instance has not changed.
   */
  public function onCollectionDependencyRemoval(array $dependencies): RemovableDependentPluginReturn;

}
+18 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Plugin;

/**
 * Enumeration of return values when acting on plugin dependency removal.
 *
 * @see \Drupal\Core\Plugin\RemovableDependentPluginInterface::onCollectionDependencyRemoval()
 */
enum RemovableDependentPluginReturn {

  case Changed;
  case Remove;
  case Unchanged;

}
+10 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\ConfigurablePluginBase;
use Drupal\Core\Plugin\RemovableDependentPluginReturn;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

@@ -157,4 +158,13 @@ public function calculateDependencies() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function onCollectionDependencyRemoval(array $dependencies): RemovableDependentPluginReturn {
    // If the module that provides the image effect plugin is uninstalled,
    // the plugin instance should be removed from the collection.
    return in_array($this->getPluginDefinition()['provider'], $dependencies['module'] ?? []) ? RemovableDependentPluginReturn::Remove : RemovableDependentPluginReturn::Unchanged;
  }

}
Loading