Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 143
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
IslandPluginManager
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 143
0.00% covered (danger)
0.00%
0 / 5
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIslandsByTypes
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
 createInstances
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 findDefinitions
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 126
0.00% covered (danger)
0.00%
0 / 1
90
 sortListByWeight
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder;
6
7use Drupal\Core\Cache\CacheBackendInterface;
8use Drupal\Core\Extension\ModuleHandlerInterface;
9use Drupal\Core\Plugin\DefaultPluginManager;
10use Drupal\display_builder\Attribute\Island;
11
12/**
13 * Island plugin manager.
14 */
15final class IslandPluginManager extends DefaultPluginManager implements IslandPluginManagerInterface {
16
17  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
18    parent::__construct('Plugin/display_builder/Island', $namespaces, $module_handler, IslandInterface::class, Island::class);
19    $this->alterInfo('island_info');
20    $this->setCacheBackend($cache_backend, 'island_plugins');
21  }
22
23  /**
24   * {@inheritdoc}
25   */
26  public function getIslandsByTypes(array $contexts = [], array $configuration = [], ?array $filter_by_island = NULL): array {
27    $result = [];
28
29    foreach ($this->createInstances($this->getDefinitions(), $contexts, $configuration) as $island_id => $island) {
30      if ($filter_by_island && !isset($filter_by_island[$island_id])) {
31        continue;
32      }
33      /** @var \Drupal\display_builder\IslandType $type */
34      $type = $island->getPluginDefinition()['type'];
35      $result[$type->value][$island_id] = $island;
36    }
37
38    if ($filter_by_island) {
39      $result = $this->sortListByWeight($result, $filter_by_island);
40    }
41
42    return $result;
43  }
44
45  /**
46   * Create a plugin instances for each definition.
47   *
48   * @param array $definitions
49   *   An array of definitions.
50   * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
51   *   (Optional) An array of contexts, keyed by context name.
52   * @param array $configuration
53   *   (Optional) An array of configuration.
54   *
55   * @return array
56   *   A list of fully configured plugin instances.
57   */
58  public function createInstances(array $definitions, array $contexts = [], array $configuration = []): array {
59    return \array_map(
60      function ($definition) use ($configuration, $contexts) {
61        $config = $configuration[$definition['id']] ?? [];
62        $config['contexts'] = $contexts;
63
64        return $this->createInstance($definition['id'], $config);
65      },
66      $definitions,
67    );
68  }
69
70  /**
71   * {@inheritdoc}
72   */
73  protected function findDefinitions() {
74    $definitions = $this->getDiscovery()->getDefinitions();
75
76    foreach ($definitions as $plugin_id => &$definition) {
77      $this->processDefinition($definition, $plugin_id);
78    }
79    $this->alterDefinitions($definitions);
80
81    // If this plugin was provided by a module that does not exist, remove the
82    // plugin definition.
83    foreach ($definitions as $plugin_id => $plugin_definition) {
84      $provider = $this->extractProviderFromDefinition($plugin_definition);
85
86      if ($provider && !\in_array($provider, ['core', 'component'], TRUE) && !$this->providerExists($provider)) {
87        unset($definitions[$plugin_id]);
88      }
89
90      if (!empty($plugin_definition['modules'] ?? [])) {
91        foreach ($plugin_definition['modules'] as $module) {
92          if (!$this->moduleHandler->moduleExists($module)) {
93            unset($definitions[$plugin_id]);
94          }
95        }
96      }
97    }
98
99    return $definitions;
100  }
101
102  /**
103   * Sort by comparison a list.
104   *
105   * @param array $list
106   *   The list to sort.
107   * @param array<int,mixed> $weight
108   *   The weigh mapping as id => weight.
109   *
110   * @return array<int,mixed>
111   *   The sorted list.
112   */
113  private function sortListByWeight(array $list, array $weight): array {
114    foreach ($list as &$items) {
115      \uksort($items, static function ($a, $b) use ($weight) {
116        return $weight[$a] <=> $weight[$b];
117      });
118    }
119
120    return $list;
121  }
122
123}