Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
46.97% |
62 / 132 |
|
66.67% |
46 / 69 |
|
35.38% |
23 / 65 |
|
50.00% |
11 / 22 |
CRAP | |
0.00% |
0 / 1 |
| PageLayout | |
68.89% |
62 / 90 |
|
66.67% |
46 / 69 |
|
35.38% |
23 / 65 |
|
50.00% |
11 / 22 |
616.85 | |
0.00% |
0 / 1 |
| getPrefix | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getPluginCollections | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getContextRequirement | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| checkInstanceId | |
0.00% |
0 / 6 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| getBuilderUrl | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getUrlFromInstanceId | |
0.00% |
0 / 4 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| getDisplayUrlFromInstanceId | |
0.00% |
0 / 4 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| getProfile | |
83.33% |
5 / 6 |
|
66.67% |
2 / 3 |
|
50.00% |
1 / 2 |
|
0.00% |
0 / 1 |
2.50 | |||
| getInstanceId | |
100.00% |
3 / 3 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| checkAccess | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| initInstanceIfMissing | |
100.00% |
5 / 5 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| getInitialSources | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
50.00% |
1 / 2 |
|
100.00% |
1 / 1 |
2.50 | |||
| getInitialContext | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getSources | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| saveSources | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getConditions | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| calculateDependencies | |
80.00% |
8 / 10 |
|
85.71% |
6 / 7 |
|
40.00% |
2 / 5 |
|
0.00% |
0 / 1 |
7.46 | |||
| delete | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
50.00% |
1 / 2 |
|
100.00% |
1 / 1 |
2.50 | |||
| postSave | |
77.78% |
7 / 9 |
|
80.00% |
4 / 5 |
|
50.00% |
2 / 4 |
|
0.00% |
0 / 1 |
4.12 | |||
| isImpactingPageVariantDetection | |
63.64% |
7 / 11 |
|
69.23% |
9 / 13 |
|
8.00% |
2 / 25 |
|
0.00% |
0 / 1 |
57.84 | |||
| getInstance | |
100.00% |
6 / 6 |
|
100.00% |
5 / 5 |
|
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
| sourceManager | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder_page_layout\Entity; |
| 6 | |
| 7 | use Drupal\Core\Access\AccessResult; |
| 8 | use Drupal\Core\Access\AccessResultInterface; |
| 9 | use Drupal\Core\Condition\ConditionPluginCollection; |
| 10 | use Drupal\Core\Config\Entity\ConfigEntityBase; |
| 11 | use Drupal\Core\Entity\Attribute\ConfigEntityType; |
| 12 | use Drupal\Core\Entity\EntityDeleteForm; |
| 13 | use Drupal\Core\Entity\EntityStorageInterface; |
| 14 | use Drupal\Core\Session\AccountInterface; |
| 15 | use Drupal\Core\StringTranslation\TranslatableMarkup; |
| 16 | use Drupal\Core\Url; |
| 17 | use Drupal\display_builder\ConfigFormBuilderInterface; |
| 18 | use Drupal\display_builder\DisplayBuilderHelpers; |
| 19 | use Drupal\display_builder\InstanceInterface; |
| 20 | use Drupal\display_builder\ProfileInterface; |
| 21 | use Drupal\display_builder_page_layout\AccessControlHandler; |
| 22 | use Drupal\display_builder_page_layout\Form\PageLayoutForm; |
| 23 | use Drupal\display_builder_page_layout\PageLayoutInterface; |
| 24 | use Drupal\display_builder_page_layout\PageLayoutListBuilder; |
| 25 | use Drupal\ui_patterns\Plugin\Context\RequirementsContext; |
| 26 | use Drupal\ui_patterns\SourcePluginManager; |
| 27 | |
| 28 | /** |
| 29 | * Defines the page layout entity type. |
| 30 | */ |
| 31 | #[ConfigEntityType( |
| 32 | id: 'page_layout', |
| 33 | label: new TranslatableMarkup('Page layout'), |
| 34 | label_collection: new TranslatableMarkup('Page layouts'), |
| 35 | label_singular: new TranslatableMarkup('page layout'), |
| 36 | label_plural: new TranslatableMarkup('page layouts'), |
| 37 | config_prefix: 'page_layout', |
| 38 | entity_keys: [ |
| 39 | 'id' => 'id', |
| 40 | 'label' => 'label', |
| 41 | 'weight' => 'weight', |
| 42 | 'uuid' => 'uuid', |
| 43 | ], |
| 44 | handlers: [ |
| 45 | 'access' => AccessControlHandler::class, |
| 46 | 'list_builder' => PageLayoutListBuilder::class, |
| 47 | 'form' => [ |
| 48 | 'add' => PageLayoutForm::class, |
| 49 | 'edit' => PageLayoutForm::class, |
| 50 | 'delete' => EntityDeleteForm::class, |
| 51 | ], |
| 52 | ], |
| 53 | links: [ |
| 54 | 'collection' => '/admin/structure/page-layout', |
| 55 | 'add-form' => '/admin/structure/page-layout/add', |
| 56 | 'edit-form' => '/admin/structure/page-layout/{page_layout}', |
| 57 | 'display-builder' => '/admin/structure/page-layout/{page_layout}/builder', |
| 58 | 'delete-form' => '/admin/structure/page-layout/{page_layout}/delete', |
| 59 | ], |
| 60 | admin_permission: 'administer page_layout', |
| 61 | label_count: [ |
| 62 | 'singular' => '@count page layout', |
| 63 | 'plural' => '@count page layouts', |
| 64 | ], |
| 65 | config_export: [ |
| 66 | 'id', |
| 67 | 'label', |
| 68 | 'weight', |
| 69 | ConfigFormBuilderInterface::PROFILE_PROPERTY, |
| 70 | ConfigFormBuilderInterface::SOURCES_PROPERTY, |
| 71 | 'conditions', |
| 72 | ], |
| 73 | )] |
| 74 | final class PageLayout extends ConfigEntityBase implements PageLayoutInterface { |
| 75 | |
| 76 | /** |
| 77 | * The example ID. |
| 78 | */ |
| 79 | protected string $id; |
| 80 | |
| 81 | /** |
| 82 | * The example label. |
| 83 | */ |
| 84 | protected string $label; |
| 85 | |
| 86 | /** |
| 87 | * Weight of this page layout when negotiating the page variant. |
| 88 | * |
| 89 | * The first/lowest that is accessible according to conditions is loaded. |
| 90 | * |
| 91 | * @var int |
| 92 | */ |
| 93 | protected $weight = 0; |
| 94 | |
| 95 | /** |
| 96 | * Display Builder Profile ID. |
| 97 | */ |
| 98 | protected string $profile = ''; |
| 99 | |
| 100 | /** |
| 101 | * A list of sources plugins. |
| 102 | * |
| 103 | * @var array |
| 104 | */ |
| 105 | protected $sources = []; |
| 106 | |
| 107 | /** |
| 108 | * Condition settings for storage. |
| 109 | * |
| 110 | * @var array |
| 111 | */ |
| 112 | protected $conditions = []; |
| 113 | |
| 114 | /** |
| 115 | * The loaded display builder instance. |
| 116 | */ |
| 117 | protected ?InstanceInterface $instance; |
| 118 | |
| 119 | /** |
| 120 | * The conditions plugins for this page. |
| 121 | */ |
| 122 | private ConditionPluginCollection $conditionPluginCollection; |
| 123 | |
| 124 | /** |
| 125 | * {@inheritdoc} |
| 126 | */ |
| 127 | public static function getPrefix(): string { |
| 128 | return 'page_layout__'; |
| 129 | } |
| 130 | |
| 131 | /** |
| 132 | * {@inheritdoc} |
| 133 | */ |
| 134 | public function getPluginCollections(): array { |
| 135 | return [ |
| 136 | 'conditions' => $this->getConditions(), |
| 137 | ]; |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * {@inheritdoc} |
| 142 | */ |
| 143 | public static function getContextRequirement(): string { |
| 144 | return 'page'; |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * {@inheritdoc} |
| 149 | */ |
| 150 | public static function checkInstanceId(string $instance_id): ?array { |
| 151 | if (!\str_starts_with($instance_id, self::getPrefix())) { |
| 152 | return NULL; |
| 153 | } |
| 154 | [, $page_layout] = \explode('__', $instance_id); |
| 155 | |
| 156 | return [ |
| 157 | 'page_layout' => $page_layout, |
| 158 | ]; |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | * {@inheritdoc} |
| 163 | */ |
| 164 | public function getBuilderUrl(): Url { |
| 165 | return Url::fromRoute('entity.page_layout.display_builder', ['page_layout' => $this->id()]); |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * {@inheritdoc} |
| 170 | */ |
| 171 | public static function getUrlFromInstanceId(string $instance_id): Url { |
| 172 | $params = self::checkInstanceId($instance_id); |
| 173 | |
| 174 | if (!$params) { |
| 175 | // Fallback to the list of instances. |
| 176 | return Url::fromRoute('entity.display_builder_instance.collection'); |
| 177 | } |
| 178 | |
| 179 | return Url::fromRoute('entity.page_layout.display_builder', $params); |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * {@inheritdoc} |
| 184 | */ |
| 185 | public static function getDisplayUrlFromInstanceId(string $instance_id): Url { |
| 186 | $params = self::checkInstanceId($instance_id); |
| 187 | |
| 188 | if (!$params) { |
| 189 | // Fallback to the list of instances. |
| 190 | return Url::fromRoute('entity.display_builder_instance.collection'); |
| 191 | } |
| 192 | |
| 193 | return Url::fromRoute('entity.page_layout.edit_form', $params); |
| 194 | } |
| 195 | |
| 196 | /** |
| 197 | * {@inheritdoc} |
| 198 | */ |
| 199 | public function getProfile(): ?ProfileInterface { |
| 200 | $storage = $this->entityTypeManager()->getStorage('display_builder_profile'); |
| 201 | $profile_id = $this->get(ConfigFormBuilderInterface::PROFILE_PROPERTY); |
| 202 | |
| 203 | if (!$profile_id) { |
| 204 | return NULL; |
| 205 | } |
| 206 | |
| 207 | /** @var \Drupal\display_builder\ProfileInterface $builder */ |
| 208 | $builder = $storage->load($profile_id); |
| 209 | |
| 210 | return $builder; |
| 211 | } |
| 212 | |
| 213 | /** |
| 214 | * {@inheritdoc} |
| 215 | */ |
| 216 | public function getInstanceId(): ?string { |
| 217 | // Usually an entity is new if no ID exists for it yet. |
| 218 | if ($this->isNew()) { |
| 219 | return NULL; |
| 220 | } |
| 221 | |
| 222 | return \sprintf('%s%s', self::getPrefix(), $this->id()); |
| 223 | } |
| 224 | |
| 225 | /** |
| 226 | * {@inheritdoc} |
| 227 | */ |
| 228 | public static function checkAccess(string $instance_id, AccountInterface $account): AccessResultInterface { |
| 229 | return $account->hasPermission('administer page_layout') ? AccessResult::allowed() : AccessResult::forbidden(); |
| 230 | } |
| 231 | |
| 232 | /** |
| 233 | * {@inheritdoc} |
| 234 | */ |
| 235 | public function initInstanceIfMissing(): void { |
| 236 | /** @var \Drupal\display_builder\InstanceStorage $storage */ |
| 237 | $storage = $this->entityTypeManager()->getStorage('display_builder_instance'); |
| 238 | |
| 239 | /** @var \Drupal\display_builder\InstanceInterface $instance */ |
| 240 | $instance = $storage->load($this->getInstanceId()); |
| 241 | |
| 242 | if (!$instance) { |
| 243 | $instance = $storage->createFromImplementation($this); |
| 244 | $instance->save(); |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | /** |
| 249 | * {@inheritdoc} |
| 250 | */ |
| 251 | public function getInitialSources(): array { |
| 252 | $sources = $this->getSources(); |
| 253 | |
| 254 | if (empty($sources)) { |
| 255 | // Fallback to a fixture mimicking the standard page layout. |
| 256 | $sources = DisplayBuilderHelpers::getFixtureDataFromExtension('display_builder_page_layout', 'default_page_layout'); |
| 257 | } |
| 258 | |
| 259 | return $sources; |
| 260 | } |
| 261 | |
| 262 | /** |
| 263 | * {@inheritdoc} |
| 264 | */ |
| 265 | public function getInitialContext(): array { |
| 266 | $contexts = []; |
| 267 | $contexts = RequirementsContext::addToContext([self::getContextRequirement()], $contexts); |
| 268 | |
| 269 | return $contexts; |
| 270 | } |
| 271 | |
| 272 | /** |
| 273 | * {@inheritdoc} |
| 274 | */ |
| 275 | public function getSources(): array { |
| 276 | return $this->sources; |
| 277 | } |
| 278 | |
| 279 | /** |
| 280 | * {@inheritdoc} |
| 281 | */ |
| 282 | public function saveSources(): void { |
| 283 | $this->sources = $this->getInstance()->getCurrentState(); |
| 284 | $this->save(); |
| 285 | } |
| 286 | |
| 287 | /** |
| 288 | * {@inheritdoc} |
| 289 | */ |
| 290 | public function getConditions(): ConditionPluginCollection { |
| 291 | if (!isset($this->conditionPluginCollection)) { |
| 292 | // Static call because EntityBase and descendants don't support |
| 293 | // dependency injection. |
| 294 | $manager = \Drupal::service('plugin.manager.condition'); |
| 295 | $this->conditionPluginCollection = new ConditionPluginCollection($manager, $this->get('conditions')); |
| 296 | } |
| 297 | |
| 298 | return $this->conditionPluginCollection; |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * {@inheritdoc} |
| 303 | */ |
| 304 | public function calculateDependencies(): PageLayout { |
| 305 | parent::calculateDependencies(); |
| 306 | $display_builder = $this->getProfile(); |
| 307 | $instance = $this->getInstance(); |
| 308 | |
| 309 | if ($display_builder && $instance) { |
| 310 | $this->addDependency('config', $display_builder->getConfigDependencyName()); |
| 311 | $contexts = $instance->getContexts() ?? []; |
| 312 | |
| 313 | foreach ($this->getSources() as $source_data) { |
| 314 | /** @var \Drupal\ui_patterns\SourceInterface $source */ |
| 315 | $source = $this->sourceManager()->getSource('', [], $source_data, $contexts); |
| 316 | $this->addDependencies($source->calculateDependencies()); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | return $this; |
| 321 | } |
| 322 | |
| 323 | /** |
| 324 | * {@inheritdoc} |
| 325 | */ |
| 326 | public function delete(): void { |
| 327 | if ($this->getInstance()) { |
| 328 | $storage = $this->entityTypeManager()->getStorage('display_builder_instance'); |
| 329 | $storage->delete([$this->getInstance()]); |
| 330 | } |
| 331 | |
| 332 | parent::delete(); |
| 333 | } |
| 334 | |
| 335 | /** |
| 336 | * {@inheritdoc} |
| 337 | */ |
| 338 | public function postSave(EntityStorageInterface $storage, $update = TRUE): void { |
| 339 | $this->initInstanceIfMissing(); |
| 340 | $instance = $this->getInstance(); |
| 341 | |
| 342 | // Save the profile in the instance if changed. |
| 343 | if ($instance->getProfile()->id() !== $this->profile) { |
| 344 | $instance->setProfile($this->profile); |
| 345 | $instance->save(); |
| 346 | } |
| 347 | |
| 348 | if ($this->isImpactingPageVariantDetection($update)) { |
| 349 | // In DisplayBuilderPageVariant we add PageLayout::>getCacheTags() to the |
| 350 | // page renderable but it works only for the pages already managed by |
| 351 | // Display Builder. |
| 352 | // In PageVariantSubscriber::onSelectPageDisplayVariant() we add a custom |
| 353 | // tag for the others. |
| 354 | /** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type */ |
| 355 | $entity_type = $this->getEntityType(); |
| 356 | \Drupal::service('cache_tags.invalidator')->invalidateTags([$entity_type->getConfigPrefix()]); |
| 357 | } |
| 358 | |
| 359 | parent::postSave($storage, $update); |
| 360 | } |
| 361 | |
| 362 | /** |
| 363 | * Does the page cache need to be flushed? |
| 364 | * |
| 365 | * Flushing a cache is something to be careful enough. Let's flush only when |
| 366 | * needed. |
| 367 | * |
| 368 | * @param bool $update |
| 369 | * TRUE if the entity has been updated, or FALSE if it has been inserted. |
| 370 | * |
| 371 | * @return bool |
| 372 | * TRUE if the cache need to be flushed. |
| 373 | */ |
| 374 | private function isImpactingPageVariantDetection(bool $update = TRUE): bool { |
| 375 | // A new active page layout has been added. |
| 376 | if (!$update && $this->status && !empty($this->sources)) { |
| 377 | return TRUE; |
| 378 | } |
| 379 | |
| 380 | // Other additions have no impact. |
| 381 | if (!$update) { |
| 382 | return FALSE; |
| 383 | } |
| 384 | |
| 385 | $previous = $this->originalEntity; |
| 386 | |
| 387 | // Those properties are impacting AccessControlHandler logic and |
| 388 | // PageVariantSubscriber results. |
| 389 | foreach (['weight', 'conditions', 'status'] as $property) { |
| 390 | if ($this->get($property) !== $previous->get($property)) { |
| 391 | return TRUE; |
| 392 | } |
| 393 | } |
| 394 | |
| 395 | // A page layout with empty sources is skipped by AccessControlHandler. |
| 396 | // This is also altering PageVariantSubscriber results. |
| 397 | if (empty($this->sources) !== empty($previous->get('sources'))) { |
| 398 | return TRUE; |
| 399 | } |
| 400 | |
| 401 | return FALSE; |
| 402 | } |
| 403 | |
| 404 | /** |
| 405 | * Gets the Display Builder instance. |
| 406 | * |
| 407 | * @return \Drupal\display_builder\InstanceInterface|null |
| 408 | * A display builder instance. |
| 409 | */ |
| 410 | private function getInstance(): ?InstanceInterface { |
| 411 | if (!$this->getInstanceId()) { |
| 412 | return NULL; |
| 413 | } |
| 414 | |
| 415 | if (!isset($this->instance)) { |
| 416 | /** @var \Drupal\display_builder\InstanceInterface|null $instance */ |
| 417 | $instance = $this->entityTypeManager()->getStorage('display_builder_instance')->load($this->getInstanceId()); |
| 418 | $this->instance = $instance; |
| 419 | } |
| 420 | |
| 421 | return $this->instance; |
| 422 | } |
| 423 | |
| 424 | /** |
| 425 | * Gets the UI Patterns Source plugins manager. |
| 426 | * |
| 427 | * @return \Drupal\ui_patterns\SourcePluginManager |
| 428 | * The manager for source plugins. |
| 429 | */ |
| 430 | private function sourceManager(): SourcePluginManager { |
| 431 | return \Drupal::service('plugin.manager.ui_patterns_source'); |
| 432 | } |
| 433 | |
| 434 | } |
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.
| 305 | parent::calculateDependencies(); |
| 306 | $display_builder = $this->getProfile(); |
| 307 | $instance = $this->getInstance(); |
| 308 | |
| 309 | if ($display_builder && $instance) { |
| 309 | if ($display_builder && $instance) { |
| 310 | $this->addDependency('config', $display_builder->getConfigDependencyName()); |
| 311 | $contexts = $instance->getContexts() ?? []; |
| 312 | |
| 313 | foreach ($this->getSources() as $source_data) { |
| 313 | foreach ($this->getSources() as $source_data) { |
| 313 | foreach ($this->getSources() as $source_data) { |
| 314 | /** @var \Drupal\ui_patterns\SourceInterface $source */ |
| 315 | $source = $this->sourceManager()->getSource('', [], $source_data, $contexts); |
| 313 | foreach ($this->getSources() as $source_data) { |
| 314 | /** @var \Drupal\ui_patterns\SourceInterface $source */ |
| 315 | $source = $this->sourceManager()->getSource('', [], $source_data, $contexts); |
| 316 | $this->addDependencies($source->calculateDependencies()); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | return $this; |
| 320 | return $this; |
| 228 | public static function checkAccess(string $instance_id, AccountInterface $account): AccessResultInterface { |
| 229 | return $account->hasPermission('administer page_layout') ? AccessResult::allowed() : AccessResult::forbidden(); |
| 229 | return $account->hasPermission('administer page_layout') ? AccessResult::allowed() : AccessResult::forbidden(); |
| 229 | return $account->hasPermission('administer page_layout') ? AccessResult::allowed() : AccessResult::forbidden(); |
| 229 | return $account->hasPermission('administer page_layout') ? AccessResult::allowed() : AccessResult::forbidden(); |
| 150 | public static function checkInstanceId(string $instance_id): ?array { |
| 151 | if (!\str_starts_with($instance_id, self::getPrefix())) { |
| 152 | return NULL; |
| 154 | [, $page_layout] = \explode('__', $instance_id); |
| 155 | |
| 156 | return [ |
| 157 | 'page_layout' => $page_layout, |
| 327 | if ($this->getInstance()) { |
| 328 | $storage = $this->entityTypeManager()->getStorage('display_builder_instance'); |
| 329 | $storage->delete([$this->getInstance()]); |
| 330 | } |
| 331 | |
| 332 | parent::delete(); |
| 332 | parent::delete(); |
| 333 | } |
| 165 | return Url::fromRoute('entity.page_layout.display_builder', ['page_layout' => $this->id()]); |
| 291 | if (!isset($this->conditionPluginCollection)) { |
| 294 | $manager = \Drupal::service('plugin.manager.condition'); |
| 295 | $this->conditionPluginCollection = new ConditionPluginCollection($manager, $this->get('conditions')); |
| 296 | } |
| 297 | |
| 298 | return $this->conditionPluginCollection; |
| 298 | return $this->conditionPluginCollection; |
| 144 | return 'page'; |
| 185 | public static function getDisplayUrlFromInstanceId(string $instance_id): Url { |
| 186 | $params = self::checkInstanceId($instance_id); |
| 187 | |
| 188 | if (!$params) { |
| 190 | return Url::fromRoute('entity.display_builder_instance.collection'); |
| 193 | return Url::fromRoute('entity.page_layout.edit_form', $params); |
| 266 | $contexts = []; |
| 267 | $contexts = RequirementsContext::addToContext([self::getContextRequirement()], $contexts); |
| 268 | |
| 269 | return $contexts; |
| 252 | $sources = $this->getSources(); |
| 253 | |
| 254 | if (empty($sources)) { |
| 256 | $sources = DisplayBuilderHelpers::getFixtureDataFromExtension('display_builder_page_layout', 'default_page_layout'); |
| 257 | } |
| 258 | |
| 259 | return $sources; |
| 259 | return $sources; |
| 411 | if (!$this->getInstanceId()) { |
| 412 | return NULL; |
| 415 | if (!isset($this->instance)) { |
| 417 | $instance = $this->entityTypeManager()->getStorage('display_builder_instance')->load($this->getInstanceId()); |
| 418 | $this->instance = $instance; |
| 419 | } |
| 420 | |
| 421 | return $this->instance; |
| 421 | return $this->instance; |
| 218 | if ($this->isNew()) { |
| 219 | return NULL; |
| 222 | return \sprintf('%s%s', self::getPrefix(), $this->id()); |
| 136 | 'conditions' => $this->getConditions(), |
| 128 | return 'page_layout__'; |
| 200 | $storage = $this->entityTypeManager()->getStorage('display_builder_profile'); |
| 201 | $profile_id = $this->get(ConfigFormBuilderInterface::PROFILE_PROPERTY); |
| 202 | |
| 203 | if (!$profile_id) { |
| 204 | return NULL; |
| 208 | $builder = $storage->load($profile_id); |
| 209 | |
| 210 | return $builder; |
| 276 | return $this->sources; |
| 171 | public static function getUrlFromInstanceId(string $instance_id): Url { |
| 172 | $params = self::checkInstanceId($instance_id); |
| 173 | |
| 174 | if (!$params) { |
| 176 | return Url::fromRoute('entity.display_builder_instance.collection'); |
| 179 | return Url::fromRoute('entity.page_layout.display_builder', $params); |
| 237 | $storage = $this->entityTypeManager()->getStorage('display_builder_instance'); |
| 238 | |
| 239 | /** @var \Drupal\display_builder\InstanceInterface $instance */ |
| 240 | $instance = $storage->load($this->getInstanceId()); |
| 241 | |
| 242 | if (!$instance) { |
| 243 | $instance = $storage->createFromImplementation($this); |
| 244 | $instance->save(); |
| 245 | } |
| 246 | } |
| 246 | } |
| 374 | private function isImpactingPageVariantDetection(bool $update = TRUE): bool { |
| 375 | // A new active page layout has been added. |
| 376 | if (!$update && $this->status && !empty($this->sources)) { |
| 376 | if (!$update && $this->status && !empty($this->sources)) { |
| 376 | if (!$update && $this->status && !empty($this->sources)) { |
| 377 | return TRUE; |
| 381 | if (!$update) { |
| 382 | return FALSE; |
| 385 | $previous = $this->originalEntity; |
| 386 | |
| 387 | // Those properties are impacting AccessControlHandler logic and |
| 388 | // PageVariantSubscriber results. |
| 389 | foreach (['weight', 'conditions', 'status'] as $property) { |
| 389 | foreach (['weight', 'conditions', 'status'] as $property) { |
| 390 | if ($this->get($property) !== $previous->get($property)) { |
| 391 | return TRUE; |
| 389 | foreach (['weight', 'conditions', 'status'] as $property) { |
| 390 | if ($this->get($property) !== $previous->get($property)) { |
| 391 | return TRUE; |
| 392 | } |
| 393 | } |
| 394 | |
| 395 | // A page layout with empty sources is skipped by AccessControlHandler. |
| 396 | // This is also altering PageVariantSubscriber results. |
| 397 | if (empty($this->sources) !== empty($previous->get('sources'))) { |
| 398 | return TRUE; |
| 401 | return FALSE; |
| 338 | public function postSave(EntityStorageInterface $storage, $update = TRUE): void { |
| 339 | $this->initInstanceIfMissing(); |
| 340 | $instance = $this->getInstance(); |
| 341 | |
| 342 | // Save the profile in the instance if changed. |
| 343 | if ($instance->getProfile()->id() !== $this->profile) { |
| 344 | $instance->setProfile($this->profile); |
| 345 | $instance->save(); |
| 346 | } |
| 347 | |
| 348 | if ($this->isImpactingPageVariantDetection($update)) { |
| 348 | if ($this->isImpactingPageVariantDetection($update)) { |
| 355 | $entity_type = $this->getEntityType(); |
| 356 | \Drupal::service('cache_tags.invalidator')->invalidateTags([$entity_type->getConfigPrefix()]); |
| 357 | } |
| 358 | |
| 359 | parent::postSave($storage, $update); |
| 359 | parent::postSave($storage, $update); |
| 360 | } |
| 283 | $this->sources = $this->getInstance()->getCurrentState(); |
| 284 | $this->save(); |
| 285 | } |
| 431 | return \Drupal::service('plugin.manager.ui_patterns_source'); |