field_attach_load
- Versions
- 7
field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT, $options = array())
Load all fields for the most current version of each of a set of objects of a single object type.
Parameters
$obj_type The type of $object; e.g. 'node' or 'user'.
$objects An array of objects for which to load fields, keyed by object id. Each object needs to have its 'bundle', 'id' and (if applicable) 'revision' keys filled.
$age FIELD_LOAD_CURRENT to load the most recent revision for all fields, or FIELD_LOAD_REVISION to load the version indicated by each object. Defaults to FIELD_LOAD_CURRENT; use field_attach_load_revision() instead of passing FIELD_LOAD_REVISION.
$options An associative array of additional options, with the following keys:
- 'field_id': The field id that should be loaded, instead of loading all fields, for each object. Note that returned objects may contain data for other fields, for example if they are read from a cache.
- 'deleted': If TRUE, the function will operate on deleted fields as well as non-deleted fields. If unset or FALSE, only non-deleted fields are operated on.
Return value
Loaded field values are added to $objects.
Related topics
Code
modules/field/field.attach.inc, line 530
<?php
function field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT, $options = array()) {
$load_current = $age == FIELD_LOAD_CURRENT;
// Merge default options.
$default_options = array(
'deleted' => FALSE,
);
$options += $default_options;
$info = entity_get_info($obj_type);
// Only the most current revision of non-deleted fields for
// cacheable fieldable types can be cached.
$cache_read = $load_current && $info['cacheable'] && empty($options['deleted']);
// In addition, do not write to the cache when loading a single field.
$cache_write = $cache_read && !isset($options['field_id']);
if (empty($objects)) {
return;
}
// Assume all objects will need to be queried. Objects found in the cache
// will be removed from the list.
$queried_objects = $objects;
// Fetch available objects from cache, if applicable.
if ($cache_read) {
// Build the list of cache entries to retrieve.
$cids = array();
foreach ($objects as $id => $object) {
$cids[] = "field:$obj_type:$id";
}
$cache = cache_get_multiple($cids, 'cache_field');
// Put the cached field values back into the objects and remove them from
// the list of objects to query.
foreach ($objects as $id => $object) {
$cid = "field:$obj_type:$id";
if (isset($cache[$cid])) {
unset($queried_objects[$id]);
foreach ($cache[$cid]->data as $field_name => $values) {
$object->$field_name = $values;
}
}
}
}
// Fetch other objects from their storage location.
if ($queried_objects) {
// The invoke order is:
// - hook_field_storage_pre_load()
// - storage backend's hook_field_storage_load()
// - field-type module's hook_field_load()
// - hook_field_attach_load()
// Invoke hook_field_storage_pre_load(): let any module load field
// data before the storage engine, accumulating along the way.
$skip_fields = array();
foreach (module_implements('field_storage_pre_load') as $module) {
$function = $module . '_field_storage_pre_load';
$function($obj_type, $queried_objects, $age, $skip_fields, $options);
}
// Collect the storage backends used by the remaining fields in the objects.
$storages = array();
foreach ($queried_objects as $obj) {
list($id, $vid, $bundle) = entity_extract_ids($obj_type, $obj);
if ($options['deleted']) {
$instances = field_read_instances(array('object_type' => $obj_type, 'bundle' => $bundle), array('include_deleted' => $options['deleted']));
}
else {
$instances = field_info_instances($obj_type, $bundle);
}
foreach ($instances as $instance) {
if (!isset($options['field_id']) || $options['field_id'] == $instance['field_id']) {
$field_name = $instance['field_name'];
$field_id = $instance['field_id'];
// Make sure all fields are present at least as empty arrays.
if (!isset($queried_objects[$id]->{$field_name})) {
$queried_objects[$id]->{$field_name} = array();
}
// Collect the storage backend if the field has not been loaded yet.
if (!isset($skip_fields[$field_id])) {
$field = field_info_field_by_id($field_id);
$storages[$field['storage']['type']][$field_id][] = $load_current ? $id : $vid;
}
}
}
}
// Invoke hook_field_storage_load() on the relevant storage backends.
foreach ($storages as $storage => $fields) {
$storage_info = field_info_storage_types($storage);
module_invoke($storage_info['module'], 'field_storage_load', $obj_type, $queried_objects, $age, $fields, $options);
}
// Invoke field-type module's hook_field_load().
_field_invoke_multiple('load', $obj_type, $queried_objects, $age, $options);
// Invoke hook_field_attach_load(): let other modules act on loading the
// object.
module_invoke_all('field_attach_load', $obj_type, $queried_objects, $age, $options);
// Build cache data.
if ($cache_write) {
foreach ($queried_objects as $id => $object) {
$data = array();
list($id, $vid, $bundle) = entity_extract_ids($obj_type, $object);
$instances = field_info_instances($obj_type, $bundle);
foreach ($instances as $instance) {
$data[$instance['field_name']] = $queried_objects[$id]->{$instance['field_name']};
}
$cid = "field:$obj_type:$id";
cache_set($cid, $data, 'cache_field');
}
}
}
}
?>Login or register to post comments 