Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
PageLayoutSource
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 12
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
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
 create
0.00% covered (danger)
0.00%
0 / 16
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
 getPropValue
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 calculateDependencies
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 getSlotDefinitions
0.00% covered (danger)
0.00%
0 / 6
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
 getSlotValues
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
 getSlotValue
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
 setSlotValue
0.00% covered (danger)
0.00%
0 / 2
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
 setSlotRenderable
0.00% covered (danger)
0.00%
0 / 2
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
 getSlotPath
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
 settingsFormPropsOnly
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
 systemRegionList
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
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder_page_layout\Plugin\UiPatterns\Source;
6
7use Drupal\Core\Config\ConfigFactoryInterface;
8use Drupal\Core\Extension\ModuleHandlerInterface;
9use Drupal\Core\Form\FormStateInterface;
10use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
11use Drupal\Core\Routing\RouteMatchInterface;
12use Drupal\Core\StringTranslation\TranslatableMarkup;
13use Drupal\Core\Utility\Token;
14use Drupal\display_builder\SourceWithSlotsInterface;
15use Drupal\ui_patterns\Attribute\Source;
16use Drupal\ui_patterns\Element\ComponentElementBuilder;
17use Drupal\ui_patterns\Entity\SampleEntityGeneratorInterface;
18use Drupal\ui_patterns\PropTypePluginManager;
19use Drupal\ui_patterns\SourcePluginBase;
20use Drupal\ui_patterns\SourcePluginManager;
21use Drupal\ui_patterns\UiPatternsNormalizerInterface;
22use Symfony\Component\DependencyInjection\ContainerInterface;
23
24/**
25 * Plugin implementation of the source.
26 */
27#[Source(
28  id: 'page_layout',
29  label: new TranslatableMarkup('Page layout (from active theme)'),
30  prop_types: ['slot'],
31  context_requirements: ['page'],
32  context_definitions: []
33)]
34class PageLayoutSource extends SourcePluginBase implements SourceWithSlotsInterface {
35
36  /**
37   * {@inheritdoc}
38   */
39  public function __construct(
40    array $configuration,
41    $plugin_id,
42    $plugin_definition,
43    PropTypePluginManager $propTypeManager,
44    ContextRepositoryInterface $contextRepository,
45    RouteMatchInterface $routeMatch,
46    SampleEntityGeneratorInterface $sampleEntityGenerator,
47    ModuleHandlerInterface $moduleHandler,
48    Token $token,
49    UiPatternsNormalizerInterface $normalizer,
50    private ComponentElementBuilder $componentElementBuilder,
51    private SourcePluginManager $sourceManager,
52    private ConfigFactoryInterface $configFactory,
53  ) {
54    parent::__construct($configuration, $plugin_id, $plugin_definition, $propTypeManager, $contextRepository, $routeMatch, $sampleEntityGenerator, $moduleHandler, $token, $normalizer);
55  }
56
57  /**
58   * {@inheritdoc}
59   */
60  public static function create(
61    ContainerInterface $container,
62    array $configuration,
63    $plugin_id,
64    $plugin_definition,
65  ): static {
66    $instance = new static(
67      $configuration,
68      $plugin_id,
69      $plugin_definition,
70      $container->get('plugin.manager.ui_patterns_prop_type'),
71      $container->get('context.repository'),
72      $container->get('current_route_match'),
73      $container->get('ui_patterns.sample_entity_generator'),
74      $container->get('module_handler'),
75      $container->get('token'),
76      $container->get('ui_patterns.normalizer'),
77      $container->get('ui_patterns.component_element_builder'),
78      $container->get('plugin.manager.ui_patterns_source'),
79      $container->get('config.factory'),
80    );
81
82    return $instance;
83  }
84
85  /**
86   * {@inheritdoc}
87   */
88  public function getPropValue(): mixed {
89    $page = [
90      '#type' => 'page',
91    ];
92
93    foreach ($this->getSlotValues() as $region_id => $region) {
94      $page[$region_id] = [];
95
96      foreach ($region as $source) {
97        $content = $this->componentElementBuilder->buildSource([], 'content', [], $source, $this->configuration['contexts'] ?? []) ?? [];
98        $content = $content['#slots']['content'][0] ?? [];
99        $page[$region_id][] = $content;
100      }
101    }
102
103    return $page;
104  }
105
106  /**
107   * {@inheritdoc}
108   */
109  public function calculateDependencies(): array {
110    $dependencies = parent::calculateDependencies();
111    $slot_definition = ['ui_patterns' => ['type_definition' => $this->sourceManager->getSlotPropType()]];
112
113    foreach ($this->getSlotValues() as $slot_id => $slot) {
114      // A slot is a list of source data.
115      $slot = \array_is_list($slot) ? $slot : [$slot];
116
117      foreach ($slot as $source) {
118        if ($source = $this->sourceManager->getSource($slot_id, $slot_definition, $source, [])) {
119          SourcePluginBase::mergeConfigDependencies(
120            $dependencies,
121            $source->calculateDependencies()
122          );
123        }
124      }
125    }
126
127    return $dependencies;
128  }
129
130  /**
131   * {@inheritdoc}
132   */
133  public function getSlotDefinitions(): array {
134    $slots = [];
135    $theme_name = $this->configFactory->get('system.theme')->get('default');
136    $regions = $this->systemRegionList($theme_name);
137
138    foreach ($regions as $region => $title) {
139      $slots[$region]['title'] = (string) $title;
140    }
141
142    return $slots;
143  }
144
145  /**
146   * {@inheritdoc}
147   */
148  public function getSlotValues(): array {
149    return $this->configuration['settings']['regions'] ?? [];
150  }
151
152  /**
153   * {@inheritdoc}
154   */
155  public function getSlotValue(string $slot_id): array {
156    return $this->configuration['settings']['regions'][$slot_id] ?? [];
157  }
158
159  /**
160   * {@inheritdoc}
161   */
162  public function setSlotValue(string $slot_id, array $slot): array {
163    $this->configuration['settings']['regions'][$slot_id] = $slot;
164
165    return $this->configuration['settings'];
166  }
167
168  /**
169   * {@inheritdoc}
170   */
171  public function setSlotRenderable(array $build, string $slot_id, array $slot): array {
172    $build[$slot_id] = $slot;
173
174    return $build;
175  }
176
177  /**
178   * {@inheritdoc}
179   */
180  public static function getSlotPath(string $slot_id): array {
181    return ['regions', $slot_id];
182  }
183
184  /**
185   * {@inheritdoc}
186   */
187  public function settingsFormPropsOnly(array $form, FormStateInterface $form_state): array {
188    return $form;
189  }
190
191  /**
192   * Wraps system_region_list().
193   *
194   * @param string $theme
195   *   The machine name of the theme.
196   *
197   * @return array
198   *   An array of region names and their human readable labels.
199   */
200  private function systemRegionList(string $theme): array {
201    return system_region_list($theme, REGIONS_VISIBLE);
202  }
203
204}