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