3 namespace Drupal\Core\Plugin;
5 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
6 use Drupal\Component\Plugin\LazyPluginCollection;
7 use Drupal\Component\Plugin\PluginManagerInterface;
8 use Drupal\Component\Plugin\ConfigurablePluginInterface;
9 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
12 * Provides a default plugin collection for a plugin type.
14 * A plugin collection is used to contain plugins that will be lazily
15 * instantiated. The configurations of each potential plugin are passed in, and
16 * the configuration key containing the plugin ID is specified by
19 class DefaultLazyPluginCollection extends LazyPluginCollection {
20 use DependencySerializationTrait;
23 * The manager used to instantiate the plugins.
25 * @var \Drupal\Component\Plugin\PluginManagerInterface
30 * The initial configuration for each plugin in the collection.
33 * An associative array containing the initial configuration for each plugin
34 * in the collection, keyed by plugin instance ID.
36 protected $configurations = [];
39 * The key within the plugin configuration that contains the plugin ID.
43 protected $pluginKey = 'id';
46 * The original order of the instances.
50 protected $originalOrder = [];
53 * Constructs a new DefaultLazyPluginCollection object.
55 * @param \Drupal\Component\Plugin\PluginManagerInterface $manager
56 * The manager to be used for instantiating plugins.
57 * @param array $configurations
58 * (optional) An associative array containing the initial configuration for
59 * each plugin in the collection, keyed by plugin instance ID.
61 public function __construct(PluginManagerInterface $manager, array $configurations = []) {
62 $this->manager = $manager;
63 $this->configurations = $configurations;
65 if (!empty($configurations)) {
66 $instance_ids = array_keys($configurations);
67 $this->instanceIDs = array_combine($instance_ids, $instance_ids);
68 // Store the original order of the instance IDs for export.
69 $this->originalOrder = $this->instanceIDs;
76 protected function initializePlugin($instance_id) {
77 $configuration = isset($this->configurations[$instance_id]) ? $this->configurations[$instance_id] : [];
78 if (!isset($configuration[$this->pluginKey])) {
79 throw new PluginNotFoundException($instance_id);
81 $this->set($instance_id, $this->manager->createInstance($configuration[$this->pluginKey], $configuration));
85 * Sorts all plugin instances in this collection.
89 public function sort() {
90 uasort($this->instanceIDs, [$this, 'sortHelper']);
95 * Provides uasort() callback to sort plugins.
97 public function sortHelper($aID, $bID) {
98 $a = $this->get($aID);
99 $b = $this->get($bID);
100 return strnatcasecmp($a->getPluginId(), $b->getPluginId());
106 public function getConfiguration() {
108 // Store the current order of the instances.
109 $current_order = $this->instanceIDs;
110 // Reorder the instances to match the original order, adding new instances
112 $this->instanceIDs = $this->originalOrder + $current_order;
114 foreach ($this as $instance_id => $instance) {
115 if ($instance instanceof ConfigurablePluginInterface) {
116 $instances[$instance_id] = $instance->getConfiguration();
119 $instances[$instance_id] = $this->configurations[$instance_id];
122 // Restore the current order.
123 $this->instanceIDs = $current_order;
130 public function setConfiguration($configuration) {
131 // Track each instance ID as it is updated.
132 $unprocessed_instance_ids = $this->getInstanceIds();
134 foreach ($configuration as $instance_id => $instance_configuration) {
135 $this->setInstanceConfiguration($instance_id, $instance_configuration);
136 // Remove this instance ID from the list being updated.
137 unset($unprocessed_instance_ids[$instance_id]);
140 // Remove remaining instances that had no configuration specified for them.
141 foreach ($unprocessed_instance_ids as $unprocessed_instance_id) {
142 $this->removeInstanceId($unprocessed_instance_id);
148 * Updates the configuration for a plugin instance.
150 * If there is no plugin instance yet, a new will be instantiated. Otherwise,
151 * the existing instance is updated with the new configuration.
153 * @param string $instance_id
154 * The ID of a plugin to set the configuration for.
155 * @param array $configuration
156 * The plugin configuration to set.
158 public function setInstanceConfiguration($instance_id, array $configuration) {
159 $this->configurations[$instance_id] = $configuration;
160 $instance = $this->get($instance_id);
161 if ($instance instanceof ConfigurablePluginInterface) {
162 $instance->setConfiguration($configuration);
169 public function addInstanceId($id, $configuration = NULL) {
170 parent::addInstanceId($id);
171 if ($configuration !== NULL) {
172 $this->setInstanceConfiguration($id, $configuration);
174 if (!isset($this->originalOrder[$id])) {
175 $this->originalOrder[$id] = $id;
182 public function removeInstanceId($instance_id) {
183 parent::removeInstanceId($instance_id);
184 unset($this->originalOrder[$instance_id]);
185 unset($this->configurations[$instance_id]);