Retrieves a list of references to a file.
Drupal\file\File $file: A file entity.
$field: (optional) A field array to be used for this check. If given, limits the reference check to the given field.
$age: (optional) A constant that specifies which references to count. Use FIELD_LOAD_REVISION to retrieve all references within all revisions or FIELD_LOAD_CURRENT to retrieve references only in the current revisions.
$field_type: (optional) The name of a field type. If given, limits the reference check to fields of the given type. If both $field and $field_type is given but $field is not the same type as $field_type, an empty array will be returned.
A multidimensional array. The keys are field_name, entity_type, entity_id and the value is an entity referencing this file.
function file_get_file_references(File $file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') {
$references =& drupal_static(__FUNCTION__, array());
$field_columns =& drupal_static(__FUNCTION__ . ':field_columns', array());
// Fill the static cache, disregard $field and $field_type for now.
if (!isset($references[$file->fid][$age])) {
$references[$file->fid][$age] = array();
$usage_list = file_usage()
->listUsage($file);
$file_usage_list = isset($usage_list['file']) ? $usage_list['file'] : array();
foreach ($file_usage_list as $entity_type => $entity_ids) {
$entity_info = entity_get_info($entity_type);
// The usage table contains usage of every revision. If we are looking
// for every revision or the entity does not support revisions then
// every usage is already a match.
$match_entity_type = $age == FIELD_LOAD_REVISION || !isset($entity_info['entity_keys']['revision']);
$entities = entity_load_multiple($entity_type, $entity_ids);
foreach ($entities as $entity) {
$bundle = $entity
->bundle();
// We need to find file fields for this entity type and bundle.
if (!isset($file_fields[$entity_type][$bundle])) {
$file_fields[$entity_type][$bundle] = array();
// This contains the possible field names.
$instances = field_info_instances($entity_type, $bundle);
foreach ($instances as $field_name => $instance) {
$current_field = field_info_field($field_name);
// If this is the first time this field type is seen, check
// whether it references files.
if (!isset($field_columns[$current_field['type']])) {
$field_columns[$current_field['type']] = file_field_find_file_reference_column($current_field);
}
// If the field type does reference files then record it.
if ($field_columns[$current_field['type']]) {
$file_fields[$entity_type][$bundle][$field_name] = $field_columns[$current_field['type']];
}
}
}
foreach ($file_fields[$entity_type][$bundle] as $field_name => $field_column) {
$match = $match_entity_type;
// If we didn't match yet then iterate over the field items to find
// the referenced file. This will fail if the usage checked is in a
// non-current revision because field items are from the current
// revision.
if (!$match && ($field_items = field_get_items($entity, $field_name))) {
foreach ($field_items as $item) {
if ($file->fid == $item[$field_column]) {
$match = TRUE;
break;
}
}
}
if ($match) {
$references[$file->fid][$age][$field_name][$entity_type][$entity
->id()] = $entity;
}
}
}
}
}
$return = $references[$file->fid][$age];
// Filter the static cache down to the requested entries. The usual static
// cache is very small so this will be very fast.
if ($field || $field_type) {
foreach ($return as $field_name => $data) {
$current_field = field_info_field($field_name);
if ($field_type && $current_field['type'] != $field_type || $field && $field['id'] != $current_field['id']) {
unset($return[$field_name]);
}
}
}
return $return;
}