Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 75
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
PageLayoutListBuilder
0.00% covered (danger)
0.00%
0 / 75
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 9
462
0.00% covered (danger)
0.00%
0 / 1
 getFormId
0.00% covered (danger)
0.00%
0 / 1
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
2
 render
0.00% covered (danger)
0.00%
0 / 8
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
2
 load
0.00% covered (danger)
0.00%
0 / 8
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
6
 buildHeader
0.00% covered (danger)
0.00%
0 / 6
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
2
 buildRow
0.00% covered (danger)
0.00%
0 / 14
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
20
 getDefaultOperations
0.00% covered (danger)
0.00%
0 / 16
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
6
 buildForm
0.00% covered (danger)
0.00%
0 / 5
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
6
 countActivePageLayouts
0.00% covered (danger)
0.00%
0 / 5
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
20
 getConditionsSummary
0.00% covered (danger)
0.00%
0 / 12
n/a
0 / 0
n/a
0 / 0
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder_page_layout;
6
7use Drupal\Core\Cache\CacheableMetadata;
8use Drupal\Core\Config\Entity\DraggableListBuilder;
9use Drupal\Core\Entity\EntityInterface;
10use Drupal\Core\Form\FormStateInterface;
11use Drupal\Core\Render\Element;
12use Drupal\Core\StringTranslation\TranslatableMarkup;
13use Drupal\Core\Url;
14
15/**
16 * Provides a listing of page layouts.
17 */
18final class PageLayoutListBuilder extends DraggableListBuilder {
19
20  /**
21   * {@inheritdoc}
22   */
23  public function getFormId(): string {
24    return 'display_builder_page_layout';
25  }
26
27  /**
28   * {@inheritdoc}
29   */
30  public function render(): array {
31    $build = parent::render();
32    $build['notice'] = [
33      '#type' => 'html_tag',
34      '#tag' => 'p',
35      '#value' => $this->t('The first enabled, non-empty, applicable to a page according to its conditions, page layout will be loaded.'),
36      '#weight' => -100,
37    ];
38
39    return $build;
40  }
41
42  /**
43   * {@inheritdoc}
44   */
45  public function load(): array {
46    $entities = parent::load();
47
48    if ($this->countActivePageLayouts($entities) === 0) {
49      $params = [
50        '@url' => Url::fromRoute('block.admin_display')->toString(),
51      ];
52      $message = $this->t('Without any active Page Layout, pages are managed by <a href="@url">Block Layout</a>.', $params);
53      $this->messenger()->addStatus($message);
54    }
55
56    return $entities;
57  }
58
59  /**
60   * {@inheritdoc}
61   */
62  public function buildHeader(): array {
63    $header = [];
64    $header['label'] = $this->t('Page layout');
65    $header['profile_id'] = $this->t('Profile');
66    $header['conditions'] = $this->t('Conditions');
67    $header['status'] = $this->t('Status');
68
69    return $header + parent::buildHeader();
70  }
71
72  /**
73   * {@inheritdoc}
74   */
75  public function buildRow(EntityInterface $entity): array {
76    $row = [];
77    /** @var \Drupal\display_builder_page_layout\PageLayoutInterface $entity */
78    $row['label'] = $entity->label();
79    $row['profile_id']['#plain_text'] = $entity->getProfile()?->label() ?? '?';
80    $row['conditions'] = [
81      '#theme' => 'item_list',
82      '#list_type' => 'ul',
83      '#items' => $this->getConditionsSummary($entity),
84    ];
85    $status = $entity->status() ? $this->t('Enabled') : '❌ ' . $this->t('Disabled');
86    $status = $entity->status() && empty($entity->getSources()) ? '❌ ' . $this->t('Empty') : $status;
87    $row['status']['#plain_text'] = $status;
88
89    $row = $row + parent::buildRow($entity);
90    $row['#attributes']['data-id'] = $entity->id();
91
92    return $row;
93  }
94
95  /**
96   * {@inheritdoc}
97   */
98  public function getDefaultOperations(EntityInterface $entity, ?CacheableMetadata $cacheability = NULL): array {
99    /** @var \Drupal\display_builder_page_layout\PageLayoutInterface @page_layout */
100    $page_layout = $entity;
101    $manager = \Drupal::service('plugin.manager.display_buildable');
102    /** @var \Drupal\display_builder\DisplayBuildableInterface $buildable */
103    $buildable = $manager->createInstance('page_layout', ['entity' => $page_layout]);
104    $operations = parent::getDefaultOperations($entity);
105    $operations[] = [
106      'title' => new TranslatableMarkup('Build display'),
107      'weight' => -10,
108      'url' => $buildable->getBuilderUrl(),
109    ];
110
111    if ($entity->hasLinkTemplate('duplicate-form')) {
112      $operations['duplicate'] = [
113        'title' => $this->t('Duplicate'),
114        'weight' => 15,
115        'url' => $entity->toUrl('duplicate-form'),
116      ];
117    }
118
119    return $operations;
120  }
121
122  /**
123   * {@inheritdoc}
124   */
125  public function buildForm(array $form, FormStateInterface $form_state) {
126    $form = parent::buildForm($form, $form_state);
127    $rows = Element::children($form['entities']);
128
129    if (\count($rows) < 2) {
130      unset($form['actions']['submit']);
131    }
132
133    return $form;
134  }
135
136  /**
137   * Count enabled and non empty Page Layout entities.
138   *
139   * @param array<int,mixed> $entities
140   *   The entities to process.
141   *
142   * @return int
143   *   The number of enabled and non empty Page Layout entities.
144   */
145  private function countActivePageLayouts(array $entities): int {
146    $count = 0;
147
148    foreach ($entities as $entity) {
149      if ($entity->status === TRUE && !empty($entity->getSources())) {
150        ++$count;
151      }
152    }
153
154    return $count;
155  }
156
157  /**
158   * Get summary of configured conditions, one item per plugin.
159   *
160   * @param PageLayoutInterface $entity
161   *   The page layout entity.
162   *
163   * @return array
164   *   The summary of configured conditions.
165   */
166  private function getConditionsSummary(PageLayoutInterface $entity): array {
167    $summary = [];
168    $conditions = $entity->getConditions();
169
170    foreach ($conditions->getIterator() as $condition) {
171      if ($condition->getPluginId() === 'request_path') {
172        $pages = \array_map('trim', \explode("\n", $condition->getConfiguration()['pages']));
173        $pages = \implode(', ', $pages);
174
175        if (!$condition->isNegated()) {
176          $summary[] = $this->t('On the following pages: @pages', ['@pages' => $pages]);
177        }
178        else {
179          $summary[] = $this->t('Not on the following pages: @pages', ['@pages' => $pages]);
180        }
181
182        continue;
183      }
184      $summary[] = $condition->summary();
185    }
186
187    return $summary;
188  }
189
190}