Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
56.67% covered (warning)
56.67%
51 / 90
66.67% covered (warning)
66.67%
34 / 51
62.22% covered (warning)
62.22%
28 / 45
65.71% covered (warning)
65.71%
23 / 35
CRAP
0.00% covered (danger)
0.00%
0 / 1
IslandPluginBase
56.67% covered (warning)
56.67%
51 / 90
66.67% covered (warning)
66.67%
34 / 51
62.22% covered (warning)
62.22%
28 / 45
65.71% covered (warning)
65.71%
23 / 35
137.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 build
57.89% covered (warning)
57.89%
11 / 19
87.50% covered (warning)
87.50%
7 / 8
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
4.59
 afterBuild
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isApplicable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
5 / 5
50.00% covered (danger)
50.00%
2 / 4
100.00% covered (success)
100.00%
1 / 1
4.12
 label
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setBuilderId
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
 setNodeId
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
 keyboardShortcuts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTypeId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHtmlId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIcon
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onAttachToRoot
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onAttachToSlot
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onMove
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onActive
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onUpdate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onDelete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onHistoryChange
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onRestore
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
 onRevert
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
 onPublish
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onPresetSave
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfiguration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setConfiguration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 defaultConfiguration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 configurationSummary
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 alterRenderable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDeferrable
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
 reload
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
 buildContent
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
 reloadWithGlobalData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 reloadWithLocalData
0.00% covered (danger)
0.00%
0 / 5
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
 reloadWithNodeData
