Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 87
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
PresetLibraryPanel
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 7
342
0.00% covered (danger)
0.00%
0 / 1
 create
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
 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
 build
0.00% covered (danger)
0.00%
0 / 39
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
 onPresetSave
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
 buildPresets
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 144
0.00% covered (danger)
0.00%
0 / 1
56
 buildPresetItem
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getPresetGroup
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\Entity\EntityStorageInterface;
8use Drupal\Core\StringTranslation\TranslatableMarkup;
9use Drupal\Core\Url;
10use Drupal\display_builder\Attribute\Island;
11use Drupal\display_builder\BlockLibrarySourceHelper;
12use Drupal\display_builder\InstanceInterface;
13use Drupal\display_builder\IslandPluginBase;
14use Drupal\display_builder\IslandType;
15use Drupal\display_builder\PatternPresetInterface;
16use Symfony\Component\DependencyInjection\ContainerInterface;
17
18/**
19 * Preset island plugin implementation.
20 */
21#[Island(
22  id: 'preset_library',
23  label: new TranslatableMarkup('Preset library'),
24  description: new TranslatableMarkup('List of preset, already build group of components.'),
25  type: IslandType::Library,
26)]
27class PresetLibraryPanel extends IslandPluginBase {
28
29  /**
30   * The Pattern preset storage.
31   */
32  protected EntityStorageInterface $presetConfigStorage;
33
34  /**
35   * {@inheritdoc}
36   */
37  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
38    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
39    $instance->presetConfigStorage = $container->get('entity_type.manager')->getStorage('pattern_preset');
40
41    return $instance;
42  }
43
44  /**
45   * {@inheritdoc}
46   */
47  public function label(): string {
48    return 'Presets';
49  }
50
51  /**
52   * {@inheritdoc}
53   */
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
72      $content = [
73        [
74          '#type' => 'html_tag',
75          '#tag' => 'p',
76        ],
77        [
78          '#type' => 'html_tag',
79          '#tag' => 'p',
80          '#value' => $this->t('Pattern presets are reusable arrangements of components and blocks.'),
81        ],
82        [
83          '#type' => 'html_tag',
84          '#tag' => 'p',
85          '#value' => $this->t('Add presets from the contextual menu.'),
86        ],
87      ];
88    }
89    else {
90      $content = $this->buildPresets($builder_id, $presets);
91    }
92
93    return [
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
104
105  /**
106   * {@inheritdoc}
107   */
108  public function onPresetSave(string $builder_id): array {
109    return $this->reloadWithGlobalData($builder_id);
110  }
111
112  /**
113   * Build preset as placeholder grouped.
114   *
115   * @param string $builder_id
116   *   Builder ID.
117   * @param \Drupal\display_builder\PatternPresetInterface[] $presets
118   *   The presets to build.
119   *
120   * @return array
121   *   Array of grouped preset plugins.
122   */
123  private function buildPresets(string $builder_id, array $presets): array {
124    $build = [];
125    $grouped_presets = [];
126
127    foreach ($presets as $preset_id => $preset) {
128      $group_key = $this->getPresetGroup($preset);
129      $grouped_presets[$group_key][$preset_id] = $preset;
130    }
131
132    $formatted_groups = [];
133
134    foreach ($grouped_presets as $group_name => $presets_in_group) {
135      $formatted_groups[$group_name] = [
136        'label' => $group_name,
137        'choices' => $presets_in_group,
138      ];
139    }
140
141    $is_single_group = \count($formatted_groups) === 1;
142
143    if (!$is_single_group) {
144      BlockLibrarySourceHelper::sortGroupedChoices($formatted_groups);
145    }
146
147    foreach ($formatted_groups as $group_data) {
148      if (!$is_single_group) {
149        $build[] = [
150          '#type' => 'html_tag',
151          '#tag' => 'h4',
152          '#value' => $group_data['label'],
153          '#attributes' => [
154            'class' => ['db-filter-hide-on-search'],
155          ],
156        ];
157      }
158
159      foreach ($group_data['choices'] as $preset) {
160        $build[] = $this->buildPresetItem($builder_id, $preset, TRUE);
161      }
162    }
163
164    $build = $this->buildDraggables($builder_id, $build);
165    $build['#source_contexts'] = $this->configuration['contexts'] ?? [];
166
167    return $build;
168  }
169
170  /**
171   * Build a preset item.
172   *
173   * @param string $builder_id
174   *   Builder ID.
175   * @param \Drupal\display_builder\PatternPresetInterface $preset
176   *   The preset entity.
177   * @param bool $with_preview
178   *   Whether to include preview attributes.
179   *
180   * @return array
181   *   The render array for the preset item.
182   */
183  private function buildPresetItem(string $builder_id, PatternPresetInterface $preset, bool $with_preview): array {
184    $keywords = \sprintf('%s %s', $preset->get('label'), $preset->get('description') ?? '');
185    $vals = ['preset_id' => $preset->id()];
186
187    if ($with_preview) {
188      $url = Url::fromRoute('display_builder.api_preset_preview', $vals);
189
190      $build = $this->buildPlaceholderButtonWithPreview($builder_id, $preset->get('label'), $vals, $url, $keywords);
191    }
192    else {
193      $build = $this->buildPlaceholderButton($preset->get('label'), $vals, $keywords);
194    }
195
196    $build['#attributes']['data-instance-id'][] = $preset->id();
197
198    return $build;
199  }
200
201  /**
202   * Gets the preset's group from the preset entity in the database.
203   *
204   * @param \Drupal\display_builder\PatternPresetInterface $preset
205   *   The preset entity.
206   *
207   * @return string
208   *   The group name, fallback to 'Others'.
209   */
210  private function getPresetGroup(PatternPresetInterface $preset): string {
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
212  }
213
214}

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.

