Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
60.48% covered (warning)
60.48%
101 / 167
56.12% covered (warning)
56.12%
55 / 98
39.74% covered (danger)
39.74%
31 / 78
56.67% covered (warning)
56.67%
17 / 30
CRAP
0.00% covered (danger)
0.00%
0 / 1
EntityViewDisplayTrait
60.48% covered (warning)
60.48%
101 / 167
56.12% covered (warning)
56.12%
55 / 98
39.74% covered (danger)
39.74%
31 / 78
56.67% covered (warning)
56.67%
17 / 30
960.13
0.00% covered (danger)
0.00%
0 / 1
 calculateDependencies
92.31% covered (success)
92.31%
12 / 13
90.00% covered (success)
90.00%
9 / 10
50.00% covered (danger)
50.00%
3 / 6
0.00% covered (danger)
0.00%
0 / 1
8.12
 isDisplayBuilderEnabled
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 onDependencyRemoval
91.67% covered (success)
91.67%
11 / 12
85.71% covered (warning)
85.71%
6 / 7
20.00% covered (danger)
20.00%
1 / 5
0.00% covered (danger)
0.00%
0 / 1
12.19
 getPrefix
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
 getContextRequirement
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
 checkInstanceId
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getBuilderUrl
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 getUrlFromInstanceId
100.00% covered (success)
100.00%
3 / 3
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
 getDisplayUrlFromInstanceId
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDisplayBuilderOverrideField
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
 getDisplayBuilderOverrideProfile
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 isDisplayBuilderOverridable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getProfile
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getInstanceId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 checkAccess
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 initInstanceIfMissing
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getInitialSources
100.00% covered (success)
100.00%
4 / 4
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
 getInitialContext
100.00% covered (success)
100.00%
10 / 10
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
 getSources
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
 saveSources
100.00% covered (success)
100.00%
3 / 3
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
 postSave
