Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
38.46% covered (danger)
38.46%
10 / 26
31.25% covered (danger)
31.25%
5 / 16
23.08% covered (danger)
23.08%
3 / 13
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
LayoutBuilderEntityViewDisplay
38.46% covered (danger)
38.46%
10 / 26
31.25% covered (danger)
31.25%
5 / 16
23.08% covered (danger)
23.08%
3 / 13
40.00% covered (danger)
40.00%
2 / 5
66.08
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
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
 preSave
50.00% covered (danger)
50.00%
2 / 4
50.00% covered (danger)
50.00%
3 / 6
16.67% covered (danger)
16.67%
1 / 6
0.00% covered (danger)
0.00%
0 / 1
13.26
 getDisplayBuilderOverrideField
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
 initialImport
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 importFromLayoutBuilder
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 3
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_entity_view\Entity;
6
7use Drupal\Core\Entity\EntityStorageInterface;
8use Drupal\Core\Entity\EntityTypeManagerInterface;
9use Drupal\display_builder\DisplayBuildableInterface;
10use Drupal\display_builder\DisplayBuildablePluginManager;
11use Drupal\display_builder\InstanceInterface;
12use Drupal\display_builder_entity_view\BuilderDataConverter;
13use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay as CoreLayoutBuilderEntityViewDisplay;
14use Drupal\ui_patterns\Element\ComponentElementBuilder;
15use Drupal\ui_patterns\SourcePluginManager;
16
17/**
18 * Provides an entity view display entity that has a display builder.
19 *
20 * When Layout Builder is activated, extends Layout Builder.
21 *
22 * @see \Drupal\display_builder_entity_view\Hook\DisplayBuilderEntityViewHook::entityTypeAlter()
23 * @see \Drupal\display_builder_entity_view\Entity\EntityViewDisplay
24 */
25class LayoutBuilderEntityViewDisplay extends CoreLayoutBuilderEntityViewDisplay implements DisplayBuilderEntityDisplayInterface, DisplayBuilderOverridableInterface {
26
27  use EntityViewDisplayTrait;
28
29  /**
30   * The source plugin manager.
31   */
32  protected SourcePluginManager $sourcePluginManager;
33
34  /**
35   * The entity type manager.
36   */
37  protected EntityTypeManagerInterface $entityTypeManager;
38
39  /**
40   * The component element builder service.
41   */
42  protected ComponentElementBuilder $componentElementBuilder;
43
44  /**
45   * The data converter from Manage Display and Layout Builder.
46   */
47  protected BuilderDataConverter $dataConverter;
48
49  /**
50   * The display buildable plugin manager.
51   */
52  protected DisplayBuildablePluginManager $displayBuildableManager;
53
54  /**
55   * The loaded display builder instance.
56   */
57  protected ?InstanceInterface $instance;
58
59  /**
60   * Constructs the LayoutBuilderEntityViewDisplay.
61   *
62   * @param array $values
63   *   The values to initialize the entity with.
64   * @param string $entity_type
65   *   The entity type ID.
66   */
67  public function __construct(array $values, $entity_type) {
68    $this->entityFieldManager = \Drupal::service('entity_field.manager');
69    parent::__construct($values, $entity_type);
70    $this->sourcePluginManager = \Drupal::service('plugin.manager.ui_patterns_source');
71    $this->entityTypeManager = \Drupal::service('entity_type.manager');
72    $this->componentElementBuilder = \Drupal::service('ui_patterns.component_element_builder');
73    $this->dataConverter = \Drupal::service('display_builder_entity_view.builder_data_converter');
74    $this->displayBuildableManager = \Drupal::service('plugin.manager.display_buildable');
75  }
76
77  /**
78   * {@inheritdoc}
79   */
80  public function preSave(EntityStorageInterface $storage): void {
81    // If the update is made from Layout Builder, convert the data and copy
82    // to Display Builder's third party settings storage.
83    if (isset($this->form_id) && $this->form_id === 'entity_view_display_layout_builder_form') {
84      if ($this->displayBuildable()->getProfile()) {
85        $this->importFromLayoutBuilder();
86      }
87    }
88    parent::preSave($storage);
89  }
90
91  /**
92   * Returns the field name used to store overridden displays.
93   *
94   * @return string|null
95   *   The field name used to store overridden displays, or NULL if not set.
96   *
97   * @see Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface
98   */
99  public function getDisplayBuilderOverrideField(): ?string {
100    return $this->getThirdPartySetting('display_builder', DisplayBuildableInterface::OVERRIDE_FIELD_PROPERTY);
101  }
102
103  /**
104   * {@inheritdoc}
105   *
106   * @see \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface
107   */
108  public function initialImport(): array {
109    if ($this->getThirdPartySetting('layout_builder', 'enabled')) {
110      $sections = $this->getThirdPartySetting('layout_builder', 'sections', []);
111
112      if (!\is_array($sections)) {
113        $sections = [];
114      }
115
116      return $this->dataConverter->convertFromLayoutBuilder($sections);
117    }
118
119    // If Layout Builder is not used, import from Manage Display data.
120    return $this->dataConverter->convertFromManageDisplay($this->getTargetEntityTypeId(), $this->getTargetBundle(), $this->content);
121  }
122
123  /**
124   * Import and convert data from layout builder.
125   *
126   * This is not used for the first import but for the following saves.
127   *
128   * @see LayoutBuilderEntityViewDisplay::preSave()
129   */
130  protected function importFromLayoutBuilder(): void {
131    if (!$this->displayBuildable()->getInstanceId()) {
132      return;
133    }
134    $sections = $this->getThirdPartySetting('layout_builder', 'sections');
135    $sources = $this->dataConverter->convertFromLayoutBuilder($sections);
136
137    /** @var \Drupal\display_builder\InstanceStorage $storage */
138    $storage = $this->entityTypeManager->getStorage('display_builder_instance');
139    /** @var \Drupal\display_builder\InstanceInterface $instance */
140    $instance = $storage->load($this->displayBuildable()->getInstanceId());
141    $instance->setNewPresent($sources, 'Import from Layout Builder');
142    $instance->save();
143  }
144
145}