PresetLibraryPanel->build
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
71    if (empty($presets)) {
72      $content = [
73        [
74          '#type' => 'html_tag',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
90      $content = $this->buildPresets($builder_id, $presets);
91    }
92
93    return [
94      '#type' => 'component',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
71    if (empty($presets)) {
72      $content = [
73        [
74          '#type' => 'html_tag',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
90      $content = $this->buildPresets($builder_id, $presets);
91    }
92
93    return [
94      '#type' => 'component',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
71    if (empty($presets)) {
72      $content = [
73        [
74          '#type' => 'html_tag',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
90      $content = $this->buildPresets($builder_id, $presets);
91    }
92
93    return [
94      '#type' => 'component',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
71    if (empty($presets)) {
72      $content = [
73        [
74          '#type' => 'html_tag',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
54  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
55    $builder_id = (string) $builder->id();
56    $entity_ids = $this->presetConfigStorage->getQuery()
57      ->accessCheck(TRUE)
58      ->condition('status', TRUE)
59      ->sort('weight', 'ASC')
60      ->execute();
61    /** @var \Drupal\display_builder\PatternPresetInterface[] $presets */
62    $presets = $this->presetConfigStorage->loadMultiple($entity_ids);
63    $contexts = $this->configuration['contexts'] ?? [];
64
65    foreach ($presets as $preset_id => $preset) {
 
65    foreach ($presets as $preset_id => $preset) {
66      if (!$preset->areContextsSatisfied($contexts)) {
67        unset($presets[$preset_id]);
68      }
69    }
70
71    if (empty($presets)) {
 
90      $content = $this->buildPresets($builder_id, $presets);
91    }
92
93    return [
94      '#type' => 'component',
 
94      '#type' => 'component',
95      '#component' => 'display_builder:library_panel',
96      '#slots' => [
97        'content' => $content,
98      ],
99      '#cache' => [
100        'tags' => $this->presetConfigStorage->getEntityType()->getListCacheTags(),
101      ],
102    ];
103  }
PresetLibraryPanel->buildPresetItem
183  private function buildPresetItem(string $builder_id, PatternPresetInterface $preset, bool $with_preview): array {
184    $keywords = \sprintf('%s %s', $preset->get('label'), $preset->get('description') ?? '');
185    $vals = ['preset_id' => $preset->id()];
186
187    if ($with_preview) {
 
187    if ($with_preview) {
188      $url = Url::fromRoute('display_builder.api_preset_preview', $vals);
 
196    $build['#attributes']['data-instance-id'][] = $preset->id();
197
198    return $build;
199  }
183  private function buildPresetItem(string $builder_id, PatternPresetInterface $preset, bool $with_preview): array {
184    $keywords = \sprintf('%s %s', $preset->get('label'), $preset->get('description') ?? '');
185    $vals = ['preset_id' => $preset->id()];
186
187    if ($with_preview) {
 
193      $build = $this->buildPlaceholderButton($preset->get('label'), $vals, $keywords);
194    }
195
196    $build['#attributes']['data-instance-id'][] = $preset->id();
 
196    $build['#attributes']['data-instance-id'][] = $preset->id();
197
198    return $build;
199  }
PresetLibraryPanel->create
37  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
38    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
39    $instance->presetConfigStorage = $container->get('entity_type.manager')->getStorage('pattern_preset');
40
41    return $instance;
42  }
PresetLibraryPanel->getPresetGroup
210  private function getPresetGroup(PatternPresetInterface $preset): string {
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
 
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
 
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
212  }
210  private function getPresetGroup(PatternPresetInterface $preset): string {
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
 
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
 
211    return $preset->getGroup() ? (string) $preset->getGroup() : (string) $this->t('Others');
212  }
PresetLibraryPanel->label
48    return 'Presets';
49  }
PresetLibraryPanel->onPresetSave
108  public function onPresetSave(string $builder_id): array {
109    return $this->reloadWithGlobalData($builder_id);
110  }