Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 114
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
BlockLibraryPanel
0.00% covered (danger)
0.00%
0 / 108
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 10
870
0.00% covered (danger)
0.00%
0 / 1
 create
0.00% covered (danger)
0.00%
0 / 4
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
 defaultConfiguration
0.00% covered (danger)
0.00%
0 / 7
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
 buildConfigurationForm
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
 configurationSummary
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 build
0.00% covered (danger)
0.00%
0 / 20
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
 label
0.00% covered (danger)
0.00%
0 / 1
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
 buildCategorySection
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 getSources
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 getProvidersOptions
0.00% covered (danger)
0.00%
0 / 8
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
 getProviders
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\Extension\ModuleExtensionList;
8use Drupal\Core\Form\FormStateInterface;
9use Drupal\Core\StringTranslation\TranslatableMarkup;
10use Drupal\display_builder\Attribute\Island;
11use Drupal\display_builder\BlockLibrarySourceHelper;
12use Drupal\display_builder\InstanceInterface;
13use Drupal\display_builder\IslandConfigurationFormInterface;
14use Drupal\display_builder\IslandConfigurationFormTrait;
15use Drupal\display_builder\IslandPluginBase;
16use Drupal\display_builder\IslandType;
17use Drupal\display_builder\SourceWithSlotsInterface;
18use Drupal\ui_patterns\SourcePluginBase;
19use Drupal\ui_patterns\SourcePluginManager;
20use Drupal\ui_patterns\SourceWithChoicesInterface;
21use Symfony\Component\DependencyInjection\ContainerInterface;
22
23/**
24 * Block library island plugin implementation.
25 */
26#[Island(
27  id: 'block_library',
28  enabled_by_default: TRUE,
29  label: new TranslatableMarkup('Blocks library'),
30  description: new TranslatableMarkup('List of available blocks.'),
31  type: IslandType::Library,
32)]
33class BlockLibraryPanel extends IslandPluginBase implements IslandConfigurationFormInterface {
34
35  use IslandConfigurationFormTrait;
36
37  private const HIDE_SOURCE = [
38    'component',
39    // Used only for imports from Manage Display and Layout Builder.
40    'extra_field',
41    // No Wysiwyg from our UI until #3561474 is fixed.
42    'wysiwyg',
43  ];
44
45  private const HIDE_PROVIDER = ['ui_patterns_blocks'];
46
47  /**
48   * The sources.
49   */
50  protected array $sources = [];
51
52  /**
53   * The module list extension service.
54   */
55  protected ModuleExtensionList $moduleList;
56
57  /**
58   * The UI Patterns source plugin manager.
59   */
60  protected SourcePluginManager $sourceManager;
61
62  /**
63   * {@inheritdoc}
64   */
65  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
66    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
67    $instance->moduleList = $container->get('extension.list.module');
68    $instance->sourceManager = $container->get('plugin.manager.ui_patterns_source');
69
70    return $instance;
71  }
72
73  /**
74   * {@inheritdoc}
75   */
76  public function defaultConfiguration(): array {
77    return [
78      'exclude' => [
79        'devel',
80        'htmx',
81        'shortcut',
82      ],
83    ];
84  }
85
86  /**
87   * {@inheritdoc}
88   */
89  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
90    $configuration = $this->getConfiguration();
91
92    $form['exclude'] = [
93      '#type' => 'checkboxes',
94      '#title' => $this->t('Exclude modules'),
95      '#options' => $this->getProvidersOptions(),
96      '#default_value' => $configuration['exclude'],
97    ];
98
99    return $form;
100  }
101
102  /**
103   * {@inheritdoc}
104   */
105  public function configurationSummary(): array {
106    $configuration = $this->getConfiguration();
107
108    return [
109      $this->t('Excluded modules: @exclude', [
110        '@exclude' => \implode(', ', \array_filter($configuration['exclude'] ?? []) ?: [$this->t('None')]),
111      ]),
112    ];
113  }
114
115  /**
116   * {@inheritdoc}
117   */
118  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
119    $builder_id = (string) $builder->id();
120    $configuration = $this->getConfiguration();
121
122    $exclude_providers = \array_merge(
123      $configuration['exclude'] ?? [],
124      self::HIDE_PROVIDER
125    );
126    $categories = BlockLibrarySourceHelper::getGroupedChoices(
127      $this->getSources(),
128      $exclude_providers,
129    );
130
131    $build = [];
132
133    foreach ($categories as $category_data) {
134      $build[] = $this->buildCategorySection($category_data, $builder_id);
135    }
136
137    return [
138      '#type' => 'component',
139      '#component' => 'display_builder:library_panel',
140      '#slots' => [
141        'content' => $this->buildDraggables($builder_id, $build),
142      ],
143    ];
144  }
145
146  /**
147   * {@inheritdoc}
148   */
149  public function label(): string {
150    return 'Blocks';
151  }
152
153  /**
154   * Build a category section.
155   *
156   * @param array $category_data
157   *   The category data.
158   * @param string $builder_id
159   *   The builder ID.
160   *
161   * @return array
162   *   The render array for the category section.
163   */
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
168      $section[] = [
169        '#type' => 'html_tag',
170        '#tag' => 'h4',
171        '#attributes' => ['class' => 'db-filter-hide-on-search'],
172        '#value' => $category_data['label'],
173      ];
174    }
175
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
184
185  /**
186   * Returns all possible sources.
187   *
188   * @throws \Drupal\Component\Plugin\Exception\PluginException
189   *
190   * @return array<string, array>
191   *   An array of sources.
192   */
193  private function getSources(): array {
194    if (!empty($this->sources)) {
195      return $this->sources;
196    }
197
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
235
236  /**
237   * Get providers options for select input.
238   *
239   * @return array
240   *   An associative array with module ID as key and module description as
241   *   value.
242   */
243  private function getProvidersOptions(): array {
244    $options = [];
245
246    foreach ($this->getProviders() as $provider_id => $provider) {
247      $params = [
248        '@name' => $provider['name'],
249        '@count' => $provider['count'],
250      ];
251      $options[$provider_id] = $this->formatPlural($provider['count'], '@name (@count block)', '@name (@count blocks)', $params);
252    }
253
254    return $options;
255  }
256
257  /**
258   * Get all providers.
259   *
260   * @return array
261   *   Drupal modules definitions, keyed by extension ID
262   */
263  private function getProviders(): array {
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
296
297}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

BlockLibraryPanel->build
118  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
119    $builder_id = (string) $builder->id();
120    $configuration = $this->getConfiguration();
121
122    $exclude_providers = \array_merge(
123      $configuration['exclude'] ?? [],
124      self::HIDE_PROVIDER
125    );
126    $categories = BlockLibrarySourceHelper::getGroupedChoices(
127      $this->getSources(),
128      $exclude_providers,
129    );
130
131    $build = [];
132
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
134      $build[] = $this->buildCategorySection($category_data, $builder_id);
 
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
134      $build[] = $this->buildCategorySection($category_data, $builder_id);
135    }
136
137    return [
138      '#type' => 'component',
139      '#component' => 'display_builder:library_panel',
140      '#slots' => [
141        'content' => $this->buildDraggables($builder_id, $build),
142      ],
143    ];
144  }
118  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
119    $builder_id = (string) $builder->id();
120    $configuration = $this->getConfiguration();
121
122    $exclude_providers = \array_merge(
123      $configuration['exclude'] ?? [],
124      self::HIDE_PROVIDER
125    );
126    $categories = BlockLibrarySourceHelper::getGroupedChoices(
127      $this->getSources(),
128      $exclude_providers,
129    );
130
131    $build = [];
132
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
134      $build[] = $this->buildCategorySection($category_data, $builder_id);
135    }
136
137    return [
138      '#type' => 'component',
139      '#component' => 'display_builder:library_panel',
140      '#slots' => [
141        'content' => $this->buildDraggables($builder_id, $build),
142      ],
143    ];
144  }
118  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
119    $builder_id = (string) $builder->id();
120    $configuration = $this->getConfiguration();
121
122    $exclude_providers = \array_merge(
123      $configuration['exclude'] ?? [],
124      self::HIDE_PROVIDER
125    );
126    $categories = BlockLibrarySourceHelper::getGroupedChoices(
127      $this->getSources(),
128      $exclude_providers,
129    );
130
131    $build = [];
132
133    foreach ($categories as $category_data) {
 
133    foreach ($categories as $category_data) {
134      $build[] = $this->buildCategorySection($category_data, $builder_id);
135    }
136
137    return [
138      '#type' => 'component',
139      '#component' => 'display_builder:library_panel',
140      '#slots' => [
141        'content' => $this->buildDraggables($builder_id, $build),
142      ],
143    ];
144  }
BlockLibraryPanel->buildCategorySection
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
169        '#type' => 'html_tag',
170        '#tag' => 'h4',
171        '#attributes' => ['class' => 'db-filter-hide-on-search'],
172        '#value' => $category_data['label'],
173      ];
174    }
175
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
177      $section[] = $choice['preview']
 
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
169        '#type' => 'html_tag',
170        '#tag' => 'h4',
171        '#attributes' => ['class' => 'db-filter-hide-on-search'],
172        '#value' => $category_data['label'],
173      ];
174    }
175
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
177      $section[] = $choice['preview']
 
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
169        '#type' => 'html_tag',
170        '#tag' => 'h4',
171        '#attributes' => ['class' => 'db-filter-hide-on-search'],
172        '#value' => $category_data['label'],
173      ];
174    }
175
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
169        '#type' => 'html_tag',
170        '#tag' => 'h4',
171        '#attributes' => ['class' => 'db-filter-hide-on-search'],
172        '#value' => $category_data['label'],
173      ];
174    }
175
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
177      $section[] = $choice['preview']
 
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
177      $section[] = $choice['preview']
 
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
164  private function buildCategorySection(array $category_data, string $builder_id): array {
165    $section = [];
166
167    if (!empty($category_data['label'])) {
 
176    foreach ($category_data['choices'] as $choice) {
 
176    foreach ($category_data['choices'] as $choice) {
177      $section[] = $choice['preview']
178        ? $this->buildPlaceholderButtonWithPreview($builder_id, $choice['label'], $choice['data'] ?? [], $choice['preview'], $choice['keywords'] ?? '')
179        : $this->buildPlaceholderButton($choice['label'], $choice['data'] ?? [], $choice['keywords'] ?? '');
180    }
181
182    return $section;
183  }
BlockLibraryPanel->buildConfigurationForm
89  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
90    $configuration = $this->getConfiguration();
91
92    $form['exclude'] = [
93      '#type' => 'checkboxes',
94      '#title' => $this->t('Exclude modules'),
95      '#options' => $this->getProvidersOptions(),
96      '#default_value' => $configuration['exclude'],
97    ];
98
99    return $form;
100  }
BlockLibraryPanel->configurationSummary
106    $configuration = $this->getConfiguration();
107
108    return [
109      $this->t('Excluded modules: @exclude', [
110        '@exclude' => \implode(', ', \array_filter($configuration['exclude'] ?? []) ?: [$this->t('None')]),
111      ]),
112    ];
113  }
BlockLibraryPanel->create
65  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
66    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
67    $instance->moduleList = $container->get('extension.list.module');
68    $instance->sourceManager = $container->get('plugin.manager.ui_patterns_source');
69
70    return $instance;
71  }
BlockLibraryPanel->defaultConfiguration
79        'devel',
80        'htmx',
81        'shortcut',
82      ],
83    ];
84  }
BlockLibraryPanel->getProviders
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
270        continue;
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
278          continue;
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
283          continue;
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
286        if (!isset($providers[$provider])) {
 
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
286        if (!isset($providers[$provider])) {
 
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
278          continue;
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
283          continue;
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
286        if (!isset($providers[$provider])) {
 
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
 
281        if (!isset($modules[$provider])) {
 
286        if (!isset($providers[$provider])) {
 
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
269      if (!isset($source_data['choices'])) {
 
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
264    $sources = $this->getSources();
265    $providers = [];
266    $modules = $this->moduleList->getAllInstalledInfo();
267
268    foreach ($sources as $source_data) {
 
268    foreach ($sources as $source_data) {
269      if (!isset($source_data['choices'])) {
270        continue;
271      }
272      $choices = $source_data['choices'];
273
274      foreach ($choices as $choice) {
275        $provider = $choice['provider'] ?? '';
276
277        if (!$provider || \in_array($provider, self::HIDE_PROVIDER, TRUE)) {
278          continue;
279        }
280
281        if (!isset($modules[$provider])) {
282          // If the provider is not a module, skip it.
283          continue;
284        }
285
286        if (!isset($providers[$provider])) {
287          $providers[$provider] = $modules[$provider];
288          $providers[$provider]['count'] = 0;
289        }
290        ++$providers[$provider]['count'];
291      }
292    }
293
294    return $providers;
295  }
BlockLibraryPanel->getProvidersOptions
244    $options = [];
245
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
247      $params = [
248        '@name' => $provider['name'],
249        '@count' => $provider['count'],
250      ];
251      $options[$provider_id] = $this->formatPlural($provider['count'], '@name (@count block)', '@name (@count blocks)', $params);
252    }
253
254    return $options;
255  }
244    $options = [];
245
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
247      $params = [
248        '@name' => $provider['name'],
249        '@count' => $provider['count'],
250      ];
251      $options[$provider_id] = $this->formatPlural($provider['count'], '@name (@count block)', '@name (@count blocks)', $params);
252    }
253
254    return $options;
255  }
244    $options = [];
245
246    foreach ($this->getProviders() as $provider_id => $provider) {
 
246    foreach ($this->getProviders() as $provider_id => $provider) {
247      $params = [
248        '@name' => $provider['name'],
249        '@count' => $provider['count'],
250      ];
251      $options[$provider_id] = $this->formatPlural($provider['count'], '@name (@count block)', '@name (@count blocks)', $params);
252    }
253
254    return $options;
255  }
BlockLibraryPanel->getSources
194    if (!empty($this->sources)) {
 
195      return $this->sources;
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
204        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
208        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
211      try {
212        $source = $this->sourceManager->createInstance(
 
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
211      try {
212        $source = $this->sourceManager->createInstance(
 
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
194    if (!empty($this->sources)) {
 
198    $definitions = $this->sourceManager->getDefinitionsForPropType('slot', $this->configuration['contexts'] ?? []);
199    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
200
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
217      catch (\Throwable $e) {
 
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
204        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
217      catch (\Throwable $e) {
 
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
208        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
217      catch (\Throwable $e) {
 
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
211      try {
212        $source = $this->sourceManager->createInstance(
 
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
217      catch (\Throwable $e) {
 
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
 
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
 
211      try {
212        $source = $this->sourceManager->createInstance(
 
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
217      catch (\Throwable $e) {
 
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
 
201    foreach ($definitions as $source_id => $definition) {
 
201    foreach ($definitions as $source_id => $definition) {
202      // A block is a source for slots but without slots.
203      if (\is_a($definition['class'], SourceWithSlotsInterface::class, TRUE)) {
204        continue;
205      }
206
207      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
208        continue;
209      }
210
211      try {
212        $source = $this->sourceManager->createInstance(
213          $source_id,
214          SourcePluginBase::buildConfiguration('slot', $slot_definition, ['source' => []], $this->configuration['contexts'] ?? [])
215        );
216      }
217      catch (\Throwable $e) {
218        $this->logger->error('Invalid source found: %message', ['%message' => $e->getMessage()]);
219
220        continue;
221      }
222
223      $this->sources[$source_id] = [
224        'definition' => $definition,
225        'source' => $source,
226      ];
227
228      if ($source instanceof SourceWithChoicesInterface) {
229        $this->sources[$source_id]['choices'] = $source->getChoices();
230      }
231    }
232
233    return $this->sources;
234  }
BlockLibraryPanel->label
150    return 'Blocks';
151  }