Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
92.59% covered (success)
92.59%
25 / 27
91.67% covered (success)
91.67%
22 / 24
38.10% covered (danger)
38.10%
8 / 21
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Profile
92.59% covered (success)
92.59%
25 / 27
91.67% covered (success)
91.67%
22 / 24
38.10% covered (danger)
38.10%
8 / 21
71.43% covered (warning)
71.43%
5 / 7
68.38
0.00% covered (danger)
0.00%
0 / 1
 getIslandConfiguration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIslandConfigurations
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setIslandConfiguration
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
50.00% covered (danger)
50.00%
1 / 2
100.00% covered (success)
100.00%
1 / 1
2.50
 getEnabledIslands
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
8 / 8
33.33% covered (danger)
33.33%
2 / 6
100.00% covered (success)
100.00%
1 / 1
8.74
 getPermissionName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRoles
80.00% covered (warning)
80.00%
4 / 5
66.67% covered (warning)
66.67%
2 / 3
50.00% covered (danger)
50.00%
1 / 2
0.00% covered (danger)
0.00%
0 / 1
2.50
 toUrl
88.89% covered (warning)
88.89%
8 / 9
85.71% covered (warning)
85.71%
6 / 7
12.50% covered (danger)
12.50%
1 / 8
0.00% covered (danger)
0.00%
0 / 1
14.72
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Entity;
6
7use Drupal\Core\Config\Entity\ConfigEntityBase;
8use Drupal\Core\Entity\Attribute\ConfigEntityType;
9use Drupal\Core\Entity\EntityDeleteForm;
10use Drupal\Core\StringTranslation\TranslatableMarkup;
11use Drupal\Core\Url;
12use Drupal\display_builder\Form\ProfileForm;
13use Drupal\display_builder\Form\ProfileIslandPluginForm;
14use Drupal\display_builder\ProfileAccessControlHandler;
15use Drupal\display_builder\ProfileViewBuilder;
16use Drupal\display_builder_ui\ProfileListBuilder;
17use Drupal\user\Entity\Role;
18use Drupal\user\RoleInterface;
19
20/**
21 * Defines the display builder entity type.
22 */
23#[ConfigEntityType(
24  id: 'display_builder_profile',
25  label: new TranslatableMarkup('Display builder profile'),
26  label_collection: new TranslatableMarkup('Display builder profiles'),
27  label_singular: new TranslatableMarkup('display builder profile'),
28  label_plural: new TranslatableMarkup('display builders profiles'),
29  entity_keys: [
30    'id' => 'id',
31    'label' => 'label',
32    'description' => 'description',
33    'weight' => 'weight',
34  ],
35  handlers: [
36    'access' => ProfileAccessControlHandler::class,
37    'route_provider' => [
38      'html' => 'Drupal\display_builder\Routing\ProfileRouteProvider',
39    ],
40    'view_builder' => ProfileViewBuilder::class,
41    'list_builder' => ProfileListBuilder::class,
42    'form' => [
43      'add' => ProfileForm::class,
44      'edit' => ProfileForm::class,
45      'delete' => EntityDeleteForm::class,
46      'edit-plugin' => ProfileIslandPluginForm::class,
47    ],
48  ],
49  links: [
50    'add-form' => '/admin/structure/display-builder/add',
51    'edit-form' => '/admin/structure/display-builder/{display_builder_profile}',
52    'edit-plugin-form' => '/admin/structure/display-builder/{display_builder_profile}/edit/{island_id}',
53    'delete-form' => '/admin/structure/display-builder/{display_builder_profile}/delete',
54    'collection' => '/admin/structure/display-builder',
55  ],
56  admin_permission: 'administer display builder profile',
57  constraints: [
58    'ImmutableProperties' => [
59      'id',
60    ],
61  ],
62  // Example: display_builder.profile.default.yml.
63  config_prefix: 'profile',
64  config_export: [
65    'id',
66    'label',
67    'description',
68    'islands',
69    'weight',
70  ],
71)]
72final class Profile extends ConfigEntityBase implements ProfileInterface {
73
74  /**
75   * The display builder config ID.
76   */
77  protected string $id;
78
79  /**
80   * The display builder label.
81   */
82  protected string $label;
83
84  /**
85   * The display builder description.
86   */
87  protected string $description;
88
89  /**
90   * The islands configuration for storage.
91   */
92  protected ?array $islands = [];
93
94  /**
95   * Weight to order the entity in lists.
96   *
97   * @var int
98   */
99  protected $weight = 0;
100
101  /**
102   * {@inheritdoc}
103   */
104  public function getIslandConfiguration(string $island_id): array {
105    return $this->islands[$island_id] ?? [];
106  }
107
108  /**
109   * {@inheritdoc}
110   */
111  public function getIslandConfigurations(): array {
112    return $this->islands ?? [];
113  }
114
115  /**
116   * {@inheritdoc}
117   */
118  public function setIslandConfiguration(string $island_id, array $configuration = []): void {
119    // When $configuration is updated from ProfileIslandPluginForm,
120    // 'weight', 'status' and 'region' properties are missing but they must not
121    // be reset.
122    $configuration['weight'] ??= $this->islands[$island_id]['weight'] ?? 0;
123    $configuration['status'] ??= $this->islands[$island_id]['status'] ?? FALSE;
124
125    // Only View islands have regions.
126    if (isset($this->islands[$island_id]['region'])) {
127      $configuration['region'] ??= $this->islands[$island_id]['region'];
128    }
129
130    $this->islands[$island_id] = $configuration;
131  }
132
133  /**
134   * {@inheritdoc}
135   */
136  public function getEnabledIslands(): array {
137    $island_enabled = [];
138
139    foreach ($this->islands as $island_id => $configuration) {
140      if (isset($configuration['status']) && $configuration['status']) {
141        $island_enabled[$island_id] = $configuration['weight'] ?? 0;
142      }
143    }
144
145    return $island_enabled;
146  }
147
148  /**
149   * {@inheritdoc}
150   */
151  public function getPermissionName(): string {
152    return 'use display builder ' . $this->id();
153  }
154
155  /**
156   * {@inheritdoc}
157   */
158  public function getRoles(): array {
159    // Do not list any roles if the permission does not exist.
160    $permission = $this->getPermissionName();
161
162    if (empty($permission)) {
163      return [];
164    }
165
166    $roles = \array_filter(Role::loadMultiple(), static fn (RoleInterface $role) => $role->hasPermission($permission));
167
168    return \array_map(static fn (RoleInterface $role) => $role->label(), $roles);
169  }
170
171  /**
172   * {@inheritdoc}
173   */
174  public function toUrl($rel = NULL, array $options = []): Url {
175    if ($rel === 'edit-plugin-form' && $this->id() && isset($options['island_id'])) {
176      $island_id = $options['island_id'];
177      unset($options['island_id']);
178
179      return Url::fromRoute(
180        'entity.display_builder_profile.edit_plugin_form',
181        ['display_builder_profile' => $this->id(), 'island_id' => $island_id],
182        $options
183      );
184    }
185
186    return parent::toUrl($rel, $options);
187  }
188
189}