55.56% covered (warning)
55.56%
10 / 18
53.85% covered (warning)
53.85%
7 / 13
16.67% covered (danger)
16.67%
3 / 18
0.00% covered (danger)
0.00%
0 / 1
35.36
 delete
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 buildMultiple
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
30
 isOverrideOfCurrentDisplay
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 getContextsForEntity
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 contextRepository
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInstance
100.00% covered (success)
100.00%
3 / 3
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
 loadDisplayBuilder
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
 buildSources
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getUrlParamsFromInstanceId
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder_entity_view\Entity;
6
7use Drupal\Core\Access\AccessResult;
8use Drupal\Core\Access\AccessResultInterface;
9use Drupal\Core\Cache\CacheableMetadata;
10use Drupal\Core\Entity\EntityStorageInterface;
11use Drupal\Core\Entity\FieldableEntityInterface;
12use Drupal\Core\Plugin\Context\Context;
13use Drupal\Core\Plugin\Context\ContextDefinition;
14use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
15use Drupal\Core\Plugin\Context\EntityContext;
16use Drupal\Core\Session\AccountInterface;
17use Drupal\Core\Url;
18use Drupal\display_builder\ConfigFormBuilderInterface;
19use Drupal\display_builder\DisplayBuildableInterface;
20use Drupal\display_builder\InstanceInterface;
21use Drupal\display_builder\ProfileInterface;
22use Drupal\display_builder_entity_view\Field\DisplayBuilderItemList;
23use Drupal\ui_patterns\Plugin\Context\RequirementsContext;
24
25/**
26 * Common methods for entity view display.
27 */
28trait EntityViewDisplayTrait {
29
30  /**
31   * Calculates dependencies for the display builder.
32   *
33   * @return $this
34   *   The current instance.
35   *
36   * @see \Drupal\Core\Entity\Display\EntityViewDisplayInterface
37   */
38  public function calculateDependencies(): self {
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
42      // If there is no instance ID, we cannot calculate dependencies.
43      return $this;
44    }
45
46    /** @var \Drupal\display_builder\InstanceInterface $instance */
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
50      return $this;
51    }
52    $contexts = $instance->getContexts();
53
54    if (!$contexts) {
55      return $this;
56    }
57
58    foreach ($this->getSources() as $source_data) {
59      /** @var \Drupal\ui_patterns\SourceInterface $source */
60      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
61      $this->addDependencies($source->calculateDependencies());
62    }
63
64    return $this;
65  }
66
67  /**
68   * Is display builder enabled?
69   *
70   * @return bool
71   *   The display builder is enabled if there is a Display Builder entity.
72   *
73   * @see \Drupal\display_builder_entity_view\DisplayBuilderEnabledInterface
74   */
75  public function isDisplayBuilderEnabled(): bool {
76    // Display Builder must not be enabled for the '_custom' view mode that is
77    // used for on-the-fly rendering of fields in isolation from the entity.
78    if ($this->getOriginalMode() === static::CUSTOM_MODE) {
79      return FALSE;
80    }
81
82    return (bool) $this->getProfile();
83  }
84
85  /**
86   * Handler for when dependencies are removed.
87   *
88   * @param array $dependencies
89   *   The dependencies that were removed.
90   *
91   * @return bool
92   *   TRUE if the display can be overridden, FALSE otherwise.
93   *
94   * @see \Drupal\Core\Entity\Display\EntityViewDisplayInterface
95   */
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
106      return TRUE;
107    }
108
109    $contexts = $instance->getContexts();
110
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
122      }
123    }
124
125    return $changed;
126  }
127
128  /**
129   * {@inheritdoc}
130   */
131  public static function getPrefix(): string {
132    return 'entity_view__';
133  }
134
135  /**
136   * Returns the context requirement for this entity view display.
137   *
138   * This is used to ensure that the entity context is available when building
139   * the display builder.
140   *
141   * @return string
142   *   The context requirement string.
143   *
144   * @see \Drupal\display_builder\DisplayBuildableInterface
145   */
146  public static function getContextRequirement(): string {
147    return 'entity';
148  }
149
150  /**
151   * {@inheritdoc}
152   *
153   * @see \Drupal\display_builder\DisplayBuildableInterface
154   */
155  public static function checkInstanceId(string $instance_id): ?array {
156    if (!\str_starts_with($instance_id, EntityViewDisplay::getPrefix())) {
157      return NULL;
158    }
159    [, $entity, $bundle, $view_mode] = \explode('__', $instance_id);
160
161    return [
162      'entity' => $entity,
163      'bundle' => $bundle,
164      'view_mode' => $view_mode,
165    ];
166  }
167
168  /**
169   * {@inheritdoc}
170   */
171  public function getBuilderUrl(): Url {
172    $fieldable_entity_type = $this->entityTypeManager->getDefinition($this->getTargetEntityTypeId());
173    $bundle_parameter_key = $fieldable_entity_type->getBundleEntityType() ?: 'bundle';
174    $parameters = [
175      $bundle_parameter_key => $this->getTargetBundle(),
176      'view_mode_name' => $this->getMode(),
177    ];
178    $route_name = \sprintf('display_builder_entity_view.%s', $this->getTargetEntityTypeId());
179
180    return Url::fromRoute($route_name, $parameters);
181  }
182
183  /**
184   * Returns the URL for the display builder from an instance id.
185   *
186   * @param string $instance_id
187   *   The builder instance ID.
188   *
189   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
190   *
191   * @return \Drupal\Core\Url
192   *   The url of the instance.
193   *
194   * @see \Drupal\display_builder\DisplayBuildableInterface
195   */
196  public static function getUrlFromInstanceId(string $instance_id): Url {
197    $params = self::getUrlParamsFromInstanceId($instance_id);
198    $route_name = \sprintf('display_builder_entity_view.%s', $params['entity']);
199
200    return Url::fromRoute($route_name, $params);
201  }
202
203  /**
204   * Returns the URL for the display builder from an instance id.
205   *
206   * @param string $instance_id
207   *   The builder instance ID.
208   *
209   * @return \Drupal\Core\Url
210   *   The url of the instance.
211   *
212   * @see Drupal\display_builder\DisplayBuildableInterface
213   */
214  public static function getDisplayUrlFromInstanceId(string $instance_id): Url {
215    $params = self::getUrlParamsFromInstanceId($instance_id);
216    $route_name = \sprintf('entity.entity_view_display.%s.view_mode', $params['entity']);
217
218    return Url::fromRoute($route_name, $params);
219  }
220
221  /**
222   * Returns the field name used to store overridden displays.
223   *
224   * @return string|null
225   *   The field name used to store overridden displays, or NULL if not set.
226   *
227   * @see \Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface
228   */
229  public function getDisplayBuilderOverrideField(): ?string {
230    return $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY);
231  }
232
233  /**
234   * Returns the display builder override profile.
235   *
236   * @return \Drupal\display_builder\ProfileInterface|null
237   *   The display builder override profile, or NULL if not set.
238   *
239   * @see \Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface
240   */
241  public function getDisplayBuilderOverrideProfile(): ?ProfileInterface {
242    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY);
243
244    if ($display_builder_id === NULL) {
245      return NULL;
246    }
247
248    return $this->loadDisplayBuilder($display_builder_id);
249  }
250
251  /**
252   * Returns TRUE if the display can be overridden.
253   *
254   * @return bool
255   *   TRUE if the display can be overridden, FALSE otherwise.
256   *
257   * @see \Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface
258   */
259  public function isDisplayBuilderOverridable(): bool {
260    return !empty($this->getDisplayBuilderOverrideField())
261      && $this->getDisplayBuilderOverrideProfile() !== NULL;
262  }
263
264  /**
265   * Returns the display builder instance.
266   *
267   * @return \Drupal\display_builder\ProfileInterface|null
268   *   The display builder instance, or NULL if not set.
269   *
270   * @see \Drupal\display_builder\DisplayBuildableInterface
271   */
272  public function getProfile(): ?ProfileInterface {
273    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::PROFILE_PROPERTY);
274
275    if ($display_builder_id === NULL) {
276      return NULL;
277    }
278
279    return $this->loadDisplayBuilder($display_builder_id);
280  }
281
282  /**
283   * Returns the instance ID for the display builder.
284   *
285   * @return string|null
286   *   The instance ID for the display builder, or NULL if the entity is new.
287   *
288   * @see \Drupal\display_builder\DisplayBuildableInterface
289   */
290  public function getInstanceId(): ?string {
291    // Usually an entity is new if no ID exists for it yet.
292    if ($this->isNew()) {
293      return NULL;
294    }
295
296    return \sprintf('%s%s', EntityViewDisplay::getPrefix(), \str_replace('.', '__', $this->id));
297  }
298
299  /**
300   * Checks access.
301   *
302   * @param string $instance_id
303   *   Instance entity ID.
304   * @param \Drupal\Core\Session\AccountInterface $account
305   *   The user session for which to check access.
306   *
307   * @return \Drupal\Core\Access\AccessResultInterface
308   *   The access result.
309   *
310   * @see \Drupal\display_builder\InstanceAccessControlHandler
311   */
312  public static function checkAccess(string $instance_id, AccountInterface $account): AccessResultInterface {
313    $params = self::getUrlParamsFromInstanceId($instance_id);
314    $permission = 'administer ' . $params['entity'] . ' display';
315
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
317  }
318
319  /**
320   * Initializes the display builder instance if it is missing.
321   *
322   * @see \Drupal\display_builder\DisplayBuildableInterface
323   */
324  public function initInstanceIfMissing(): void {
325    /** @var \Drupal\display_builder\InstanceStorage $storage */
326    $storage = $this->entityTypeManager->getStorage('display_builder_instance');
327
328    /** @var \Drupal\display_builder\InstanceInterface $instance */
329    $instance = $storage->load($this->getInstanceId());
330
331    if (!$instance) {
332      $instance = $storage->createFromImplementation($this);
333      $instance->save();
334    }
335  }
336
337  /**
338   * {@inheritdoc}
339   */
340  public function getInitialSources(): array {
341    // Get the sources stored in config.
342    $sources = $this->getSources();
343
344    if (empty($sources)) {
345      // initialImport() has two implementations:
346      // - EntityViewDisplay::initialImport()
347      // - LayoutBuilderEntityViewDisplay::initialImport()
348      $sources = $this->initialImport();
349    }
350
351    return $sources;
352  }
353
354  /**
355   * {@inheritdoc}
356   */
357  public function getInitialContext(): array {
358    $entity_type_id = $this->getTargetEntityTypeId();
359    $bundle = $this->getTargetBundle();
360    $view_mode = $this->getMode();
361    $sampleEntity = $this->sampleEntityGenerator->get($entity_type_id, $bundle);
362    $contexts = [
363      'entity' => EntityContext::fromEntity($sampleEntity),
364      'bundle' => new Context(ContextDefinition::create('string'), $bundle),
365      'view_mode' => new Context(ContextDefinition::create('string'), $view_mode),
366    ];
367
368    return RequirementsContext::addToContext([self::getContextRequirement()], $contexts);
369  }
370
371  /**
372   * Returns the sources of the display builder.
373   *
374   * @return array
375   *   The sources of the display builder.
376   *
377   * @see \Drupal\display_builder\DisplayBuildableInterface
378   */
379  public function getSources(): array {
380    return $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::SOURCES_PROPERTY, []);
381  }
382
383  /**
384   * Saves the sources of the display builder.
385   *
386   * @see \Drupal\display_builder\DisplayBuildableInterface
387   */
388  public function saveSources(): void {
389    $data = $this->getInstance()->getCurrentState();
390    $this->setThirdPartySetting('display_builder', ConfigFormBuilderInterface::SOURCES_PROPERTY, $data);
391    $this->save();
392  }
393
394  /**
395   * Post-save operations for the display builder.
396   *
397   * @param \Drupal\Core\Entity\EntityStorageInterface $storage
398   *   The entity storage.
399   * @param bool $update
400   *   Whether the entity is being updated.
401   *
402   * @see \Drupal\Core\Entity\Display\EntityViewDisplayInterface
403   */
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
438  }
439
440  /**
441   * Deletes the display builder instance if it exists.
442   *
443   * @see \Drupal\Core\Entity\Display\EntityViewDisplayInterface
444   */
445  public function delete(): void {
446    if ($instance = $this->getInstance()) {
447      $instance->delete();
448    }
449    parent::delete();
450  }
451
452  /**
453   * Builds a renderable array for the components of a set of entities.
454   *
455   * @param \Drupal\Core\Entity\FieldableEntityInterface[] $entities
456   *   The entities being displayed.
457   *
458   * @return array
459   *   A renderable array for the entities, indexed by the same keys as the
460   *   $entities array parameter.
461   *
462   * @see \Drupal\Core\Entity\Display\EntityViewDisplayInterface
463   */
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
471      // This is also preventing the availability of Display Builder overrides
472      // when Display Builder is not used for the entity view display.
473      // @todo Is it something we want to keep like that?
474      // @see https://www.drupal.org/project/display_builder/issues/3540048
475      return $build_list;
476    }
477
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
498  }
499
500  /**
501   * Chef if the instance is overriding this display.
502   *
503   * @param \Drupal\display_builder\InstanceInterface $instance
504   *   A list of display builder instances.
505   *
506   * @return bool
507   *   Is the instance overriding this display?
508   */
509  protected function isOverrideOfCurrentDisplay(InstanceInterface $instance): bool {
510    $parts = DisplayBuilderItemList::checkInstanceId((string) $instance->id());
511
512    if (!$parts) {
513      return FALSE;
514    }
515
516    if ($parts['entity_type_id'] !== $this->getTargetEntityTypeId()) {
517      return FALSE;
518    }
519
520    if ($parts['field_name'] !== $this->getDisplayBuilderOverrideField()) {
521      return FALSE;
522    }
523
524    return TRUE;
525  }
526
527  /**
528   * Gets the available contexts for a given entity.
529   *
530   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
531   *   The entity.
532   *
533   * @return \Drupal\Core\Plugin\Context\ContextInterface[]
534   *   An array of context objects for a given entity.
535   */
536  protected function getContextsForEntity(FieldableEntityInterface $entity): array {
537    $available_context_ids = \array_keys($this->contextRepository()->getAvailableContexts());
538
539    return [
540      'view_mode' => new Context(ContextDefinition::create('string'), $this->getMode()),
541      'entity' => EntityContext::fromEntity($entity),
542      'display' => EntityContext::fromEntity($this),
543    ] + $this->contextRepository()->getRuntimeContexts($available_context_ids);
544  }
545
546  /**
547   * Wraps the context repository service.
548   *
549   * @return \Drupal\Core\Plugin\Context\ContextRepositoryInterface
550   *   The context repository service.
551   */
552  protected function contextRepository(): ContextRepositoryInterface {
553    return \Drupal::service('context.repository');
554  }
555
556  /**
557   * Gets the Display Builder instance.
558   *
559   * @return \Drupal\display_builder\InstanceInterface|null
560   *   A display builder instance.
561   */
562  protected function getInstance(): ?InstanceInterface {
563    /** @var \Drupal\display_builder\InstanceInterface|null $instance */
564    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
565    $this->instance = $instance;
566
567    return $this->instance;
568  }
569
570  /**
571   * Loads display builder by id.
572   *
573   * @param string $display_builder_id
574   *   The display builder ID.
575   *
576   * @return \Drupal\display_builder\ProfileInterface|null
577   *   The display builder, or NULL if not found.
578   */
579  private function loadDisplayBuilder(string $display_builder_id): ?ProfileInterface {
580    if (empty($display_builder_id)) {
581      return NULL;
582    }
583    $storage = $this->entityTypeManager->getStorage('display_builder_profile');
584
585    /** @var \Drupal\display_builder\ProfileInterface $display_builder */
586    $display_builder = $storage->load($display_builder_id);
587
588    return $display_builder;
589  }
590
591  /**
592   * Builds the render array for the sources of a given entity.
593   *
594   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
595   *   The entity.
596   * @param array $sources
597   *   The sources to build.
598   *
599   * @return array
600   *   The render array representing the sources of the entity.
601   */
602  private function buildSources(FieldableEntityInterface $entity, array $sources): array {
603    $contexts = $this->getContextsForEntity($entity);
604    $cacheability = new CacheableMetadata();
605    $fake_build = [];
606
607    foreach ($sources as $source_data) {
608      $fake_build = $this->componentElementBuilder->buildSource($fake_build, 'content', [], $source_data, $contexts);
609    }
610    $build = $fake_build['#slots']['content'] ?? [];
611    $build['#cache'] = $fake_build['#cache'] ?? [];
612    // The render array is built based on decisions made by SourceStorage
613    // plugins, and therefore it needs to depend on the accumulated
614    // cacheability of those decisions.
615    $cacheability->applyTo($build);
616
617    return $build;
618  }
619
620  /**
621   * Returns the URL for the display builder from an instance id.
622   *
623   * @param string $instance_id
624   *   The builder instance ID.
625   *
626   * @return array
627   *   The url parameters for this instance id.
628   */
629  private static function getUrlParamsFromInstanceId(string $instance_id): array {
630    [, $entity, $bundle, $view_mode] = \explode('__', $instance_id);
631    $fieldable_entity_type = \Drupal::service('entity_type.manager')->getDefinition($entity);
632    $bundle_parameter_key = $fieldable_entity_type->getBundleEntityType() ?: 'bundle';
633
634    return [
635      $bundle_parameter_key => $bundle,
636      'view_mode_name' => $view_mode,
637      'entity' => $entity,
638    ];
639  }
640
641}

