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\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    $manager = \Drupal::service('plugin.manager.display_buildable');
101    /** @var \Drupal\display_builder\DisplayBuildableInterface $buildable */
102    $buildable = $manager->createInstance('page_layout', ['entity' => $page_layout]);
103    $operations = parent::getDefaultOperations($entity);
104    $operations[] = [
105      'title' => new TranslatableMarkup('Build display'),
106      'weight' => -10,
107      'url' => $buildable->getBuilderUrl(),
108    ];
109
110    if ($entity->hasLinkTemplate('duplicate-form')) {
111      $operations['duplicate'] = [
112        'title' => $this->t('Duplicate'),
113        'weight' => 15,
114        'url' => $entity->toUrl('duplicate-form'),
115      ];
116    }
117
118    return $operations;
119  }
120
121  /**
122   * {@inheritdoc}
123   */
124  public function buildForm(array $form, FormStateInterface $form_state) {
125    $form = parent::buildForm($form, $form_state);
126    $rows = Element::children($form['entities']);
127
128    if (\count($rows) < 2) {
129      unset($form['actions']['submit']);
130    }
131
132    return $form;
133  }
134
135  /**
136   * Count enabled and non empty Page Layout entities.
137   *
138   * @param array<int,mixed> $entities
139   *   The entities to process.
140   *
141   * @return int
142   *   The number of enabled and non empty Page Layout entities.
143   */
144  private function countActivePageLayouts(array $entities): int {
145    $count = 0;
146
147    foreach ($entities as $entity) {
148      if ($entity->status === TRUE && !empty($entity->getSources())) {
149        ++$count;
150      }
151    }
152
153    return $count;
154  }
155
156  /**
157   * Get summary of configured conditions, one item per plugin.
158   *
159   * @param PageLayoutInterface $entity
160   *   The page layout entity.
161   *
162   * @return array
163   *   The summary of configured conditions.
164   */
165  private function getConditionsSummary(PageLayoutInterface $entity): array {
166    $summary = [];
167    $conditions = $entity->getConditions();
168
169    foreach ($conditions->getIterator() as $condition) {
170      if ($condition->getPluginId() === 'request_path') {
171        $pages = \array_map('trim', \explode("\n", $condition->getConfiguration()['pages']));
172        $pages = \implode(', ', $pages);
173
174        if (!$condition->isNegated()) {
175          $summary[] = $this->t('On the following pages: @pages', ['@pages' => $pages]);
176        }
177        else {
178          $summary[] = $this->t('Not on the following pages: @pages', ['@pages' => $pages]);
179        }
180
181        continue;
182      }
183      $summary[] = $condition->summary();
184    }
185
186    return $summary;
187  }
188
189}