annotate core/lib/Drupal/Core/Entity/EntityDisplayBase.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Entity;
Chris@0 4
Chris@0 5 use Drupal\Core\Config\Entity\ConfigEntityBase;
Chris@0 6 use Drupal\Core\Config\Entity\ConfigEntityInterface;
Chris@0 7 use Drupal\Core\Field\FieldDefinitionInterface;
Chris@0 8 use Drupal\Core\Entity\Display\EntityDisplayInterface;
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Provides a common base class for entity view and form displays.
Chris@0 12 */
Chris@0 13 abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDisplayInterface {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * The 'mode' for runtime EntityDisplay objects used to render entities with
Chris@0 17 * arbitrary display options rather than a configured view mode or form mode.
Chris@0 18 *
Chris@0 19 * @todo Prevent creation of a mode with this ID
Chris@0 20 * https://www.drupal.org/node/2410727
Chris@0 21 */
Chris@0 22 const CUSTOM_MODE = '_custom';
Chris@0 23
Chris@0 24 /**
Chris@0 25 * Unique ID for the config entity.
Chris@0 26 *
Chris@0 27 * @var string
Chris@0 28 */
Chris@0 29 protected $id;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * Entity type to be displayed.
Chris@0 33 *
Chris@0 34 * @var string
Chris@0 35 */
Chris@0 36 protected $targetEntityType;
Chris@0 37
Chris@0 38 /**
Chris@0 39 * Bundle to be displayed.
Chris@0 40 *
Chris@0 41 * @var string
Chris@0 42 */
Chris@0 43 protected $bundle;
Chris@0 44
Chris@0 45 /**
Chris@0 46 * A list of field definitions eligible for configuration in this display.
Chris@0 47 *
Chris@0 48 * @var \Drupal\Core\Field\FieldDefinitionInterface[]
Chris@0 49 */
Chris@0 50 protected $fieldDefinitions;
Chris@0 51
Chris@0 52 /**
Chris@0 53 * View or form mode to be displayed.
Chris@0 54 *
Chris@0 55 * @var string
Chris@0 56 */
Chris@0 57 protected $mode = self::CUSTOM_MODE;
Chris@0 58
Chris@0 59 /**
Chris@0 60 * Whether this display is enabled or not. If the entity (form) display
Chris@0 61 * is disabled, we'll fall back to the 'default' display.
Chris@0 62 *
Chris@0 63 * @var bool
Chris@0 64 */
Chris@0 65 protected $status;
Chris@0 66
Chris@0 67 /**
Chris@0 68 * List of component display options, keyed by component name.
Chris@0 69 *
Chris@0 70 * @var array
Chris@0 71 */
Chris@0 72 protected $content = [];
Chris@0 73
Chris@0 74 /**
Chris@0 75 * List of components that are set to be hidden.
Chris@0 76 *
Chris@0 77 * @var array
Chris@0 78 */
Chris@0 79 protected $hidden = [];
Chris@0 80
Chris@0 81 /**
Chris@0 82 * The original view or form mode that was requested (case of view/form modes
Chris@0 83 * being configured to fall back to the 'default' display).
Chris@0 84 *
Chris@0 85 * @var string
Chris@0 86 */
Chris@0 87 protected $originalMode;
Chris@0 88
Chris@0 89 /**
Chris@0 90 * The plugin objects used for this display, keyed by field name.
Chris@0 91 *
Chris@0 92 * @var array
Chris@0 93 */
Chris@0 94 protected $plugins = [];
Chris@0 95
Chris@0 96 /**
Chris@0 97 * Context in which this entity will be used (e.g. 'view', 'form').
Chris@0 98 *
Chris@0 99 * @var string
Chris@0 100 */
Chris@0 101 protected $displayContext;
Chris@0 102
Chris@0 103 /**
Chris@0 104 * The plugin manager used by this entity type.
Chris@0 105 *
Chris@0 106 * @var \Drupal\Component\Plugin\PluginManagerBase
Chris@0 107 */
Chris@0 108 protected $pluginManager;
Chris@0 109
Chris@0 110 /**
Chris@0 111 * The renderer.
Chris@0 112 *
Chris@0 113 * @var \Drupal\Core\Render\RendererInterface
Chris@0 114 */
Chris@0 115 protected $renderer;
Chris@0 116
Chris@0 117 /**
Chris@0 118 * {@inheritdoc}
Chris@0 119 */
Chris@0 120 public function __construct(array $values, $entity_type) {
Chris@0 121 if (!isset($values['targetEntityType']) || !isset($values['bundle'])) {
Chris@0 122 throw new \InvalidArgumentException('Missing required properties for an EntityDisplay entity.');
Chris@0 123 }
Chris@0 124
Chris@0 125 if (!$this->entityTypeManager()->getDefinition($values['targetEntityType'])->entityClassImplements(FieldableEntityInterface::class)) {
Chris@0 126 throw new \InvalidArgumentException('EntityDisplay entities can only handle fieldable entity types.');
Chris@0 127 }
Chris@0 128
Chris@0 129 $this->renderer = \Drupal::service('renderer');
Chris@0 130
Chris@0 131 // A plugin manager and a context type needs to be set by extending classes.
Chris@0 132 if (!isset($this->pluginManager)) {
Chris@0 133 throw new \RuntimeException('Missing plugin manager.');
Chris@0 134 }
Chris@0 135 if (!isset($this->displayContext)) {
Chris@0 136 throw new \RuntimeException('Missing display context type.');
Chris@0 137 }
Chris@0 138
Chris@0 139 parent::__construct($values, $entity_type);
Chris@0 140
Chris@0 141 $this->originalMode = $this->mode;
Chris@0 142
Chris@0 143 $this->init();
Chris@0 144 }
Chris@0 145
Chris@0 146 /**
Chris@0 147 * Initializes the display.
Chris@0 148 *
Chris@0 149 * This fills in default options for components:
Chris@0 150 * - that are not explicitly known as either "visible" or "hidden" in the
Chris@0 151 * display,
Chris@0 152 * - or that are not supposed to be configurable.
Chris@0 153 */
Chris@0 154 protected function init() {
Chris@0 155 // Only populate defaults for "official" view modes and form modes.
Chris@0 156 if ($this->mode !== static::CUSTOM_MODE) {
Chris@0 157 $default_region = $this->getDefaultRegion();
Chris@0 158 // Fill in defaults for extra fields.
Chris@0 159 $context = $this->displayContext == 'view' ? 'display' : $this->displayContext;
Chris@0 160 $extra_fields = \Drupal::entityManager()->getExtraFields($this->targetEntityType, $this->bundle);
Chris@0 161 $extra_fields = isset($extra_fields[$context]) ? $extra_fields[$context] : [];
Chris@0 162 foreach ($extra_fields as $name => $definition) {
Chris@0 163 if (!isset($this->content[$name]) && !isset($this->hidden[$name])) {
Chris@0 164 // Extra fields are visible by default unless they explicitly say so.
Chris@0 165 if (!isset($definition['visible']) || $definition['visible'] == TRUE) {
Chris@17 166 $this->setComponent($name, [
Chris@17 167 'weight' => $definition['weight'],
Chris@17 168 ]);
Chris@0 169 }
Chris@0 170 else {
Chris@17 171 $this->removeComponent($name);
Chris@0 172 }
Chris@0 173 }
Chris@0 174 // Ensure extra fields have a 'region'.
Chris@0 175 if (isset($this->content[$name])) {
Chris@0 176 $this->content[$name] += ['region' => $default_region];
Chris@0 177 }
Chris@0 178 }
Chris@0 179
Chris@0 180 // Fill in defaults for fields.
Chris@0 181 $fields = $this->getFieldDefinitions();
Chris@0 182 foreach ($fields as $name => $definition) {
Chris@0 183 if (!$definition->isDisplayConfigurable($this->displayContext) || (!isset($this->content[$name]) && !isset($this->hidden[$name]))) {
Chris@0 184 $options = $definition->getDisplayOptions($this->displayContext);
Chris@0 185
Chris@0 186 // @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
Chris@0 187 if (!isset($options['region']) && !empty($options['type']) && $options['type'] === 'hidden') {
Chris@0 188 $options['region'] = 'hidden';
Chris@0 189 @trigger_error("Specifying 'type' => 'hidden' is deprecated, use 'region' => 'hidden' instead.", E_USER_DEPRECATED);
Chris@0 190 }
Chris@0 191
Chris@0 192 if (!empty($options['region']) && $options['region'] === 'hidden') {
Chris@14 193 $this->removeComponent($name);
Chris@0 194 }
Chris@0 195 elseif ($options) {
Chris@0 196 $options += ['region' => $default_region];
Chris@14 197 $this->setComponent($name, $options);
Chris@0 198 }
Chris@0 199 // Note: (base) fields that do not specify display options are not
Chris@0 200 // tracked in the display at all, in order to avoid cluttering the
Chris@0 201 // configuration that gets saved back.
Chris@0 202 }
Chris@0 203 }
Chris@0 204 }
Chris@0 205 }
Chris@0 206
Chris@0 207 /**
Chris@0 208 * {@inheritdoc}
Chris@0 209 */
Chris@0 210 public function getTargetEntityTypeId() {
Chris@0 211 return $this->targetEntityType;
Chris@0 212 }
Chris@0 213
Chris@0 214 /**
Chris@0 215 * {@inheritdoc}
Chris@0 216 */
Chris@0 217 public function getMode() {
Chris@0 218 return $this->get('mode');
Chris@0 219 }
Chris@0 220
Chris@0 221 /**
Chris@0 222 * {@inheritdoc}
Chris@0 223 */
Chris@0 224 public function getOriginalMode() {
Chris@0 225 return $this->get('originalMode');
Chris@0 226 }
Chris@0 227
Chris@0 228 /**
Chris@0 229 * {@inheritdoc}
Chris@0 230 */
Chris@0 231 public function getTargetBundle() {
Chris@0 232 return $this->bundle;
Chris@0 233 }
Chris@0 234
Chris@0 235 /**
Chris@0 236 * {@inheritdoc}
Chris@0 237 */
Chris@0 238 public function setTargetBundle($bundle) {
Chris@0 239 $this->set('bundle', $bundle);
Chris@0 240 return $this;
Chris@0 241 }
Chris@0 242
Chris@0 243 /**
Chris@0 244 * {@inheritdoc}
Chris@0 245 */
Chris@0 246 public function id() {
Chris@0 247 return $this->targetEntityType . '.' . $this->bundle . '.' . $this->mode;
Chris@0 248 }
Chris@0 249
Chris@0 250 /**
Chris@0 251 * {@inheritdoc}
Chris@0 252 */
Chris@14 253 public function preSave(EntityStorageInterface $storage) {
Chris@0 254 // Ensure that a region is set on each component.
Chris@0 255 foreach ($this->getComponents() as $name => $component) {
Chris@0 256 $this->handleHiddenType($name, $component);
Chris@0 257 // Ensure that a region is set.
Chris@0 258 if (isset($this->content[$name]) && !isset($component['region'])) {
Chris@0 259 // Directly set the component to bypass other changes in setComponent().
Chris@0 260 $this->content[$name]['region'] = $this->getDefaultRegion();
Chris@0 261 }
Chris@0 262 }
Chris@0 263
Chris@0 264 ksort($this->content);
Chris@0 265 ksort($this->hidden);
Chris@14 266 parent::preSave($storage);
Chris@0 267 }
Chris@0 268
Chris@0 269 /**
Chris@0 270 * Handles a component type of 'hidden'.
Chris@0 271 *
Chris@0 272 * @deprecated This method exists only for backwards compatibility.
Chris@0 273 *
Chris@0 274 * @todo Remove this in https://www.drupal.org/node/2799641.
Chris@0 275 *
Chris@0 276 * @param string $name
Chris@0 277 * The name of the component.
Chris@0 278 * @param array $component
Chris@0 279 * The component array.
Chris@0 280 */
Chris@0 281 protected function handleHiddenType($name, array $component) {
Chris@0 282 if (!isset($component['region']) && isset($component['type']) && $component['type'] === 'hidden') {
Chris@0 283 $this->removeComponent($name);
Chris@0 284 }
Chris@0 285 }
Chris@0 286
Chris@0 287 /**
Chris@0 288 * {@inheritdoc}
Chris@0 289 */
Chris@0 290 public function calculateDependencies() {
Chris@0 291 parent::calculateDependencies();
Chris@18 292 $target_entity_type = $this->entityTypeManager()->getDefinition($this->targetEntityType);
Chris@0 293
Chris@0 294 // Create dependency on the bundle.
Chris@0 295 $bundle_config_dependency = $target_entity_type->getBundleConfigDependency($this->bundle);
Chris@0 296 $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']);
Chris@0 297
Chris@0 298 // If field.module is enabled, add dependencies on 'field_config' entities
Chris@0 299 // for both displayed and hidden fields. We intentionally leave out base
Chris@0 300 // field overrides, since the field still exists without them.
Chris@0 301 if (\Drupal::moduleHandler()->moduleExists('field')) {
Chris@0 302 $components = $this->content + $this->hidden;
Chris@18 303 $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($this->targetEntityType, $this->bundle);
Chris@0 304 foreach (array_intersect_key($field_definitions, $components) as $field_name => $field_definition) {
Chris@0 305 if ($field_definition instanceof ConfigEntityInterface && $field_definition->getEntityTypeId() == 'field_config') {
Chris@0 306 $this->addDependency('config', $field_definition->getConfigDependencyName());
Chris@0 307 }
Chris@0 308 }
Chris@0 309 }
Chris@0 310
Chris@0 311 // Depend on configured modes.
Chris@0 312 if ($this->mode != 'default') {
Chris@18 313 $mode_entity = $this->entityTypeManager()->getStorage('entity_' . $this->displayContext . '_mode')->load($target_entity_type->id() . '.' . $this->mode);
Chris@0 314 $this->addDependency('config', $mode_entity->getConfigDependencyName());
Chris@0 315 }
Chris@0 316 return $this;
Chris@0 317 }
Chris@0 318
Chris@0 319 /**
Chris@0 320 * {@inheritdoc}
Chris@0 321 */
Chris@0 322 public function toArray() {
Chris@0 323 $properties = parent::toArray();
Chris@0 324 // Do not store options for fields whose display is not set to be
Chris@0 325 // configurable.
Chris@0 326 foreach ($this->getFieldDefinitions() as $field_name => $definition) {
Chris@0 327 if (!$definition->isDisplayConfigurable($this->displayContext)) {
Chris@0 328 unset($properties['content'][$field_name]);
Chris@0 329 unset($properties['hidden'][$field_name]);
Chris@0 330 }
Chris@0 331 }
Chris@0 332
Chris@0 333 return $properties;
Chris@0 334 }
Chris@0 335
Chris@0 336 /**
Chris@0 337 * {@inheritdoc}
Chris@0 338 */
Chris@0 339 public function createCopy($mode) {
Chris@0 340 $display = $this->createDuplicate();
Chris@0 341 $display->mode = $display->originalMode = $mode;
Chris@0 342 return $display;
Chris@0 343 }
Chris@0 344
Chris@0 345 /**
Chris@0 346 * {@inheritdoc}
Chris@0 347 */
Chris@0 348 public function getComponents() {
Chris@0 349 return $this->content;
Chris@0 350 }
Chris@0 351
Chris@0 352 /**
Chris@0 353 * {@inheritdoc}
Chris@0 354 */
Chris@0 355 public function getComponent($name) {
Chris@0 356 return isset($this->content[$name]) ? $this->content[$name] : NULL;
Chris@0 357 }
Chris@0 358
Chris@0 359 /**
Chris@0 360 * {@inheritdoc}
Chris@0 361 */
Chris@0 362 public function setComponent($name, array $options = []) {
Chris@0 363 // If no weight specified, make sure the field sinks at the bottom.
Chris@0 364 if (!isset($options['weight'])) {
Chris@0 365 $max = $this->getHighestWeight();
Chris@0 366 $options['weight'] = isset($max) ? $max + 1 : 0;
Chris@0 367 }
Chris@0 368
Chris@0 369 // For a field, fill in default options.
Chris@0 370 if ($field_definition = $this->getFieldDefinition($name)) {
Chris@0 371 $options = $this->pluginManager->prepareConfiguration($field_definition->getType(), $options);
Chris@0 372 }
Chris@0 373
Chris@0 374 // Ensure we always have an empty settings and array.
Chris@0 375 $options += ['settings' => [], 'third_party_settings' => []];
Chris@0 376
Chris@0 377 $this->content[$name] = $options;
Chris@0 378 unset($this->hidden[$name]);
Chris@0 379 unset($this->plugins[$name]);
Chris@0 380
Chris@0 381 return $this;
Chris@0 382 }
Chris@0 383
Chris@0 384 /**
Chris@0 385 * {@inheritdoc}
Chris@0 386 */
Chris@0 387 public function removeComponent($name) {
Chris@0 388 $this->hidden[$name] = TRUE;
Chris@0 389 unset($this->content[$name]);
Chris@0 390 unset($this->plugins[$name]);
Chris@0 391
Chris@0 392 return $this;
Chris@0 393 }
Chris@0 394
Chris@0 395 /**
Chris@0 396 * {@inheritdoc}
Chris@0 397 */
Chris@0 398 public function getHighestWeight() {
Chris@0 399 $weights = [];
Chris@0 400
Chris@0 401 // Collect weights for the components in the display.
Chris@0 402 foreach ($this->content as $options) {
Chris@0 403 if (isset($options['weight'])) {
Chris@0 404 $weights[] = $options['weight'];
Chris@0 405 }
Chris@0 406 }
Chris@0 407
Chris@0 408 // Let other modules feedback about their own additions.
Chris@0 409 $weights = array_merge($weights, \Drupal::moduleHandler()->invokeAll('field_info_max_weight', [$this->targetEntityType, $this->bundle, $this->displayContext, $this->mode]));
Chris@0 410
Chris@0 411 return $weights ? max($weights) : NULL;
Chris@0 412 }
Chris@0 413
Chris@0 414 /**
Chris@0 415 * Gets the field definition of a field.
Chris@0 416 */
Chris@0 417 protected function getFieldDefinition($field_name) {
Chris@0 418 $definitions = $this->getFieldDefinitions();
Chris@0 419 return isset($definitions[$field_name]) ? $definitions[$field_name] : NULL;
Chris@0 420 }
Chris@0 421
Chris@0 422 /**
Chris@0 423 * Gets the definitions of the fields that are candidate for display.
Chris@0 424 */
Chris@0 425 protected function getFieldDefinitions() {
Chris@0 426 if (!isset($this->fieldDefinitions)) {
Chris@0 427 $definitions = \Drupal::entityManager()->getFieldDefinitions($this->targetEntityType, $this->bundle);
Chris@0 428 // For "official" view modes and form modes, ignore fields whose
Chris@0 429 // definition states they should not be displayed.
Chris@0 430 if ($this->mode !== static::CUSTOM_MODE) {
Chris@0 431 $definitions = array_filter($definitions, [$this, 'fieldHasDisplayOptions']);
Chris@0 432 }
Chris@0 433 $this->fieldDefinitions = $definitions;
Chris@0 434 }
Chris@0 435
Chris@0 436 return $this->fieldDefinitions;
Chris@0 437 }
Chris@0 438
Chris@0 439 /**
Chris@0 440 * Determines if a field has options for a given display.
Chris@0 441 *
Chris@12 442 * @param \Drupal\Core\Field\FieldDefinitionInterface $definition
Chris@0 443 * A field definition.
Chris@0 444 * @return array|null
Chris@0 445 */
Chris@0 446 private function fieldHasDisplayOptions(FieldDefinitionInterface $definition) {
Chris@0 447 // The display only cares about fields that specify display options.
Chris@0 448 // Discard base fields that are not rendered through formatters / widgets.
Chris@0 449 return $definition->getDisplayOptions($this->displayContext);
Chris@0 450 }
Chris@0 451
Chris@0 452 /**
Chris@0 453 * {@inheritdoc}
Chris@0 454 */
Chris@0 455 public function onDependencyRemoval(array $dependencies) {
Chris@0 456 $changed = parent::onDependencyRemoval($dependencies);
Chris@0 457 foreach ($dependencies['config'] as $entity) {
Chris@0 458 if ($entity->getEntityTypeId() == 'field_config') {
Chris@0 459 // Remove components for fields that are being deleted.
Chris@0 460 $this->removeComponent($entity->getName());
Chris@0 461 unset($this->hidden[$entity->getName()]);
Chris@0 462 $changed = TRUE;
Chris@0 463 }
Chris@0 464 }
Chris@0 465 foreach ($this->getComponents() as $name => $component) {
Chris@0 466 if ($renderer = $this->getRenderer($name)) {
Chris@0 467 if (in_array($renderer->getPluginDefinition()['provider'], $dependencies['module'])) {
Chris@0 468 // Revert to the defaults if the plugin that supplies the widget or
Chris@0 469 // formatter depends on a module that is being uninstalled.
Chris@0 470 $this->setComponent($name);
Chris@0 471 $changed = TRUE;
Chris@0 472 }
Chris@0 473
Chris@0 474 // Give this component the opportunity to react on dependency removal.
Chris@0 475 $component_removed_dependencies = $this->getPluginRemovedDependencies($renderer->calculateDependencies(), $dependencies);
Chris@0 476 if ($component_removed_dependencies) {
Chris@0 477 if ($renderer->onDependencyRemoval($component_removed_dependencies)) {
Chris@0 478 // Update component settings to reflect changes.
Chris@0 479 $component['settings'] = $renderer->getSettings();
Chris@0 480 $component['third_party_settings'] = [];
Chris@0 481 foreach ($renderer->getThirdPartyProviders() as $module) {
Chris@0 482 $component['third_party_settings'][$module] = $renderer->getThirdPartySettings($module);
Chris@0 483 }
Chris@0 484 $this->setComponent($name, $component);
Chris@0 485 $changed = TRUE;
Chris@0 486 }
Chris@0 487 // If there are unresolved deleted dependencies left, disable this
Chris@0 488 // component to avoid the removal of the entire display entity.
Chris@0 489 if ($this->getPluginRemovedDependencies($renderer->calculateDependencies(), $dependencies)) {
Chris@0 490 $this->removeComponent($name);
Chris@0 491 $arguments = [
Chris@0 492 '@display' => (string) $this->getEntityType()->getLabel(),
Chris@0 493 '@id' => $this->id(),
Chris@0 494 '@name' => $name,
Chris@0 495 ];
Chris@0 496 $this->getLogger()->warning("@display '@id': Component '@name' was disabled because its settings depend on removed dependencies.", $arguments);
Chris@0 497 $changed = TRUE;
Chris@0 498 }
Chris@0 499 }
Chris@0 500 }
Chris@0 501 }
Chris@0 502 return $changed;
Chris@0 503 }
Chris@0 504
Chris@0 505 /**
Chris@0 506 * Returns the plugin dependencies being removed.
Chris@0 507 *
Chris@0 508 * The function recursively computes the intersection between all plugin
Chris@0 509 * dependencies and all removed dependencies.
Chris@0 510 *
Chris@0 511 * Note: The two arguments do not have the same structure.
Chris@0 512 *
Chris@0 513 * @param array[] $plugin_dependencies
Chris@0 514 * A list of dependencies having the same structure as the return value of
Chris@0 515 * ConfigEntityInterface::calculateDependencies().
Chris@0 516 * @param array[] $removed_dependencies
Chris@0 517 * A list of dependencies having the same structure as the input argument of
Chris@0 518 * ConfigEntityInterface::onDependencyRemoval().
Chris@0 519 *
Chris@0 520 * @return array
Chris@0 521 * A recursively computed intersection.
Chris@0 522 *
Chris@0 523 * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies()
Chris@0 524 * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::onDependencyRemoval()
Chris@0 525 */
Chris@0 526 protected function getPluginRemovedDependencies(array $plugin_dependencies, array $removed_dependencies) {
Chris@0 527 $intersect = [];
Chris@0 528 foreach ($plugin_dependencies as $type => $dependencies) {
Chris@0 529 if ($removed_dependencies[$type]) {
Chris@0 530 // Config and content entities have the dependency names as keys while
Chris@0 531 // module and theme dependencies are indexed arrays of dependency names.
Chris@0 532 // @see \Drupal\Core\Config\ConfigManager::callOnDependencyRemoval()
Chris@0 533 if (in_array($type, ['config', 'content'])) {
Chris@0 534 $removed = array_intersect_key($removed_dependencies[$type], array_flip($dependencies));
Chris@0 535 }
Chris@0 536 else {
Chris@0 537 $removed = array_values(array_intersect($removed_dependencies[$type], $dependencies));
Chris@0 538 }
Chris@0 539 if ($removed) {
Chris@0 540 $intersect[$type] = $removed;
Chris@0 541 }
Chris@0 542 }
Chris@0 543 }
Chris@0 544 return $intersect;
Chris@0 545 }
Chris@0 546
Chris@0 547 /**
Chris@0 548 * Gets the default region.
Chris@0 549 *
Chris@0 550 * @return string
Chris@0 551 * The default region for this display.
Chris@0 552 */
Chris@0 553 protected function getDefaultRegion() {
Chris@0 554 return 'content';
Chris@0 555 }
Chris@0 556
Chris@0 557 /**
Chris@0 558 * {@inheritdoc}
Chris@0 559 */
Chris@0 560 public function __sleep() {
Chris@0 561 // Only store the definition, not external objects or derived data.
Chris@0 562 $keys = array_keys($this->toArray());
Chris@0 563 // In addition, we need to keep the entity type and the "is new" status.
Chris@0 564 $keys[] = 'entityTypeId';
Chris@0 565 $keys[] = 'enforceIsNew';
Chris@0 566 // Keep track of the serialized keys, to avoid calling toArray() again in
Chris@0 567 // __wakeup(). Because of the way __sleep() works, the data has to be
Chris@0 568 // present in the object to be included in the serialized values.
Chris@0 569 $keys[] = '_serializedKeys';
Chris@0 570 $this->_serializedKeys = $keys;
Chris@0 571 return $keys;
Chris@0 572 }
Chris@0 573
Chris@0 574 /**
Chris@0 575 * {@inheritdoc}
Chris@0 576 */
Chris@0 577 public function __wakeup() {
Chris@0 578 // Determine what were the properties from toArray() that were saved in
Chris@0 579 // __sleep().
Chris@0 580 $keys = $this->_serializedKeys;
Chris@0 581 unset($this->_serializedKeys);
Chris@0 582 $values = array_intersect_key(get_object_vars($this), array_flip($keys));
Chris@0 583 // Run those values through the __construct(), as if they came from a
Chris@0 584 // regular entity load.
Chris@0 585 $this->__construct($values, $this->entityTypeId);
Chris@0 586 }
Chris@0 587
Chris@0 588 /**
Chris@0 589 * Provides the 'system' channel logger service.
Chris@0 590 *
Chris@0 591 * @return \Psr\Log\LoggerInterface
Chris@0 592 * The 'system' channel logger.
Chris@0 593 */
Chris@0 594 protected function getLogger() {
Chris@0 595 return \Drupal::logger('system');
Chris@0 596 }
Chris@0 597
Chris@0 598 }