Paths

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

EntityViewDisplayTrait->buildMultiple
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
475      return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
 
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
 
489      if (\count($sources) === 0) {
 
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
 
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
 
489      if (\count($sources) === 0) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
 
489      if (\count($sources) === 0) {
 
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
 
489      if (\count($sources) === 0) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
464  public function buildMultiple(array $entities): array {
465    $build_list = parent::buildMultiple($entities);
466
467    // If no display builder enabled, stop here and return:
468    // - 'Manage Display' build if this trait is used in EntityViewDisplay
469    // - 'Layout Builder' build if used in LayoutBuilderEntityViewDisplay.
470    if (!$this->isDisplayBuilderEnabled()) {
 
478    foreach ($entities as $id => $entity) {
 
478    foreach ($entities as $id => $entity) {
479      $sources = [];
480
481      if ($this->isDisplayBuilderOverridable()) {
482        $display_builder_field = $this->getDisplayBuilderOverrideField();
483        $overridden_field = $entity->get($display_builder_field);
484        \assert($overridden_field instanceof DisplayBuildableInterface);
485        $sources = $overridden_field->getSources();
486      }
487
488      // If the overridden field is empty fallback to the entity view.
489      if (\count($sources) === 0) {
490        $sources = $this->getSources();
491      }
492
493      // @see entity.html.twig
494      $build_list[$id]['content'] = $this->buildSources($entity, $sources);
495    }
496
497    return $build_list;
EntityViewDisplayTrait->buildSources
602  private function buildSources(FieldableEntityInterface $entity, array $sources): array {
603    $contexts = $this->getContextsForEntity($entity);
604    $cacheability = new CacheableMetadata();
605    $fake_build = [];
606
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
608      $fake_build = $this->componentElementBuilder->buildSource($fake_build, 'content', [], $source_data, $contexts);
 
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
608      $fake_build = $this->componentElementBuilder->buildSource($fake_build, 'content', [], $source_data, $contexts);
609    }
610    $build = $fake_build['#slots']['content'] ?? [];
611    $build['#cache'] = $fake_build['#cache'] ?? [];
612    // The render array is built based on decisions made by SourceStorage
613    // plugins, and therefore it needs to depend on the accumulated
614    // cacheability of those decisions.
615    $cacheability->applyTo($build);
616
617    return $build;
602  private function buildSources(FieldableEntityInterface $entity, array $sources): array {
603    $contexts = $this->getContextsForEntity($entity);
604    $cacheability = new CacheableMetadata();
605    $fake_build = [];
606
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
608      $fake_build = $this->componentElementBuilder->buildSource($fake_build, 'content', [], $source_data, $contexts);
609    }
610    $build = $fake_build['#slots']['content'] ?? [];
611    $build['#cache'] = $fake_build['#cache'] ?? [];
612    // The render array is built based on decisions made by SourceStorage
613    // plugins, and therefore it needs to depend on the accumulated
614    // cacheability of those decisions.
615    $cacheability->applyTo($build);
616
617    return $build;
602  private function buildSources(FieldableEntityInterface $entity, array $sources): array {
603    $contexts = $this->getContextsForEntity($entity);
604    $cacheability = new CacheableMetadata();
605    $fake_build = [];
606
607    foreach ($sources as $source_data) {
 
607    foreach ($sources as $source_data) {
608      $fake_build = $this->componentElementBuilder->buildSource($fake_build, 'content', [], $source_data, $contexts);
609    }
610    $build = $fake_build['#slots']['content'] ?? [];
611    $build['#cache'] = $fake_build['#cache'] ?? [];
612    // The render array is built based on decisions made by SourceStorage
613    // plugins, and therefore it needs to depend on the accumulated
614    // cacheability of those decisions.
615    $cacheability->applyTo($build);
616
617    return $build;
EntityViewDisplayTrait->calculateDependencies
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
43      return $this;
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
 
50      return $this;
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
 
52    $contexts = $instance->getContexts();
53
54    if (!$contexts) {
 
55      return $this;
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
 
52    $contexts = $instance->getContexts();
53
54    if (!$contexts) {
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
59      /** @var \Drupal\ui_patterns\SourceInterface $source */
60      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
59      /** @var \Drupal\ui_patterns\SourceInterface $source */
60      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
61      $this->addDependencies($source->calculateDependencies());
62    }
63
64    return $this;
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
 
52    $contexts = $instance->getContexts();
53
54    if (!$contexts) {
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
59      /** @var \Drupal\ui_patterns\SourceInterface $source */
60      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
61      $this->addDependencies($source->calculateDependencies());
62    }
63
64    return $this;
39    parent::calculateDependencies();
40
41    if (!$this->getInstanceId()) {
 
47    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
48
49    if (!$instance) {
 
52    $contexts = $instance->getContexts();
53
54    if (!$contexts) {
 
58    foreach ($this->getSources() as $source_data) {
 
58    foreach ($this->getSources() as $source_data) {
59      /** @var \Drupal\ui_patterns\SourceInterface $source */
60      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
61      $this->addDependencies($source->calculateDependencies());
62    }
63
64    return $this;
EntityViewDisplayTrait->checkAccess
312  public static function checkAccess(string $instance_id, AccountInterface $account): AccessResultInterface {
313    $params = self::getUrlParamsFromInstanceId($instance_id);
314    $permission = 'administer ' . $params['entity'] . ' display';
315
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
 
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
 
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
312  public static function checkAccess(string $instance_id, AccountInterface $account): AccessResultInterface {
313    $params = self::getUrlParamsFromInstanceId($instance_id);
314    $permission = 'administer ' . $params['entity'] . ' display';
315
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
 
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
 
316    return $account->hasPermission($permission) ? AccessResult::allowed() : AccessResult::forbidden();
EntityViewDisplayTrait->checkInstanceId
155  public static function checkInstanceId(string $instance_id): ?array {
156    if (!\str_starts_with($instance_id, EntityViewDisplay::getPrefix())) {
 
157      return NULL;
155  public static function checkInstanceId(string $instance_id): ?array {
156    if (!\str_starts_with($instance_id, EntityViewDisplay::getPrefix())) {
 
159    [, $entity, $bundle, $view_mode] = \explode('__', $instance_id);
160
161    return [
162      'entity' => $entity,
163      'bundle' => $bundle,
164      'view_mode' => $view_mode,
EntityViewDisplayTrait->contextRepository
553    return \Drupal::service('context.repository');
EntityViewDisplayTrait->delete
446    if ($instance = $this->getInstance()) {
 
447      $instance->delete();
448    }
449    parent::delete();
 
449    parent::delete();
450  }
446    if ($instance = $this->getInstance()) {
 
449    parent::delete();
450  }
EntityViewDisplayTrait->getBuilderUrl
172    $fieldable_entity_type = $this->entityTypeManager->getDefinition($this->getTargetEntityTypeId());
173    $bundle_parameter_key = $fieldable_entity_type->getBundleEntityType() ?: 'bundle';
174    $parameters = [
175      $bundle_parameter_key => $this->getTargetBundle(),
176      'view_mode_name' => $this->getMode(),
177    ];
178    $route_name = \sprintf('display_builder_entity_view.%s', $this->getTargetEntityTypeId());
179
180    return Url::fromRoute($route_name, $parameters);
EntityViewDisplayTrait->getContextRequirement
147    return 'entity';
EntityViewDisplayTrait->getContextsForEntity
536  protected function getContextsForEntity(FieldableEntityInterface $entity): array {
537    $available_context_ids = \array_keys($this->contextRepository()->getAvailableContexts());
538
539    return [
540      'view_mode' => new Context(ContextDefinition::create('string'), $this->getMode()),
541      'entity' => EntityContext::fromEntity($entity),
542      'display' => EntityContext::fromEntity($this),
543    ] + $this->contextRepository()->getRuntimeContexts($available_context_ids);
EntityViewDisplayTrait->getDisplayBuilderOverrideField
230    return $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY);
EntityViewDisplayTrait->getDisplayBuilderOverrideProfile
242    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY);
243
244    if ($display_builder_id === NULL) {
 
245      return NULL;
242    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY);
243
244    if ($display_builder_id === NULL) {
 
248    return $this->loadDisplayBuilder($display_builder_id);
EntityViewDisplayTrait->getDisplayUrlFromInstanceId
214  public static function getDisplayUrlFromInstanceId(string $instance_id): Url {
215    $params = self::getUrlParamsFromInstanceId($instance_id);
216    $route_name = \sprintf('entity.entity_view_display.%s.view_mode', $params['entity']);
217
218    return Url::fromRoute($route_name, $params);
EntityViewDisplayTrait->getInitialContext
358    $entity_type_id = $this->getTargetEntityTypeId();
359    $bundle = $this->getTargetBundle();
360    $view_mode = $this->getMode();
361    $sampleEntity = $this->sampleEntityGenerator->get($entity_type_id, $bundle);
362    $contexts = [
363      'entity' => EntityContext::fromEntity($sampleEntity),
364      'bundle' => new Context(ContextDefinition::create('string'), $bundle),
365      'view_mode' => new Context(ContextDefinition::create('string'), $view_mode),
366    ];
367
368    return RequirementsContext::addToContext([self::getContextRequirement()], $contexts);
EntityViewDisplayTrait->getInitialSources
342    $sources = $this->getSources();
343
344    if (empty($sources)) {
 
348      $sources = $this->initialImport();
349    }
350
351    return $sources;
 
351    return $sources;
342    $sources = $this->getSources();
343
344    if (empty($sources)) {
 
351    return $sources;
EntityViewDisplayTrait->getInstance
564    $instance = $this->entityTypeManager->getStorage('display_builder_instance')->load($this->getInstanceId());
565    $this->instance = $instance;
566
567    return $this->instance;
EntityViewDisplayTrait->getInstanceId
292    if ($this->isNew()) {
 
293      return NULL;
292    if ($this->isNew()) {
 
296    return \sprintf('%s%s', EntityViewDisplay::getPrefix(), \str_replace('.', '__', $this->id));
EntityViewDisplayTrait->getPrefix
132    return 'entity_view__';
EntityViewDisplayTrait->getProfile
273    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::PROFILE_PROPERTY);
274
275    if ($display_builder_id === NULL) {
 
276      return NULL;
273    $display_builder_id = $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::PROFILE_PROPERTY);
274
275    if ($display_builder_id === NULL) {
 
279    return $this->loadDisplayBuilder($display_builder_id);
EntityViewDisplayTrait->getSources
380    return $this->getThirdPartySetting('display_builder', ConfigFormBuilderInterface::SOURCES_PROPERTY, []);
EntityViewDisplayTrait->getUrlFromInstanceId
196  public static function getUrlFromInstanceId(string $instance_id): Url {
197    $params = self::getUrlParamsFromInstanceId($instance_id);
198    $route_name = \sprintf('display_builder_entity_view.%s', $params['entity']);
199
200    return Url::fromRoute($route_name, $params);
EntityViewDisplayTrait->getUrlParamsFromInstanceId
629  private static function getUrlParamsFromInstanceId(string $instance_id): array {
630    [, $entity, $bundle, $view_mode] = \explode('__', $instance_id);
631    $fieldable_entity_type = \Drupal::service('entity_type.manager')->getDefinition($entity);
632    $bundle_parameter_key = $fieldable_entity_type->getBundleEntityType() ?: 'bundle';
633
634    return [
635      $bundle_parameter_key => $bundle,
636      'view_mode_name' => $view_mode,
637      'entity' => $entity,
EntityViewDisplayTrait->initInstanceIfMissing
326    $storage = $this->entityTypeManager->getStorage('display_builder_instance');
327
328    /** @var \Drupal\display_builder\InstanceInterface $instance */
329    $instance = $storage->load($this->getInstanceId());
330
331    if (!$instance) {
 
332      $instance = $storage->createFromImplementation($this);
333      $instance->save();
334    }
335  }
 
335  }
326    $storage = $this->entityTypeManager->getStorage('display_builder_instance');
327
328    /** @var \Drupal\display_builder\InstanceInterface $instance */
329    $instance = $storage->load($this->getInstanceId());
330
331    if (!$instance) {
 
335  }
EntityViewDisplayTrait->isDisplayBuilderEnabled
78    if ($this->getOriginalMode() === static::CUSTOM_MODE) {
 
79      return FALSE;
78    if ($this->getOriginalMode() === static::CUSTOM_MODE) {
 
82    return (bool) $this->getProfile();
EntityViewDisplayTrait->isDisplayBuilderOverridable
260    return !empty($this->getDisplayBuilderOverrideField())
 
261      && $this->getDisplayBuilderOverrideProfile() !== NULL;
 
261      && $this->getDisplayBuilderOverrideProfile() !== NULL;
260    return !empty($this->getDisplayBuilderOverrideField())
 
261      && $this->getDisplayBuilderOverrideProfile() !== NULL;
EntityViewDisplayTrait->isOverrideOfCurrentDisplay
509  protected function isOverrideOfCurrentDisplay(InstanceInterface $instance): bool {
510    $parts = DisplayBuilderItemList::checkInstanceId((string) $instance->id());
511
512    if (!$parts) {
 
513      return FALSE;
509  protected function isOverrideOfCurrentDisplay(InstanceInterface $instance): bool {
510    $parts = DisplayBuilderItemList::checkInstanceId((string) $instance->id());
511
512    if (!$parts) {
 
516    if ($parts['entity_type_id'] !== $this->getTargetEntityTypeId()) {
 
517      return FALSE;
509  protected function isOverrideOfCurrentDisplay(InstanceInterface $instance): bool {
510    $parts = DisplayBuilderItemList::checkInstanceId((string) $instance->id());
511
512    if (!$parts) {
 
516    if ($parts['entity_type_id'] !== $this->getTargetEntityTypeId()) {
 
520    if ($parts['field_name'] !== $this->getDisplayBuilderOverrideField()) {
 
521      return FALSE;
509  protected function isOverrideOfCurrentDisplay(InstanceInterface $instance): bool {
510    $parts = DisplayBuilderItemList::checkInstanceId((string) $instance->id());
511
512    if (!$parts) {
 
516    if ($parts['entity_type_id'] !== $this->getTargetEntityTypeId()) {
 
520    if ($parts['field_name'] !== $this->getDisplayBuilderOverrideField()) {
 
524    return TRUE;
EntityViewDisplayTrait->loadDisplayBuilder
579  private function loadDisplayBuilder(string $display_builder_id): ?ProfileInterface {
580    if (empty($display_builder_id)) {
 
581      return NULL;
579  private function loadDisplayBuilder(string $display_builder_id): ?ProfileInterface {
580    if (empty($display_builder_id)) {
 
583    $storage = $this->entityTypeManager->getStorage('display_builder_profile');
584
585    /** @var \Drupal\display_builder\ProfileInterface $display_builder */
586    $display_builder = $storage->load($display_builder_id);
587
588    return $display_builder;
EntityViewDisplayTrait->onDependencyRemoval
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
 
106      return TRUE;
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
 
109    $contexts = $instance->getContexts();
110
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
 
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
 
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
 
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
122      }
123    }
124
125    return $changed;
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
 
109    $contexts = $instance->getContexts();
110
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
 
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
 
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
122      }
123    }
124
125    return $changed;
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
 
109    $contexts = $instance->getContexts();
110
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
122      }
123    }
124
125    return $changed;
96  public function onDependencyRemoval(array $dependencies): bool {
97    $changed = parent::onDependencyRemoval($dependencies);
98
99    // Loop through all sources and determine if the removed dependencies are
100    // used by their plugins.
101    /** @var \Drupal\display_builder\InstanceInterface $instance */
102    $instance = $this->getInstance();
103
104    // @todo not working when content entity type is deleted.
105    if (!$instance) {
 
109    $contexts = $instance->getContexts();
110
111    foreach ($this->getSources() as $source_data) {
 
111    foreach ($this->getSources() as $source_data) {
112      /** @var \Drupal\ui_patterns\SourceInterface $source */
113      $source = $this->sourcePluginManager->getSource('', [], $source_data, $contexts);
114      $source_dependencies = $source->calculateDependencies();
115      $source_removed_dependencies = $this->getPluginRemovedDependencies($source_dependencies, $dependencies);
116
117      if ($source_removed_dependencies) {
118        // @todo Allow the plugins to react to their dependency removal in
119        // https://www.drupal.org/project/drupal/issues/2579743.
120        // $this->removeSource($delta);
121        $changed = TRUE;
122      }
123    }
124
125    return $changed;
EntityViewDisplayTrait->postSave
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
426          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
430          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
413        $instance->setProfile($profile_id);
414        $instance->save();
415      }
416    }
417
418    // Do also overrides.
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
426          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
430          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
406      $this->initInstanceIfMissing();
407
408      // Save the profile in the instance if changed.
409      $instance = $this->getInstance();
410      $profile_id = (string) $profile->id();
411
412      if ($instance->getProfile()->id() !== $profile_id) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
426          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
430          continue;
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
 
429        if ($override->getProfile()->id() === $profile_id) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
420      $profile_id = (string) $profile->id();
421      $storage = $this->entityTypeManager->getStorage('display_builder_instance');
422
423      foreach ($storage->loadMultiple() as $override) {
 
423      foreach ($storage->loadMultiple() as $override) {
424        /** @var \Drupal\display_builder\InstanceInterface $override */
425        if (!$this->isOverrideOfCurrentDisplay($override)) {
426          continue;
427        }
428
429        if ($override->getProfile()->id() === $profile_id) {
430          continue;
431        }
432        $override->setProfile($profile_id);
433        $override->save();
434      }
435    }
436
437    parent::postSave($storage, $update);
 
437    parent::postSave($storage, $update);
438  }
404  public function postSave(EntityStorageInterface $storage, $update = TRUE): void {
405    if ($profile = $this->getProfile()) {
 
419    if ($profile = $this->getDisplayBuilderOverrideProfile()) {
 
437    parent::postSave($storage, $update);
438  }
EntityViewDisplayTrait->saveSources
389    $data = $this->getInstance()->getCurrentState();
390    $this->setThirdPartySetting('display_builder', ConfigFormBuilderInterface::SOURCES_PROPERTY, $data);
391    $this->save();
392  }