Index: filefield_widget.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield_widget.inc,v retrieving revision 1.96 diff -u -r1.96 filefield_widget.inc --- filefield_widget.inc 8 May 2010 04:25:37 -0000 1.96 +++ filefield_widget.inc 16 Jun 2010 21:36:50 -0000 @@ -433,10 +433,7 @@ if ($file = field_file_load($element['fid']['#value'])) { $file = (object) $file; if ($file->status == FILE_STATUS_PERMANENT) { - // TODO: We could use field_file_references() here to reference any file - // but hook_file_delete() needs to be implemented first. - $references = module_invoke('filefield', 'file_references', $file); - if ($references['filefield'] == 0) { + if (field_file_references($file) == 0) { form_error($element, t('Referencing to the file used in the %field field is not allowed.', array('%field' => $element['#title']))); } } Index: filefield_field.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield_field.inc,v retrieving revision 1.37 diff -u -r1.37 filefield_field.inc --- filefield_field.inc 28 Apr 2010 22:38:13 -0000 1.37 +++ filefield_field.inc 16 Jun 2010 21:36:49 -0000 @@ -181,7 +181,7 @@ // If this is a new node there are no old items to worry about. // On new revisions, old files are always maintained in the previous revision. - if ($node->is_new || !empty($node->revision)) { + if ($node->is_new || !empty($node->revision) || !empty($node->skip_filefield_delete)) { return; } @@ -193,6 +193,7 @@ if (isset($oitem['fid']) && !in_array($oitem['fid'], $curfids)) { // For hook_file_references, remember that this is being deleted. $oitem['field_name'] = $field['field_name']; + $oitem['delete_vid'] = $orig->vid; filefield_field_delete_file($oitem, $field); } } @@ -206,6 +207,7 @@ foreach ($items as $delta => $item) { // For hook_file_references, remember that this is being deleted. $item['field_name'] = $field['field_name']; + $item['delete_vid'] = $node->vid; if (filefield_field_delete_file($item, $field)) { $items[$delta] = NULL; } Index: filefield.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.module,v retrieving revision 1.217 diff -u -r1.217 filefield.module --- filefield.module 8 May 2010 04:25:37 -0000 1.217 +++ filefield.module 16 Jun 2010 21:36:49 -0000 @@ -645,7 +645,7 @@ * Implementation of hook_file_delete(). */ function filefield_file_delete($file) { - // foreach field... remove items referencing $file. + filefield_delete_file_references($file); } /** @@ -1007,3 +1007,49 @@ return $files; } + +/** + * Delete all node references of a file. + * + * @param $file + * The file object for which to find references. + * @param $field + * Optional. The CCK field array or field name as a string. + */ +function filefield_delete_file_references($file, $field = NULL) { + $fields = filefield_get_field_list(NULL, $field); + $file = (object) $file; + + $references = filefield_get_file_references($file, $field); + foreach ($references as $nid => $node_references) { + // Do not update a node if it is already being deleted directly by the user. + if (isset($file->delete_nid) && $file->delete_nid == $nid) { + continue; + } + + foreach ($node_references as $vid) { + // Do not update the node revision if that revision is already being + // saved or deleted directly by the user. + if (isset($file->delete_vid) && $file->delete_vid == $vid) { + continue; + } + + $node = node_load(array('vid' => $vid)); + foreach ($fields as $field_name => $field) { + if (isset($node->$field_name)) { + foreach ($node->$field_name as $delta => $item) { + if ($item['fid'] == $file->fid) { + unset($node->{$field_name}[$delta]); + } + } + $node->$field_name = array_values(array_filter($node->$field_name)); + } + } + + // Save the node after removing the file references. This flag prevents + // FileField from attempting to delete the file again. + $node->skip_filefield_delete = TRUE; + node_save($node); + } + } +}