#369560 and #380200: New APIs for retreiving a list of files within a node, and the...
authorNathan Haug
Sun, 12 Apr 2009 20:37:37 +0000 (20:37 +0000)
committerNathan Haug
Sun, 12 Apr 2009 20:37:37 +0000 (20:37 +0000)
filefield.module

index 65ee9a5..6898d30 100644 (file)
@@ -598,14 +598,7 @@ function filefield_progress_implementation() {
  * 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 @@ function filefield_validate_associate_field(&$file, $field) {
  ******************************************************************************/
 
 /**
+ * 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;
+}