0.00% covered (danger)
0.00%
0 / 5
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
 getArgs
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
2
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Island;
6
7use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
8use Drupal\Component\Plugin\PluginBase;
9use Drupal\Core\Entity\EntityTypeManagerInterface;
10use Drupal\Core\Form\FormBuilderInterface;
11use Drupal\Core\Form\FormState;
12use Drupal\Core\Form\FormStateInterface;
13use Drupal\Core\StringTranslation\StringTranslationTrait;
14use Drupal\Core\Theme\ComponentPluginManager;
15use Drupal\display_builder\DisplayBuilderHtmx;
16use Drupal\display_builder\HtmxEvents;
17use Drupal\display_builder\InstanceInterface;
18use Drupal\display_builder\RenderableBuilderTrait;
19use Drupal\ui_patterns\SourcePluginManager;
20use Psr\Log\LoggerInterface;
21use Symfony\Component\DependencyInjection\ContainerInterface;
22
23/**
24 * Base class for island plugins.
25 */
26abstract class IslandPluginBase extends PluginBase implements IslandInterface {
27
28  use RenderableBuilderTrait;
29  use StringTranslationTrait;
30
31  /**
32   * The island data.
33   */
34  protected array $data;
35
36  /**
37   * The builder id.
38   */
39  protected string $builderId;
40
41  /**
42   * The builder instance entity.
43   */
44  protected ?InstanceInterface $builder = NULL;
45
46  /**
47   * The tree node id (when the island is executed in the context of a node).
48   */
49  protected ?string $nodeId = NULL;
50
51  /**
52   * {@inheritdoc}
53   */
54  public function __construct(
55    array $configuration,
56    $plugin_id,
57    $plugin_definition,
58    protected ComponentPluginManager $sdcManager,
59    protected HtmxEvents $htmxEvents,
60    protected EntityTypeManagerInterface $entityTypeManager,
61    protected SourcePluginManager $sourceManager,
62    protected LoggerInterface $logger,
63    protected FormBuilderInterface $formBuilder,
64  ) {
65    parent::__construct($configuration, $plugin_id, $plugin_definition);
66    $this->data = $configuration;
67    $this->setConfiguration($configuration);
68  }
69
70  /**
71   * {@inheritdoc}
72   */
73  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
74    return new static(
75      $configuration,
76      $plugin_id,
77      $plugin_definition,
78      $container->get('plugin.manager.sdc'),
79      $container->get('display_builder.htmx_events'),
80      $container->get('entity_type.manager'),
81      $container->get('plugin.manager.ui_patterns_source'),
82      $container->get('logger.factory')->get('display_builder'),
83      $container->get('form_builder'),
84    );
85  }
86
87  /**
88   * {@inheritdoc}
89   */
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
99      $this->data = $data['third_party_settings'][$this->getPluginId()];
100    }
101    // Otherwise, fallback on global data.
102    else {
103      $this->data = $data;
104    }
105
106    if (!$this->isApplicable()) {
107      return [];
108    }
109
110    if (!$this instanceof IslandWithFormInterface) {
111      return $this->buildContent($builder, $data, $options);
112    }
113
114    $contexts = $this->configuration['contexts'] ?? [];
115
116    $form_state = new FormState();
117
118    // We have to force form to not rebuild, otherwise, we are losing data of an
119    // island plugin when another is submitted.
120    // Example: submitting Styles Panel make lose default form values for
121    // Instance Form Panel.
122    $form_state->setRebuild(FALSE);
123    $form_state->setExecuted();
124
125    $form_state->addBuildInfo('args', [$this->getArgs(), $contexts, $options]);
126    $form_state->setTemporaryValue('gathered_contexts', $contexts);
127
128    $build = $this->formBuilder->buildForm($this::getFormClass(), $form_state);
129
130    return $this->afterBuild($build, $form_state);
131  }
132
133  /**
134   * {@inheritdoc}
135   */
136  public function afterBuild(array $element, FormStateInterface $form_state): array {
137    if (!$this->isApplicable()) {
138      return [];
139    }
140
141    $definition = $this->getPluginDefinition();
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
143
144    return $this->htmxEvents->onThirdPartyFormChange($element, $this->builderId, $this->nodeId, $island_id);
145  }
146
147  /**
148   * {@inheritdoc}
149   */
150  public function isApplicable(): bool {
151    $definition = $this->getPluginDefinition();
152
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
154  }
155
156  /**
157   * {@inheritdoc}
158   */
159  public function label(): string {
160    // Cast the label to a string since it is a TranslatableMarkup object.
161    return (string) $this->pluginDefinition['label'];
162  }
163
164  /**
165   * {@inheritdoc}
166   */
167  public function setBuilderId(string $builder_id): void {
168    $this->builderId = $builder_id;
169  }
170
171  /**
172   * {@inheritdoc}
173   */
174  public function setNodeId(?string $node_id): void {
175    $this->nodeId = $node_id;
176  }
177
178  /**
179   * {@inheritdoc}
180   */
181  public static function keyboardShortcuts(): array {
182    return [];
183  }
184
185  /**
186   * {@inheritdoc}
187   */
188  public function getTypeId(): string {
189    return $this->pluginDefinition['type']->value;
190  }
191
192  /**
193   * {@inheritdoc}
194   */
195  public function getHtmlId(string $builder_id): string {
196    return \implode('-', ['island', $builder_id, $this->pluginDefinition['id']]);
197  }
198
199  /**
200   * {@inheritdoc}
201   */
202  public function getIcon(): ?string {
203    return $this->pluginDefinition['icon'] ?? NULL;
204  }
205
206  /**
207   * {@inheritdoc}
208   */
209  public function onAttachToRoot(InstanceInterface $instance, string $node_id): array {
210    return [];
211  }
212
213  /**
214   * {@inheritdoc}
215   */
216  public function onAttachToSlot(InstanceInterface $instance, string $node_id, string $parent_id): array {
217    return [];
218  }
219
220  /**
221   * {@inheritdoc}
222   */
223  public function onMove(InstanceInterface $instance, string $node_id): array {
224    return [];
225  }
226
227  /**
228   * {@inheritdoc}
229   */
230  public function onActive(InstanceInterface $instance, array $data): array {
231    return [];
232  }
233
234  /**
235   * {@inheritdoc}
236   */
237  public function onUpdate(InstanceInterface $instance, string $node_id): array {
238    return [];
239  }
240
241  /**
242   * {@inheritdoc}
243   */
244  public function onDelete(InstanceInterface $instance, ?string $parent_id): array {
245    return [];
246  }
247
248  /**
249   * {@inheritdoc}
250   */
251  public function onHistoryChange(InstanceInterface $instance): array {
252    return [];
253  }
254
255  /**
256   * {@inheritdoc}
257   */
258  public function onRestore(InstanceInterface $instance): array {
259    return [];
260  }
261
262  /**
263   * {@inheritdoc}
264   */
265  public function onRevert(InstanceInterface $instance): array {
266    return [];
267  }
268
269  /**
270   * {@inheritdoc}
271   */
272  public function onPublish(InstanceInterface $instance): array {
273    return [];
274  }
275
276  /**
277   * {@inheritdoc}
278   */
279  public function onPresetSave(InstanceInterface $instance): array {
280    return [];
281  }
282
283  /**
284   * {@inheritdoc}
285   */
286  public function getConfiguration(): array {
287    return \array_merge($this->defaultConfiguration(), $this->configuration);
288  }
289
290  /**
291   * {@inheritdoc}
292   */
293  public function setConfiguration(array $configuration): void {
294    $this->configuration = \array_merge($this->defaultConfiguration(), $configuration);
295  }
296
297  /**
298   * {@inheritdoc}
299   */
300  public function defaultConfiguration(): array {
301    return [];
302  }
303
304  /**
305   * {@inheritdoc}
306   */
307  public function configurationSummary(): array {
308    return [];
309  }
310
311  /**
312   * {@inheritdoc}
313   */
314  public function alterRenderable(InstanceInterface $instance, array $build): array {
315    return $build;
316  }
317
318  /**
319   * {@inheritdoc}
320   */
321  public function isDeferrable(): bool {
322    // View panels share a tab strip or a sidebar drawer and Floating controls
323    // ride along with the panel they attach to, so all of them spend most of
324    // their time off screen. Everything else is permanently visible.
325    return \in_array($this->getTypeId(), [
326      IslandType::View->value,
327      IslandType::Floating->value,
328    ], TRUE);
329  }
330
331  /**
332   * {@inheritdoc}
333   */
334  public function reload(InstanceInterface $instance): array {
335    return $this->reloadWithGlobalData($instance);
336  }
337
338  /**
339   * Build content for non-form islands.
340   *
341   * Override this method instead of build() when the plugin does not implement
342   * IslandWithFormInterface but still wants to reuse the preamble logic from
343   * build() (setting builder context, checking isApplicable()).
344   *
345   * @param \Drupal\display_builder\InstanceInterface $builder
346   *   Display builder instance.
347   * @param array $data
348   *   The data array.
349   * @param array $options
350   *   Additional options.
351   *
352   * @return array
353   *   A renderable array.
354   */
355  protected function buildContent(InstanceInterface $builder, array $data, array $options): array {
356    return [];
357  }
358
359  /**
360   * Helper method to reload island with global data.
361   *
362   * @param \Drupal\display_builder\InstanceInterface $instance
363   *   The display builder instance.
364   *
365   * @return array
366   *   Returns a render array with out-of-band commands.
367   */
368  protected function reloadWithGlobalData(InstanceInterface $instance): array {
369    return DisplayBuilderHtmx::outOfBand(
370      $this->build($instance, $instance->getCurrentState()),
371      '#' . $this->getHtmlId((string) $instance->id()),
372      'innerHTML'
373    );
374  }
375
376  /**
377   * Helper method to reload island with provided local data.
378   *
379   * @param \Drupal\display_builder\InstanceInterface $instance
380   *   The display builder instance.
381   * @param array $data
382   *   The local data array to use for building the island.
383   *
384   * @return array
385   *   Returns a render array with out-of-band commands.
386   */
387  protected function reloadWithLocalData(InstanceInterface $instance, array $data): array {
388    return DisplayBuilderHtmx::outOfBand(
389      $this->build($instance, $data),
390      '#' . $this->getHtmlId((string) $instance->id()),
391      'innerHTML'
392    );
393  }
394
395  /**
396   * Helper method to reload island with node-specific data.
397   *
398   * @param \Drupal\display_builder\InstanceInterface $instance
399   *   The display builder instance.
400   * @param string $node_id
401   *   The tree node ID.
402   *
403   * @return array
404   *   Returns a render array with out-of-band commands.
405   */
406  protected function reloadWithNodeData(InstanceInterface $instance, string $node_id): array {
407    return DisplayBuilderHtmx::outOfBand(
408      $this->build($instance, $instance->getNode($node_id)),
409      '#' . $this->getHtmlId($node_id),
410      'innerHTML'
411    );
412  }
413
414  /**
415   * Get args passed to plugin.
416   *
417   * @return array
418   *   Array of arguments.
419   */
420  private function getArgs(): array {
421    return [
422      'island_id' => $this->getPluginId(),
423      'builder_id' => $this->builderId,
424      'instance_id' => $this->nodeId,
425      'instance' => $this->data,
426    ];
427  }
428
429}

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.

