2009-02-05 03:42:58 +00:00
|
|
|
<?php
|
|
|
|
|
2009-02-08 21:22:59 +00:00
|
|
|
/**
|
|
|
|
* @file
|
2009-02-10 03:16:15 +00:00
|
|
|
* Field CRUD API, handling field and field instance creation and deletion.
|
2009-02-08 21:22:59 +00:00
|
|
|
*/
|
|
|
|
|
2013-01-07 11:22:28 +00:00
|
|
|
use Drupal\Core\Entity\EntityInterface;
|
2013-04-13 17:06:40 +00:00
|
|
|
use Drupal\field\Plugin\Core\Entity\Field;
|
|
|
|
use Drupal\field\Plugin\Core\Entity\FieldInstance;
|
2012-05-07 02:56:49 +00:00
|
|
|
use Drupal\field\FieldException;
|
|
|
|
|
2009-02-05 03:42:58 +00:00
|
|
|
/**
|
|
|
|
* @defgroup field_crud Field CRUD API
|
|
|
|
* @{
|
2012-09-27 15:44:17 +00:00
|
|
|
* Creates, updates, and deletes Field API fields, bundles, and instances.
|
2009-02-05 03:42:58 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* Modules use this API, often in hook_install(), to create custom data
|
|
|
|
* structures. UI modules will use it to create a user interface.
|
2009-02-05 03:42:58 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* The Field CRUD API uses @link field Field API data structures @endlink.
|
2011-11-30 02:42:42 +00:00
|
|
|
*
|
2011-12-22 09:32:53 +00:00
|
|
|
* See @link field Field API @endlink for information about the other parts of
|
|
|
|
* the Field API.
|
2009-02-05 03:42:58 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Reads a single field record directly from the database.
|
|
|
|
*
|
|
|
|
* Generally, you should use the field_info_field() instead.
|
2009-02-05 03:42:58 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* This function will not return deleted fields. Use field_read_fields() instead
|
|
|
|
* for this purpose.
|
2009-05-28 10:05:32 +00:00
|
|
|
*
|
2009-02-05 03:42:58 +00:00
|
|
|
* @param $field_name
|
|
|
|
* The field name to read.
|
|
|
|
* @param array $include_additional
|
2012-09-27 15:44:17 +00:00
|
|
|
* The default behavior of this function is to not return a field that is
|
|
|
|
* inactive. Setting $include_additional['include_inactive'] to TRUE will
|
|
|
|
* override this behavior.
|
|
|
|
*
|
2009-02-05 03:42:58 +00:00
|
|
|
* @return
|
2010-01-03 23:31:17 +00:00
|
|
|
* A field definition array, or FALSE.
|
2009-02-05 03:42:58 +00:00
|
|
|
*/
|
|
|
|
function field_read_field($field_name, $include_additional = array()) {
|
|
|
|
$fields = field_read_fields(array('field_name' => $field_name), $include_additional);
|
|
|
|
return $fields ? current($fields) : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Reads in fields that match an array of conditions.
|
2009-02-05 03:42:58 +00:00
|
|
|
*
|
2013-04-13 17:06:40 +00:00
|
|
|
* @param array $conditions
|
|
|
|
* An array of conditions to match against. Keys are names of properties found
|
|
|
|
* in field configuration files, and values are conditions to match.
|
2009-02-05 03:42:58 +00:00
|
|
|
* @param array $include_additional
|
2012-09-27 15:44:17 +00:00
|
|
|
* The default behavior of this function is to not return fields that are
|
|
|
|
* inactive or have been deleted. Setting
|
2009-02-05 03:42:58 +00:00
|
|
|
* $include_additional['include_inactive'] or
|
2012-09-27 15:44:17 +00:00
|
|
|
* $include_additional['include_deleted'] to TRUE will override this behavior.
|
|
|
|
*
|
2009-02-05 03:42:58 +00:00
|
|
|
* @return
|
2009-05-28 10:05:32 +00:00
|
|
|
* An array of fields matching $params. If
|
2012-09-27 15:44:17 +00:00
|
|
|
* $include_additional['include_deleted'] is TRUE, the array is keyed by
|
|
|
|
* field ID, otherwise it is keyed by field name.
|
2009-02-05 03:42:58 +00:00
|
|
|
*/
|
2013-04-13 17:06:40 +00:00
|
|
|
function field_read_fields($conditions = array(), $include_additional = array()) {
|
|
|
|
// Include inactive fields if specified in the $include_additional parameter.
|
|
|
|
$include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive'];
|
|
|
|
// Include deleted fields if specified either in the $include_additional or
|
|
|
|
// the $conditions parameters.
|
|
|
|
$include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']);
|
2012-09-28 22:11:59 +00:00
|
|
|
|
2013-06-12 15:38:00 +00:00
|
|
|
// Pass include_inactive and include_deleted to the $conditions array.
|
|
|
|
$conditions['include_inactive'] = $include_inactive;
|
|
|
|
$conditions['include_deleted'] = $include_deleted;
|
2013-04-13 17:06:40 +00:00
|
|
|
|
2013-06-12 15:38:00 +00:00
|
|
|
return entity_load_multiple_by_properties('field_entity', $conditions);
|
2009-02-05 03:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-02-19 01:09:31 +00:00
|
|
|
* Reads a single instance record from the database.
|
2009-12-03 02:30:18 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* Generally, you should use field_info_instance() instead, as it provides
|
|
|
|
* caching and allows other modules the opportunity to append additional
|
|
|
|
* formatters, widgets, and other information.
|
2009-05-28 10:05:32 +00:00
|
|
|
*
|
2010-02-11 17:44:47 +00:00
|
|
|
* @param $entity_type
|
2010-02-12 05:38:10 +00:00
|
|
|
* The type of entity to which the field is bound.
|
2009-02-05 03:42:58 +00:00
|
|
|
* @param $field_name
|
|
|
|
* The field name to read.
|
|
|
|
* @param $bundle
|
|
|
|
* The bundle to which the field is bound.
|
|
|
|
* @param array $include_additional
|
2012-09-27 15:44:17 +00:00
|
|
|
* The default behavior of this function is to not return an instance that has
|
|
|
|
* been deleted, or whose field is inactive. Setting
|
2009-10-01 19:16:57 +00:00
|
|
|
* $include_additional['include_inactive'] or
|
2012-09-27 15:44:17 +00:00
|
|
|
* $include_additional['include_deleted'] to TRUE will override this behavior.
|
|
|
|
*
|
2009-02-05 03:42:58 +00:00
|
|
|
* @return
|
|
|
|
* An instance structure, or FALSE.
|
|
|
|
*/
|
2010-02-11 17:44:47 +00:00
|
|
|
function field_read_instance($entity_type, $field_name, $bundle, $include_additional = array()) {
|
2010-03-27 05:52:50 +00:00
|
|
|
$instances = field_read_instances(array('entity_type' => $entity_type, 'field_name' => $field_name, 'bundle' => $bundle), $include_additional);
|
2009-02-05 03:42:58 +00:00
|
|
|
return $instances ? current($instances) : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Reads in field instances that match an array of conditions.
|
2009-02-05 03:42:58 +00:00
|
|
|
*
|
|
|
|
* @param $param
|
2013-04-13 17:06:40 +00:00
|
|
|
* An array of properties to use in selecting a field instance. Keys are names
|
|
|
|
* of properties found in field instance configuration files, and values are
|
|
|
|
* conditions to match.
|
2009-02-05 03:42:58 +00:00
|
|
|
* @param $include_additional
|
2012-09-27 15:44:17 +00:00
|
|
|
* The default behavior of this function is to not return field instances that
|
|
|
|
* have been marked deleted, or whose field is inactive. Setting
|
|
|
|
* $include_additional['include_inactive'] or
|
|
|
|
* $include_additional['include_deleted'] to TRUE will override this behavior.
|
|
|
|
*
|
2009-02-05 03:42:58 +00:00
|
|
|
* @return
|
|
|
|
* An array of instances matching the arguments.
|
|
|
|
*/
|
2013-04-13 17:06:40 +00:00
|
|
|
function field_read_instances($conditions = array(), $include_additional = array()) {
|
|
|
|
// Include instances of inactive fields if specified in the
|
|
|
|
// $include_additional parameter.
|
2010-02-07 05:12:35 +00:00
|
|
|
$include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive'];
|
2013-04-13 17:06:40 +00:00
|
|
|
// Include deleted instances if specified either in the $include_additional
|
|
|
|
// or the $conditions parameters.
|
|
|
|
$include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']);
|
2010-02-07 05:12:35 +00:00
|
|
|
|
2013-06-12 15:38:00 +00:00
|
|
|
// Pass include_inactive and include_deleted to the $conditions array.
|
|
|
|
$conditions['include_inactive'] = $include_inactive;
|
|
|
|
$conditions['include_deleted'] = $include_deleted;
|
2013-04-13 17:06:40 +00:00
|
|
|
|
2013-06-12 15:38:00 +00:00
|
|
|
return entity_load_multiple_by_properties('field_instance', $conditions);
|
2009-02-05 03:42:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @} End of "defgroup field_crud".
|
2009-02-08 21:22:59 +00:00
|
|
|
*/
|
2009-08-11 14:59:40 +00:00
|
|
|
|
2009-12-03 02:30:18 +00:00
|
|
|
/**
|
2009-08-11 14:59:40 +00:00
|
|
|
* @defgroup field_purge Field API bulk data deletion
|
|
|
|
* @{
|
2012-09-27 15:44:17 +00:00
|
|
|
* Cleans up after Field API bulk deletion operations.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* Field API provides functions for deleting data attached to individual
|
2010-02-12 05:38:10 +00:00
|
|
|
* entities as well as deleting entire fields or field instances in a single
|
2009-08-11 14:59:40 +00:00
|
|
|
* operation.
|
|
|
|
*
|
2010-02-12 05:38:10 +00:00
|
|
|
* Deleting field data items for an entity with field_attach_delete() involves
|
2009-08-11 14:59:40 +00:00
|
|
|
* three separate operations:
|
|
|
|
* - Invoking the Field Type API hook_field_delete() for each field on the
|
2012-09-27 15:44:17 +00:00
|
|
|
* entity. The hook for each field type receives the entity and the specific
|
|
|
|
* field being deleted. A file field module might use this hook to delete
|
|
|
|
* uploaded files from the filesystem.
|
|
|
|
* - Invoking the Field Storage API hook_field_storage_delete() to remove data
|
|
|
|
* from the primary field storage. The hook implementation receives the entity
|
|
|
|
* being deleted and deletes data for all of the entity's bundle's fields.
|
2009-08-11 14:59:40 +00:00
|
|
|
* - Invoking the global Field Attach API hook_field_attach_delete() for all
|
2012-09-27 15:44:17 +00:00
|
|
|
* modules that implement it. Each hook implementation receives the entity
|
|
|
|
* being deleted and can operate on whichever subset of the entity's bundle's
|
|
|
|
* fields it chooses to.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* These hooks are invoked immediately when field_attach_delete() is called.
|
|
|
|
* Similar operations are performed for field_attach_delete_revision().
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* When a field, bundle, or field instance is deleted, it is not practical to
|
2010-02-12 05:38:10 +00:00
|
|
|
* invoke these hooks immediately on every affected entity in a single page
|
2009-08-11 14:59:40 +00:00
|
|
|
* request; there could be thousands or millions of them. Instead, the
|
|
|
|
* appropriate field data items, instances, and/or fields are marked as deleted
|
|
|
|
* so that subsequent load or query operations will not return them. Later, a
|
|
|
|
* separate process cleans up, or "purges", the marked-as-deleted data by going
|
2012-09-27 15:44:17 +00:00
|
|
|
* through the three-step process described above and, finally, removing deleted
|
|
|
|
* field and instance records.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* Purging field data is made somewhat tricky by the fact that, while
|
2010-02-12 05:38:10 +00:00
|
|
|
* field_attach_delete() has a complete entity to pass to the various deletion
|
2009-08-11 14:59:40 +00:00
|
|
|
* hooks, the Field API purge process only has the field data it has previously
|
2010-02-12 05:38:10 +00:00
|
|
|
* stored. It cannot reconstruct complete original entities to pass to the
|
|
|
|
* deletion hooks. It is even possible that the original entity to which some
|
2009-08-11 14:59:40 +00:00
|
|
|
* Field API data was attached has been itself deleted before the field purge
|
|
|
|
* operation takes place.
|
|
|
|
*
|
2010-02-12 05:38:10 +00:00
|
|
|
* Field API resolves this problem by using "pseudo-entities" during purge
|
|
|
|
* operations. A pseudo-entity contains only the information from the original
|
2012-09-27 15:44:17 +00:00
|
|
|
* entity that Field API knows about: entity type, ID, revision ID, and bundle.
|
|
|
|
* It also contains the field data for whichever field instance is currently
|
|
|
|
* being purged. For example, suppose that the node type 'story' used to contain
|
|
|
|
* a field called 'subtitle' but the field was deleted. If node 37 was a story
|
|
|
|
* with a subtitle, the pseudo-entity passed to the purge hooks would look
|
|
|
|
* something like this:
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* @code
|
2010-02-12 05:38:10 +00:00
|
|
|
* $entity = stdClass Object(
|
2009-08-11 14:59:40 +00:00
|
|
|
* [nid] => 37,
|
|
|
|
* [vid] => 37,
|
|
|
|
* [type] => 'story',
|
|
|
|
* [subtitle] => array(
|
|
|
|
* [0] => array(
|
|
|
|
* 'value' => 'subtitle text',
|
|
|
|
* ),
|
|
|
|
* ),
|
|
|
|
* );
|
|
|
|
* @endcode
|
2011-11-30 02:42:42 +00:00
|
|
|
*
|
2011-12-22 09:32:53 +00:00
|
|
|
* See @link field Field API @endlink for information about the other parts of
|
|
|
|
* the Field API.
|
2009-08-11 14:59:40 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Purges a batch of deleted Field API data, instances, or fields.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
2012-03-23 19:45:06 +00:00
|
|
|
* 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.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* @param $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.
|
2013-04-20 03:47:11 +00:00
|
|
|
$instances = field_read_instances(array('deleted' => TRUE), array('include_deleted' => TRUE));
|
2013-04-11 12:55:05 +00:00
|
|
|
$factory = Drupal::service('entity.query');
|
2012-10-30 10:41:42 +00:00
|
|
|
$info = entity_get_info();
|
2009-08-11 14:59:40 +00:00
|
|
|
foreach ($instances as $instance) {
|
2012-10-30 10:41:42 +00:00
|
|
|
$entity_type = $instance['entity_type'];
|
2013-04-13 17:06:40 +00:00
|
|
|
|
|
|
|
// EntityFieldQuery currently fails on conditions on comment bundle.
|
|
|
|
// Remove when http://drupal.org/node/731724 is fixed.
|
|
|
|
if ($entity_type == 'comment') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-10-30 10:41:42 +00:00
|
|
|
$ids = (object) array(
|
|
|
|
'entity_type' => $entity_type,
|
|
|
|
'bundle' => $instance['bundle'],
|
|
|
|
);
|
2010-06-14 15:41:03 +00:00
|
|
|
// field_purge_data() will need the field array.
|
2009-08-11 14:59:40 +00:00
|
|
|
$field = field_info_field_by_id($instance['field_id']);
|
2010-06-14 15:41:03 +00:00
|
|
|
// Retrieve some entities.
|
2013-01-11 02:12:12 +00:00
|
|
|
$query = $factory->get($entity_type)
|
2013-04-13 17:06:40 +00:00
|
|
|
->condition('id:' . $field['uuid'] . '.deleted', 1)
|
2013-01-11 02:12:12 +00:00
|
|
|
->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();
|
2009-08-11 14:59:40 +00:00
|
|
|
|
2010-06-14 15:41:03 +00:00
|
|
|
if ($results) {
|
2012-10-30 10:41:42 +00:00
|
|
|
$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);
|
|
|
|
}
|
2013-04-13 17:06:40 +00:00
|
|
|
field_attach_load($entity_type, $entities, FIELD_LOAD_CURRENT, array('field_id' => $field['uuid'], 'deleted' => 1));
|
2012-10-30 10:41:42 +00:00
|
|
|
foreach ($entities as $entity) {
|
|
|
|
// Purge the data for the entity.
|
2013-01-07 11:22:28 +00:00
|
|
|
field_purge_data($entity, $field, $instance);
|
2009-08-11 14:59:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// No field data remains for the instance, so we can remove it.
|
|
|
|
field_purge_instance($instance);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-15 04:13:48 +00:00
|
|
|
// Retrieve all deleted fields. Any that have no instances can be purged.
|
2013-04-13 17:06:40 +00:00
|
|
|
$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));
|
2010-12-15 04:13:48 +00:00
|
|
|
if (empty($instances)) {
|
2009-08-11 14:59:40 +00:00
|
|
|
field_purge_field($field);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-02-12 05:38:10 +00:00
|
|
|
* Purges the field data for a single field on a single pseudo-entity.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* This is basically the same as field_attach_delete() except it only applies to
|
|
|
|
* a single field. The entity itself is not being deleted, and it is quite
|
2009-08-11 14:59:40 +00:00
|
|
|
* possible that other field data will remain attached to it.
|
|
|
|
*
|
2013-01-07 11:22:28 +00:00
|
|
|
* @param \Drupal\Core\Entity\EntityInterface $entity
|
2010-04-24 07:19:09 +00:00
|
|
|
* The pseudo-entity whose field data is being purged.
|
2009-08-11 14:59:40 +00:00
|
|
|
* @param $field
|
|
|
|
* The (possibly deleted) field whose data is being purged.
|
|
|
|
* @param $instance
|
|
|
|
* The deleted field instance whose data is being purged.
|
|
|
|
*/
|
2013-01-07 11:22:28 +00:00
|
|
|
function field_purge_data(EntityInterface $entity, $field, $instance) {
|
2009-08-11 14:59:40 +00:00
|
|
|
// Each field type's hook_field_delete() only expects to operate on a single
|
|
|
|
// field at a time, so we can use it as-is for purging.
|
|
|
|
$options = array('field_id' => $instance['field_id'], 'deleted' => TRUE);
|
2013-01-07 11:22:28 +00:00
|
|
|
_field_invoke('delete', $entity, $dummy, $dummy, $options);
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Tell the field storage system to purge the data.
|
2013-01-07 11:22:28 +00:00
|
|
|
module_invoke($field['storage']['module'], 'field_storage_purge', $entity, $field, $instance);
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Let other modules act on purging the data.
|
|
|
|
foreach (module_implements('field_attach_purge') as $module) {
|
|
|
|
$function = $module . '_field_attach_purge';
|
2013-01-07 11:22:28 +00:00
|
|
|
$function($entity, $field, $instance);
|
2009-08-11 14:59:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Purges a field instance record from the database.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
2012-09-27 15:44:17 +00:00
|
|
|
* This function assumes all data for the instance has already been purged and
|
2009-08-11 14:59:40 +00:00
|
|
|
* should only be called by field_purge_batch().
|
|
|
|
*
|
|
|
|
* @param $instance
|
|
|
|
* The instance record to purge.
|
|
|
|
*/
|
|
|
|
function field_purge_instance($instance) {
|
|
|
|
// Notify the storage engine.
|
- Patch #443422 by yched, bjaspan | chx, merlinofchaos, Scott Reynolds, plach, profix898, mattyoung: added support for pluggable 'per field' storage engine. Comes with documentation and tests.
The Field Attach API uses the Field Storage API to perform all "database access". Each Field Storage API hook function defines a primitive database operation such as read, write, or delete. The default field storage module, field_sql_storage.module, uses the local SQL database to implement these operations, but alternative field storage backends can choose to represent the data in SQL differently or use a completely different storage mechanism such as a cloud-based database.
2009-09-27 12:52:55 +00:00
|
|
|
$field = field_info_field_by_id($instance['field_id']);
|
|
|
|
module_invoke($field['storage']['module'], 'field_storage_purge_instance', $instance);
|
2009-08-11 14:59:40 +00:00
|
|
|
|
2013-04-13 17:06:40 +00:00
|
|
|
$state = Drupal::state();
|
|
|
|
$deleted_instances = $state->get('field.instance.deleted');
|
|
|
|
unset($deleted_instances[$instance['uuid']]);
|
|
|
|
$state->set('field.instance.deleted', $deleted_instances);
|
|
|
|
|
2009-08-11 14:59:40 +00:00
|
|
|
// Clear the cache.
|
2009-09-07 15:49:01 +00:00
|
|
|
field_info_cache_clear();
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Invoke external hooks after the cache is cleared for API consistency.
|
|
|
|
module_invoke_all('field_purge_instance', $instance);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-12-03 02:30:18 +00:00
|
|
|
* Purges a field record from the database.
|
2009-08-11 14:59:40 +00:00
|
|
|
*
|
|
|
|
* This function assumes all instances for the field has already been purged,
|
|
|
|
* and should only be called by field_purge_batch().
|
|
|
|
*
|
|
|
|
* @param $field
|
|
|
|
* The field record to purge.
|
|
|
|
*/
|
|
|
|
function field_purge_field($field) {
|
2013-04-13 17:06:40 +00:00
|
|
|
$instances = field_read_instances(array('field_id' => $field['uuid']), array('include_deleted' => 1));
|
2009-08-11 14:59:40 +00:00
|
|
|
if (count($instances) > 0) {
|
2010-06-05 12:05:25 +00:00
|
|
|
throw new FieldException(t('Attempt to purge a field @field_name that still has instances.', array('@field_name' => $field['field_name'])));
|
2009-08-11 14:59:40 +00:00
|
|
|
}
|
|
|
|
|
2013-04-13 17:06:40 +00:00
|
|
|
$state = Drupal::state();
|
|
|
|
$deleted_fields = $state->get('field.field.deleted');
|
|
|
|
unset($deleted_fields[$field['uuid']]);
|
|
|
|
$state->set('field.field.deleted', $deleted_fields);
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Notify the storage engine.
|
- Patch #443422 by yched, bjaspan | chx, merlinofchaos, Scott Reynolds, plach, profix898, mattyoung: added support for pluggable 'per field' storage engine. Comes with documentation and tests.
The Field Attach API uses the Field Storage API to perform all "database access". Each Field Storage API hook function defines a primitive database operation such as read, write, or delete. The default field storage module, field_sql_storage.module, uses the local SQL database to implement these operations, but alternative field storage backends can choose to represent the data in SQL differently or use a completely different storage mechanism such as a cloud-based database.
2009-09-27 12:52:55 +00:00
|
|
|
module_invoke($field['storage']['module'], 'field_storage_purge_field', $field);
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Clear the cache.
|
2009-09-07 15:49:01 +00:00
|
|
|
field_info_cache_clear();
|
2009-08-11 14:59:40 +00:00
|
|
|
|
|
|
|
// Invoke external hooks after the cache is cleared for API consistency.
|
|
|
|
module_invoke_all('field_purge_field', $field);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @} End of "defgroup field_purge".
|
|
|
|
*/
|