Index: filefield.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/filefield/filefield.module,v retrieving revision 1.190 diff -u -r1.190 filefield.module --- filefield.module 12 Apr 2009 19:14:02 -0000 1.190 +++ filefield.module 12 Apr 2009 20:35:46 -0000 @@ -598,14 +598,7 @@ * Implementation of hook_file_references(). */ function filefield_file_references($file) { - $references = 0; - foreach (content_fields() as $field) { - if ($field['type'] != 'filefield') { - continue; - } - $references += filefield_get_file_reference_count($file, $field); - } - return array('filefield' => $references); + return array('filefield' => filefield_get_file_reference_count($file)); } /** @@ -824,38 +817,132 @@ ******************************************************************************/ /** + * Return an array of file fields within a node type or by field name. + * + * @param $field + * Optional. May be either a field array or a field name. + * @param $node_type + * Optional. The node type to filter the list of fields. + */ +function filefield_get_field_list($node_type = NULL, $field = NULL) { + // Build the list of fields to be used for retrieval. + if (isset($field)) { + if (is_string($field)) { + $field = content_fields($field, $node_type); + } + $fields = array($field['field_name'] => $field); + } + elseif (isset($node_type)) { + $type = content_types($node_type); + $fields = $type['fields']; + } + else { + $fields = content_fields(); + } + + // Filter down the list just to file fields. + foreach ($fields as $key => $field) { + if ($field['type'] != 'filefield') { + unset($fields[$key]); + } + } + + return $fields; +} + +/** * Count the number of times the file is referenced within a field. * * @param $file * A file object. * @param $field - * The CCK field array. + * Optional. The CCK field array or field name as a string. * @return * An integer value. */ -function filefield_get_file_reference_count($file, $field) { - $db_info = content_database_info($field); - $references = db_result(db_query( - 'SELECT count('. $db_info['columns']['fid']['column'] .') - FROM {'. $db_info['table'] .'} - WHERE '. $db_info['columns']['fid']['column'] .' = %d', $file->fid - )); - - // If a field_name is present in the file object, the file is being deleted - // from this field. - if (isset($file->field_name) && $field['field_name'] == $file->field_name) { - // If deleting the entire node, count how many references to decrement. - if (isset($file->delete_nid)) { - $node_references = db_result(db_query( - 'SELECT count('. $db_info['columns']['fid']['column'] .') - FROM {'. $db_info['table'] .'} - WHERE '. $db_info['columns']['fid']['column'] .' = %d AND nid = %d', $file->fid, $file->delete_nid - )); - $references = $references - $node_references; +function filefield_get_file_reference_count($file, $field = NULL) { + $fields = filefield_get_field_list(NULL, $field); + $file = (object) $file; + + $references = 0; + foreach ($fields as $field) { + $db_info = content_database_info($field); + $references += db_result(db_query( + 'SELECT count('. $db_info['columns']['fid']['column'] .') + FROM {'. $db_info['table'] .'} + WHERE '. $db_info['columns']['fid']['column'] .' = %d', $file->fid + )); + + // If a field_name is present in the file object, the file is being deleted + // from this field. + if (isset($file->field_name) && $field['field_name'] == $file->field_name) { + // If deleting the entire node, count how many references to decrement. + if (isset($file->delete_nid)) { + $node_references = db_result(db_query( + 'SELECT count('. $db_info['columns']['fid']['column'] .') + FROM {'. $db_info['table'] .'} + WHERE '. $db_info['columns']['fid']['column'] .' = %d AND nid = %d', $file->fid, $file->delete_nid + )); + $references = $references - $node_references; + } + else { + $references = $references - 1; + } } - else { - $references = $references - 1; + } + + return $references; +} + +/** + * Get a list of node IDs that reference 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. + * @return + * An array of IDs grouped by NID: array([nid] => array([vid1], [vid2])). + */ +function filefield_get_file_references($file, $field = NULL) { + $fields = filefield_get_field_list(NULL, $field); + $file = (object) $file; + + $references = array(); + foreach ($fields as $field) { + $db_info = content_database_info($field); + $sql = 'SELECT nid, vid FROM {'. $db_info['table'] .'} WHERE '. $db_info['columns']['fid']['column'] .' = %d'; + $result = db_query($sql, $file->fid); + while ($row = db_fetch_object($result)) { + $references[$row->nid][$row->vid] = $row->vid; } } + return $references; } + +/** + * Get all FileField files connected to a node ID. + * + * @param $nid + * The node object. + * @param $field_name + * Optional. The CCK field array or field name as a string. + * @return + * An array of all files attached to that field (or all fields). + */ +function filefield_get_node_files($node, $field = NULL) { + $fields = filefield_get_field_list($node->type, $field); + + // Get the file rows. + foreach ($fields as $field) { + $db_info = content_database_info($field); + $sql = 'SELECT f.* FROM {files} f INNER JOIN {' . $db_info['table'] . '} c ON f.fid = c.' . $db_info['columns']['fid']['column'] . ' AND c.vid = %d'; + $result = db_query($sql, $node->vid); + while ($file = db_fetch_array($result)) { + $files[$file['fid']] = $file; + } + } + + return $files; +}