IslandPluginBase->__construct
55    array $configuration,
56    $plugin_id,
57    $plugin_definition,
58    protected ComponentPluginManager $sdcManager,
59    protected HtmxEvents $htmxEvents,
60    protected EntityTypeManagerInterface $entityTypeManager,
61    protected SourcePluginManager $sourceManager,
62    protected LoggerInterface $logger,
63    protected FormBuilderInterface $formBuilder,
64  ) {
65    parent::__construct($configuration, $plugin_id, $plugin_definition);
66    $this->data = $configuration;
67    $this->setConfiguration($configuration);
68  }
IslandPluginBase->afterBuild
136  public function afterBuild(array $element, FormStateInterface $form_state): array {
137    if (!$this->isApplicable()) {
 
138      return [];
136  public function afterBuild(array $element, FormStateInterface $form_state): array {
137    if (!$this->isApplicable()) {
 
141    $definition = $this->getPluginDefinition();
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
 
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
 
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
143
144    return $this->htmxEvents->onThirdPartyFormChange($element, $this->builderId, $this->nodeId, $island_id);
145  }
136  public function afterBuild(array $element, FormStateInterface $form_state): array {
137    if (!$this->isApplicable()) {
 
141    $definition = $this->getPluginDefinition();
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
 
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
 
142    $island_id = $definition instanceof PluginDefinitionInterface ? $definition->id() : ($definition['id'] ?? '');
143
144    return $this->htmxEvents->onThirdPartyFormChange($element, $this->builderId, $this->nodeId, $island_id);
145  }
IslandPluginBase->alterRenderable
314  public function alterRenderable(InstanceInterface $instance, array $build): array {
315    return $build;
316  }
IslandPluginBase->build
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
99      $this->data = $data['third_party_settings'][$this->getPluginId()];
 
106    if (!$this->isApplicable()) {
 
107      return [];
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
99      $this->data = $data['third_party_settings'][$this->getPluginId()];
 
106    if (!$this->isApplicable()) {
 
110    if (!$this instanceof IslandWithFormInterface) {
 
111      return $this->buildContent($builder, $data, $options);
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
99      $this->data = $data['third_party_settings'][$this->getPluginId()];
 
106    if (!$this->isApplicable()) {
 
110    if (!$this instanceof IslandWithFormInterface) {
 
114    $contexts = $this->configuration['contexts'] ?? [];
115
116    $form_state = new FormState();
117
118    // We have to force form to not rebuild, otherwise, we are losing data of an
119    // island plugin when another is submitted.
120    // Example: submitting Styles Panel make lose default form values for
121    // Instance Form Panel.
122    $form_state->setRebuild(FALSE);
123    $form_state->setExecuted();
124
125    $form_state->addBuildInfo('args', [$this->getArgs(), $contexts, $options]);
126    $form_state->setTemporaryValue('gathered_contexts', $contexts);
127
128    $build = $this->formBuilder->buildForm($this::getFormClass(), $form_state);
129
130    return $this->afterBuild($build, $form_state);
131  }
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
103      $this->data = $data;
104    }
105
106    if (!$this->isApplicable()) {
 
106    if (!$this->isApplicable()) {
 
107      return [];
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
103      $this->data = $data;
104    }
105
106    if (!$this->isApplicable()) {
 
106    if (!$this->isApplicable()) {
 
110    if (!$this instanceof IslandWithFormInterface) {
 
111      return $this->buildContent($builder, $data, $options);
90  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
91    $this->builder = $builder;
92
93    $builder_id = (string) $builder->id();
94    $this->builderId = $builder_id;
95    $this->nodeId = $data['node_id'] ?? NULL;
96
97    // First, get specific data for the plugin.
98    if (isset($data['third_party_settings'][$this->getPluginId()])) {
 
103      $this->data = $data;
104    }
105
106    if (!$this->isApplicable()) {
 
106    if (!$this->isApplicable()) {
 
110    if (!$this instanceof IslandWithFormInterface) {
 
114    $contexts = $this->configuration['contexts'] ?? [];
115
116    $form_state = new FormState();
117
118    // We have to force form to not rebuild, otherwise, we are losing data of an
119    // island plugin when another is submitted.
120    // Example: submitting Styles Panel make lose default form values for
121    // Instance Form Panel.
122    $form_state->setRebuild(FALSE);
123    $form_state->setExecuted();
124
125    $form_state->addBuildInfo('args', [$this->getArgs(), $contexts, $options]);
126    $form_state->setTemporaryValue('gathered_contexts', $contexts);
127
128    $build = $this->formBuilder->buildForm($this::getFormClass(), $form_state);
129
130    return $this->afterBuild($build, $form_state);
131  }
IslandPluginBase->buildContent
355  protected function buildContent(InstanceInterface $builder, array $data, array $options): array {
356    return [];
357  }
IslandPluginBase->configurationSummary
308    return [];
309  }
IslandPluginBase->create
73  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
74    return new static(
75      $configuration,
76      $plugin_id,
77      $plugin_definition,
78      $container->get('plugin.manager.sdc'),
79      $container->get('display_builder.htmx_events'),
80      $container->get('entity_type.manager'),
81      $container->get('plugin.manager.ui_patterns_source'),
82      $container->get('logger.factory')->get('display_builder'),
83      $container->get('form_builder'),
84    );
85  }
IslandPluginBase->defaultConfiguration
301    return [];
302  }
IslandPluginBase->getArgs
422      'island_id' => $this->getPluginId(),
423      'builder_id' => $this->builderId,
424      'instance_id' => $this->nodeId,
425      'instance' => $this->data,
426    ];
427  }
IslandPluginBase->getConfiguration
287    return \array_merge($this->defaultConfiguration(), $this->configuration);
288  }
IslandPluginBase->getHtmlId
195  public function getHtmlId(string $builder_id): string {
196    return \implode('-', ['island', $builder_id, $this->pluginDefinition['id']]);
197  }
IslandPluginBase->getIcon
203    return $this->pluginDefinition['icon'] ?? NULL;
204  }
IslandPluginBase->getTypeId
189    return $this->pluginDefinition['type']->value;
190  }
IslandPluginBase->isApplicable
151    $definition = $this->getPluginDefinition();
152
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
154  }
151    $definition = $this->getPluginDefinition();
152
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
154  }
151    $definition = $this->getPluginDefinition();
152
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
154  }
151    $definition = $this->getPluginDefinition();
152
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
 
153    return $this->nodeId !== NULL && \is_array($definition) && !empty($this->data);
154  }
IslandPluginBase->isDeferrable
325    return \in_array($this->getTypeId(), [
326      IslandType::View->value,
327      IslandType::Floating->value,
328    ], TRUE);
329  }
IslandPluginBase->keyboardShortcuts
182    return [];
183  }
IslandPluginBase->label
161    return (string) $this->pluginDefinition['label'];
162  }
IslandPluginBase->onActive
230  public function onActive(InstanceInterface $instance, array $data): array {
231    return [];
232  }
IslandPluginBase->onAttachToRoot
209  public function onAttachToRoot(InstanceInterface $instance, string $node_id): array {
210    return [];
211  }
IslandPluginBase->onAttachToSlot
216  public function onAttachToSlot(InstanceInterface $instance, string $node_id, string $parent_id): array {
217    return [];
218  }
IslandPluginBase->onDelete
244  public function onDelete(InstanceInterface $instance, ?string $parent_id): array {
245    return [];
246  }
IslandPluginBase->onHistoryChange
251  public function onHistoryChange(InstanceInterface $instance): array {
252    return [];
253  }
IslandPluginBase->onMove
223  public function onMove(InstanceInterface $instance, string $node_id): array {
224    return [];
225  }
IslandPluginBase->onPresetSave
279  public function onPresetSave(InstanceInterface $instance): array {
280    return [];
281  }
IslandPluginBase->onPublish
272  public function onPublish(InstanceInterface $instance): array {
273    return [];
274  }
IslandPluginBase->onRestore
258  public function onRestore(InstanceInterface $instance): array {
259    return [];
260  }
IslandPluginBase->onRevert
265  public function onRevert(InstanceInterface $instance): array {
266    return [];
267  }
IslandPluginBase->onUpdate
237  public function onUpdate(InstanceInterface $instance, string $node_id): array {
238    return [];
239  }
IslandPluginBase->reload
334  public function reload(InstanceInterface $instance): array {
335    return $this->reloadWithGlobalData($instance);
336  }
IslandPluginBase->reloadWithGlobalData
368  protected function reloadWithGlobalData(InstanceInterface $instance): array {
369    return DisplayBuilderHtmx::outOfBand(
370      $this->build($instance, $instance->getCurrentState()),
371      '#' . $this->getHtmlId((string) $instance->id()),
372      'innerHTML'
373    );
374  }
IslandPluginBase->reloadWithLocalData
387  protected function reloadWithLocalData(InstanceInterface $instance, array $data): array {
388    return DisplayBuilderHtmx::outOfBand(
389      $this->build($instance, $data),
390      '#' . $this->getHtmlId((string) $instance->id()),
391      'innerHTML'
392    );
393  }
IslandPluginBase->reloadWithNodeData
406  protected function reloadWithNodeData(InstanceInterface $instance, string $node_id): array {
407    return DisplayBuilderHtmx::outOfBand(
408      $this->build($instance, $instance->getNode($node_id)),
409      '#' . $this->getHtmlId($node_id),
410      'innerHTML'
411    );
412  }
IslandPluginBase->setBuilderId
167  public function setBuilderId(string $builder_id): void {
168    $this->builderId = $builder_id;
169  }
IslandPluginBase->setConfiguration
293  public function setConfiguration(array $configuration): void {
294    $this->configuration = \array_merge($this->defaultConfiguration(), $configuration);
295  }
IslandPluginBase->setNodeId
174  public function setNodeId(?string $node_id): void {
175    $this->nodeId = $node_id;
176  }