You are here

protected function EntityTraversal::doTraversalRecursive in General Data Protection Regulation 3.0.x

Same name and namespace in other branches
  1. 8.2 modules/gdpr_fields/src/EntityTraversal.php \Drupal\gdpr_fields\EntityTraversal::doTraversalRecursive()
  2. 8 modules/gdpr_fields/src/EntityTraversal.php \Drupal\gdpr_fields\EntityTraversal::doTraversalRecursive()

Traverses the entity relationship tree.

Calls the handleEntity method for every entity found.

Parameters

\Drupal\Core\Entity\EntityInterface $entity: The root entity to traverse.

\Drupal\gdpr_fields\Entity\GdprField|null $parent_config: (Optional) The parent config field settings.

int|null $row_id: (Optional) The row to place the information in.

Throws

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

\Drupal\Component\Plugin\Exception\PluginNotFoundException

2 calls to EntityTraversal::doTraversalRecursive()
EntityTraversal::traverseEntity in modules/gdpr_fields/src/EntityTraversal.php
Traverses the entity relationship tree.
RightToBeForgottenEntityTraversal::traverseEntity in modules/gdpr_tasks/src/Traversal/RightToBeForgottenEntityTraversal.php
Traverses the entity relationship tree.

File

modules/gdpr_fields/src/EntityTraversal.php, line 150

Class

EntityTraversal
Base class for traversing entities.

Namespace

Drupal\gdpr_fields

Code

protected function doTraversalRecursive(EntityInterface $entity, GdprField $parent_config = NULL, $row_id = NULL) {

  // If the entity is not fieldable, don't continue.
  if (!$entity instanceof FieldableEntityInterface) {
    return;
  }
  $entity_type = $entity
    ->getEntityTypeId();

  // Explicitly make sure we don't traverse any links to excluded entities.
  $definition = $this->entityTypeManager
    ->getDefinition($entity_type);
  if ($definition
    ->get('gdpr_entity_traversal_exclude')) {
    return;
  }

  // Check for infinite loop.
  if (isset($this->entities[$entity_type][$entity
    ->id()])) {
    return;
  }
  if (!isset($row_id)) {
    $row_id = $entity
      ->id();
  }

  // Store the entity in progress to make sure we don't get stuck
  // in an infinite loop by processing the same entity again.
  $this->entities[$entity_type][$entity
    ->id()] = $entity;

  // GDPR config for this entity.

  /** @var \Drupal\gdpr_fields\Entity\GdprFieldConfigEntity $config */
  $config = $this->configStorage
    ->load($entity_type);
  if ($config === NULL) {
    return;
  }

  // Let subclasses do with the entity. They will add to the $results array.
  $this
    ->processEntity($entity, $config, $row_id, $parent_config);

  // Find relationships from this entity.
  $fields = $config
    ->getFieldsForBundle($entity
    ->bundle());
  foreach ($fields as $field_config) {

    // Only include fields explicitly enabled for entity traversal.
    if ($field_config
      ->includeRelatedEntities() && $entity
      ->hasField($field_config->name)) {

      // If there is no value, we don't need to proceed.
      $referenced_entities = $entity
        ->get($field_config->name)
        ->referencedEntities();
      if (empty($referenced_entities)) {
        continue;
      }
      $single_cardinality = $entity
        ->get($field_config->name)
        ->getFieldDefinition()
        ->getFieldStorageDefinition()
        ->getCardinality() === 1;
      $passed_row_id = $single_cardinality ? $row_id : NULL;

      // Loop through each child entity and traverse their relationships too.
      foreach ($referenced_entities as $child_entity) {
        $this
          ->doTraversalRecursive($child_entity, $field_config, $passed_row_id);
      }
    }
  }

  // Now we want to look up any reverse relationships that have been marked
  // as owner.
  foreach ($this
    ->getAllReverseRelationships() as $relationship) {
    if ($relationship['target_type'] === $entity_type) {

      // Load all instances of this entity where the field value is the same
      // as our entity's ID.
      $storage = $this->entityTypeManager
        ->getStorage($relationship['entity_type']);
      $ids = $storage
        ->getQuery()
        ->condition($relationship['field'], $entity
        ->id())
        ->execute();
      foreach ($storage
        ->loadMultiple($ids) as $related_entity) {
        $this
          ->doTraversalRecursive($related_entity, $relationship['config']);
      }
    }
  }
}