Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentEntitySource
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 5
240
0.00% covered (danger)
0.00%
0 / 1
 create
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 defaultSettings
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getPropValue
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 settingsForm
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
42
 getEntity
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder_entity_view\Plugin\UiPatterns\Source;
6
7use Drupal\Core\Config\Entity\ConfigEntityType;
8use Drupal\Core\Entity\ContentEntityInterface;
9use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
10use Drupal\Core\Entity\EntityTypeManagerInterface;
11use Drupal\Core\Form\FormStateInterface;
12use Drupal\Core\StringTranslation\TranslatableMarkup;
13use Drupal\ui_patterns\Attribute\Source;
14use Drupal\ui_patterns\SourcePluginBase;
15use Symfony\Component\DependencyInjection\ContainerInterface;
16
17/**
18 * Plugin implementation of the source.
19 */
20#[Source(
21  id: 'content_entity',
22  label: new TranslatableMarkup('Content entity'),
23  description: new TranslatableMarkup('A content entity with a specific display.'),
24  prop_types: ['slot'],
25  context_requirements: ['content'],
26)]
27class ContentEntitySource extends SourcePluginBase {
28
29  /**
30   * The entity type manager.
31   */
32  protected ?EntityTypeManagerInterface $entityTypeManager;
33
34  /**
35   * The entity display manager.
36   */
37  protected ?EntityDisplayRepositoryInterface $entityDisplay;
38
39  /**
40   * {@inheritdoc}
41   */
42  public static function create(
43    ContainerInterface $container,
44    array $configuration,
45    $plugin_id,
46    $plugin_definition,
47  ): static {
48    $plugin = parent::create(
49      $container,
50      $configuration,
51      $plugin_id,
52      $plugin_definition
53    );
54    $plugin->entityTypeManager = $container->get('entity_type.manager');
55    $plugin->entityDisplay = $container->get('entity_display.repository');
56
57    return $plugin;
58  }
59
60  /**
61   * {@inheritdoc}
62   */
63  public function defaultSettings(): array {
64    return [
65      'entity' => NULL,
66      'entity_type' => NULL,
67      'entity_display' => NULL,
68    ];
69  }
70
71  /**
72   * {@inheritdoc}
73   */
74  public function getPropValue(): mixed {
75    $entity = $this->getEntity();
76
77    if ($entity === NULL) {
78      return [];
79    }
80
81    $entity_type = $this->getSetting('entity_type');
82
83    if ($entity_type === NULL) {
84      return [];
85    }
86
87    $view_builder = $this->entityTypeManager->getViewBuilder($entity_type);
88
89    return $view_builder->view($entity, $this->getSetting('entity_display') ?? 'default');
90  }
91
92  /**
93   * {@inheritdoc}
94   */
95  public function settingsForm(array $form, FormStateInterface $form_state): array {
96    $form = parent::settingsForm($form, $form_state);
97
98    $entity_type = $this->getSetting('entity_type');
99
100    if ($entity_type === NULL || empty($entity_type)) {
101      $options = [];
102
103      foreach ($this->entityTypeManager->getDefinitions() as $key => $value) {
104        if (!$value instanceof ConfigEntityType) {
105          $options[$key] = $value->getLabel();
106        }
107      }
108
109      $form['entity_type'] = [
110        '#type' => 'select',
111        '#title' => $this->t('Pick a content entity type'),
112        '#options' => $options,
113      ];
114
115      return $form;
116    }
117
118    // Once entity type selected, we do not allow change.
119    $form['entity_type'] = [
120      '#type' => 'hidden',
121      '#value' => $entity_type,
122    ];
123
124    $entity = $this->getEntity();
125    $form['entity'] = [
126      '#type' => 'entity_autocomplete',
127      '#title' => $this->t('Search a content of type @type', ['@type' => $entity_type]),
128      '#target_type' => $entity_type,
129      '#default_value' => $entity,
130      '#selection_handler' => 'default',
131      '#placeholder' => $this->t('Search for a content'),
132    ];
133
134    if (!$entity) {
135      return $form;
136    }
137
138    $display_options = $this->entityDisplay->getViewModeOptions($entity_type);
139    $form['entity_display'] = [
140      '#type' => 'select',
141      '#title' => $this->t('Pick a display mode'),
142      '#options' => $display_options,
143      '#default_value' => $this->getSetting('entity_display'),
144    ];
145
146    return $form;
147  }
148
149  /**
150   * Returns the referenced content entity object.
151   */
152  private function getEntity(): ?ContentEntityInterface {
153    $entity_id = $this->getSetting('entity');
154    $entity_type = $this->getSetting('entity_type');
155
156    if (!$entity_id || !$entity_type) {
157      return NULL;
158    }
159
160    if (!\is_numeric($entity_id)) {
161      return NULL;
162    }
163
164    $storage = $this->entityTypeManager->getStorage($entity_type);
165
166    /** @var \Drupal\Core\Entity\ContentEntityInterface|null $entity */
167    $entity = $storage->load((int) $entity_id);
168
169    return $entity;
170  }
171
172}