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}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.