Purges a batch of deleted Field API data, instances, or fields.
This function will purge deleted field data in batches. The batch size is defined as an argument to the function, and once each batch is finished, it continues with the next batch until all have completed. If a deleted field instance with no remaining data records is found, the instance itself will be purged. If a deleted field with no remaining field instances is found, the field itself will be purged.
$batch_size: The maximum number of field data records to purge before returning.
function field_purge_batch($batch_size) {
// Retrieve all deleted field instances. We cannot use field_info_instances()
// because that function does not return deleted instances.
$instances = field_read_instances(array(
'deleted' => TRUE,
), array(
'include_deleted' => TRUE,
));
$factory = Drupal::service('entity.query');
$info = entity_get_info();
foreach ($instances as $instance) {
$entity_type = $instance['entity_type'];
// EntityFieldQuery currently fails on conditions on comment bundle.
// Remove when http://drupal.org/node/731724 is fixed.
if ($entity_type == 'comment') {
continue;
}
$ids = (object) array(
'entity_type' => $entity_type,
'bundle' => $instance['bundle'],
);
// field_purge_data() will need the field array.
$field = field_info_field_by_id($instance['field_id']);
// Retrieve some entities.
$query = $factory
->get($entity_type)
->condition('id:' . $field['uuid'] . '.deleted', 1)
->range(0, $batch_size);
// If there's no bundle key, all results will have the same bundle.
if (!empty($info[$entity_type]['entity_keys']['bundle'])) {
$query
->condition($info[$entity_type]['entity_keys']['bundle'], $ids->bundle);
}
$results = $query
->execute();
if ($results) {
$entities = array();
foreach ($results as $revision_id => $entity_id) {
// This might not be the revision id if the entity type does not support
// revisions but _field_create_entity_from_ids() checks that and
// disregards this value so there is no harm setting it.
$ids->revision_id = $revision_id;
$ids->entity_id = $entity_id;
$entities[$entity_id] = _field_create_entity_from_ids($ids);
}
field_attach_load($entity_type, $entities, FIELD_LOAD_CURRENT, array(
'field_id' => $field['uuid'],
'deleted' => 1,
));
foreach ($entities as $entity) {
// Purge the data for the entity.
field_purge_data($entity, $field, $instance);
}
}
else {
// No field data remains for the instance, so we can remove it.
field_purge_instance($instance);
}
}
// Retrieve all deleted fields. Any that have no instances can be purged.
$deleted_fields = Drupal::state()
->get('field.field.deleted') ?: array();
foreach ($deleted_fields as $field) {
$field = new Field($field);
$instances = field_read_instances(array(
'field_id' => $field['uuid'],
), array(
'include_deleted' => 1,
));
if (empty($instances)) {
field_purge_field($field);
}
}
}