function FileReferenceResolver::getReferences

Retrieves a list of references to a file.

Parameters

\Drupal\file\FileInterface $file: A file entity.

Return value

\Generator<int, \Drupal\file\FileReferenceUsage> This yields FileReferenceUsage objects.

Related topics

File

core/modules/file/src/FileReferenceResolver.php, line 60

Class

FileReferenceResolver
Retrieves file references.

Namespace

Drupal\file

Code

public function getReferences(FileInterface $file) : \Generator {
  $cid = 'file_references:' . $file->id();
  $cache = $this->memoryCache
    ->get($cid);
  if ($cache) {
    return yield from $cache->data;
  }
  $references = [];
  $cacheability_metadata = new CacheableMetadata();
  $cacheability_metadata->addCacheTags([
    'file_references',
  ]);
  $cacheability_metadata->addCacheableDependency($file);
  $revision_reference_count = [];
  // Loop over all usages registered by the file module.
  $usages_by_file_module = $this->fileUsage
    ->listUsage($file)['file'] ?? [];
  foreach ($usages_by_file_module as $entity_type_id => $entity_ids) {
    $entity_type = $this->entityTypeManager
      ->getDefinition($entity_type_id);
    $storage = $this->entityTypeManager
      ->getStorage($entity_type_id);
    $entities = $storage->loadMultiple(array_keys($entity_ids));
    $revision_reference_count[$entity_type_id] = 0;
    /** @var \Drupal\Core\Entity\FieldableEntityInterface[] $entities */
    foreach ($entities as $entity) {
      $cacheability_metadata->addCacheableDependency($entity);
      // If there are no file reference fields then this is a stale reference
      // ignore it.
      $file_reference_fields = $this->getFileReferenceFields($entity);
      if (!$file_reference_fields) {
        continue;
      }
      $default_revision_match = FALSE;
      foreach ($file_reference_fields as $field_name => $field_column) {
        if ($this->isFileReferencedByField($entity, $file, $field_name, $field_column)) {
          $default_revision_match = TRUE;
          $references[] = new FileReferenceUsage($entity->getEntityTypeId(), $field_name, id: $entity->id());
        }
      }
      if (!$default_revision_match && $entity_type->isRevisionable() && $storage instanceof RevisionableStorageInterface) {
        // Only attempt to find a limited amount of revisions per entity type,
        // very few sites should hit this limit, if they do, they will
        // need to override this with a different, if possible optimized
        // implementation.
        if ($revision_reference_count[$entity_type_id] > static::REVISION_LOOKUP_LIMIT) {
          continue;
        }
        $revision_reference_count[$entity_type_id]++;
        // The file reference was not found in any field in the current
        // entity, it may be referenced in a non-default revision. At this
        // point, the possible fields are known, create a query that fetches
        // the most recent revision that references the given file in any of
        // those fields.
        $revision = $this->getReferencingRevision($entity, $file);
        if ($revision === NULL) {
          continue;
        }
        $cacheability_metadata->addCacheableDependency($revision);
        foreach ($this->getFileReferenceFields($entity) as $field_name => $field_column) {
          if ($this->isFileReferencedByField($revision, $file, $field_name, $field_column)) {
            $references[] = new FileReferenceUsage($revision->getEntityTypeId(), $field_name, revisionId: $revision->getRevisionId());
          }
        }
      }
    }
  }
  $this->memoryCache
    ->set($cid, $references, tags: $cacheability_metadata->getCacheTags());
  return yield from $references;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.