If you want to add code for that purpose to a custom module you already have, then you can use the code the Reference Delete module is using as guide.
In short, the code used in the 7.x-1 branch:
- When an entity is deleted, it adds its ID and type to a queue
- During cron task, delete the reference to the deleted entities found on the tables used from the reference fields
The first part is done implementing hook_entity_delete()
. For the second part, this is the relevant code used from that module.
/**
* Returns an array of fields, filtered by module.
*/
function _reference_delete_get_reference_fields($module) {
$fields = field_info_field_map();
$reference_fields = array();
foreach ( $fields as $field_name => &$properties ) {
$properties = field_info_field($field_name);
if ($properties['module'] == $module) {
$reference_fields[$field_name] = $properties;
}
}
if ( !empty($reference_fields) ) {
return $reference_fields;
}
}
/**
* Implements hook_reference_delete_delete_references().
*/
function entityreference_reference_delete_delete_references($entity_id, $type) {
$module = 'entityreference';
if ( $fields = _reference_delete_get_reference_fields($module) ) {
foreach ( $fields as $field_name => $properties ) {
// Acts only if the target entity is of the same type of the entity that's being deleted
if ( $properties['settings']['target_type'] == $type ) {
$tables = reset($properties['storage']['details']);
foreach ( $tables as $table ) {
$keys = array_keys($table);
$table_name = reset($keys);
$column_name = $table[$table_name]['target_id'];
db_delete($table_name)
->condition($column_name, $entity_id, '=')
->execute();
watchdog('reference_delete', 'Deleted all references to entity %entity_type #!entity_id from table !table', array('%entity_type' => $type, '!entity_id' => $entity_id, '!table' => $table_name), WATCHDOG_NOTICE);
}
}
}
}
}
/**
* Implements hook_reference_delete_delete_references().
*/
function references_reference_delete_delete_references($entity_id, $type) {
switch ($type) {
case 'node' :
$module = 'node_reference';
if ( $fields = _references_reference_delete_make_table_names($module) ) {
foreach ( $fields as $field => $tables ) {
foreach ( $tables as $table ) {
db_delete($table)
->condition($field . '_nid', $entity_id, '=')
->execute();
watchdog('reference_delete', 'Deleted all references to entity %entity_type #!entity_id from table !table', array('%entity_type' => $type, '!entity_id' => $entity_id, '!table' => $table_name), WATCHDOG_NOTICE);
}
}
}
break;
case 'user' :
$module = 'user_reference';
if ( $fields = _references_reference_delete_make_table_names($module) ) {
foreach ( $fields as $field => $tables ) {
foreach ( $tables as $table_name ) {
db_delete($table_name)
->condition($field . '_uid', $entity_id, '=')
->execute();
watchdog('reference_delete', 'Deleted all references to entity %entity_type #!entity_id from table !table', array('%entity_type' => $type, '!entity_id' => $entity_id, '!table' => $table_name), WATCHDOG_NOTICE);
}
}
}
break;
}
}
/**
* Creates table names (used only for References).
*/
function _references_reference_delete_make_table_names($module) {
if (isset($module)) {
$fields = _reference_delete_get_reference_fields($module);
if ( count($fields) ) {
$tables = array();
foreach ( $fields as $field ) {
$tables[$field] = array('field_data_' . $field, 'field_revision_' . $field);
}
return $tables;
}
}
}
hook_reference_delete_delete_references()
is a hook used from that module. You don't need to implement it, but use that code to write a function, or a hook, for example hook_cron()
or the worker callback of a queue, in the case you want to follow the same approach used from that module.
I would rather implement hook_entity_delete()
and delete any reference to the deleted node from the tables used from the reference module being used.