Issue #1027184 by Aron Novak: Expose file download URL as a token.
[project/filefield.git] / filefield_field.inc
index 4885fe0..1917644 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
@@ -19,7 +18,7 @@ function filefield_field_settings_form($field) {
     '#title' => t('List field'),
     '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
     '#default_value' => $field['list_field'] === '' ? 0 : (int) $field['list_field'],
-    '#description' => t('The "list" option lets a user choose if a file should be shown in a list when viewing the content after creation.'),
+    '#description' => t('Display a checkbox where users may choose if a file should be shown when viewing the content. Most formatters other than <em>Generic file</em> do not support this option.'),
     '#attributes' => array('class' => 'filefield-list-field'),
   );
   $form['list_default'] = array(
@@ -32,7 +31,7 @@ function filefield_field_settings_form($field) {
     '#title' => t('Description field'),
     '#default_value' => $field['description_field'] === '' ? 0 : (int) $field['description_field'],
     '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
-    '#description' => t('When enabled, will display a text field where users may enter a description about the uploaded file.'),
+    '#description' => t('Display a text field where users may enter a description about the uploaded file. The description text is used when using the <em>Generic file</em> formatter to link to the file, the file name will be used otherwise. Most other formatters do not use the description field on output.'),
   );
 
   return $form;
@@ -86,6 +85,7 @@ function filefield_field_settings_views_data($field) {
   $data[$table_alias][$field['field_name'] .'_data']['field'] = array(
     'title' => $data[$table_alias][$field['field_name'] .'_data']['title'],
     'title short' => $data[$table_alias][$field['field_name'] .'_data']['title short'],
+    'help' => t('Can be used to display specific alt, title, or description information. May cause duplicate rows if grouping fields.'),
     'field' => $db_info['columns']['data']['column'],
     'table' => $db_info['table'],
     'handler' => 'filefield_handler_field_data',
@@ -142,9 +142,14 @@ function filefield_field_load($node, $field, &$items, $teaser, $page) {
       while (!empty($item['data']) && is_string($item['data'])) {
         $item['data'] = unserialize($item['data']);
       }
-      $items[$delta] = array_merge($item, $file);
+      // Merge any data added by modules in hook_file_load().
+      if (isset($file['data']) && isset($item['data'])) {
+        $file['data'] = array_merge((array) $file['data'], (array) $item['data']);
+      }
+      $items[$delta] = array_merge($file, $item);
     }
   }
+
   return array($field['field_name'] => $items);
 }
 
@@ -176,7 +181,7 @@ function filefield_field_update($node, $field, &$items, $teaser, $page) {
 
   // 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;
   } 
 
@@ -188,6 +193,7 @@ function filefield_field_update($node, $field, &$items, $teaser, $page) {
       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); 
       }
     }
@@ -201,6 +207,7 @@ function filefield_field_delete_revision($node, $field, &$items, $teaser, $page)
   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;
     }
@@ -219,6 +226,17 @@ function filefield_field_delete($node, $field, &$items, $teaser, $page) {
     $item['delete_nid'] = $node->nid;
     filefield_field_delete_file($item, $field);
   }
+
+  // Delete all the remaining items present only in older revisions.
+  $db_info = content_database_info($field);
+  $result = db_query('SELECT vid, f.* FROM {' . $db_info['table'] . '} t INNER JOIN {files} f ON t.' . $db_info['columns']['fid']['column'] . ' = f.fid WHERE nid = %d AND vid != %d', $node->nid, $node->vid);
+  while ($item = db_fetch_array($result)) {
+    if (isset($item['fid'])) {
+      $item['field_name'] = $field['field_name'];
+      $item['delete_vid'] = $item['vid'];
+      filefield_field_delete_file($item, $field); 
+    }
+  }
 }
 
 /**
@@ -256,7 +274,7 @@ function filefield_field_sanitize($node, $field, &$items, $teaser, $page) {
     if (empty($item['fid']) || !empty($item['delete'])) {
       // Check for default images at the widget level.
       // TODO: Provide an API to ImageField to do this itself?
-      if (!empty($field['widget']['use_default_image']) && !empty($field['widget']['default_image']['filepath'])) {
+      if (!empty($field['widget']['use_default_image']) && !empty($field['widget']['default_image']['filepath']) && $delta == 0) {
         $items[$delta] = $field['widget']['default_image'];
         $items[$delta]['default'] = TRUE;
       }
@@ -265,25 +283,28 @@ function filefield_field_sanitize($node, $field, &$items, $teaser, $page) {
         continue;
       }
     }
-    // Load the complete file if a filepath is not available.
-    if (!empty($item['fid']) && empty($item['filepath'])) {
-      $items[$delta] = array_merge($item, field_file_load($item['fid']));
-    }
+
     // Add nid so formatters can create a link to the node.
     $items[$delta]['nid'] = $node->nid;
 
-    // TODO: This is only necessary for Views, which doesn't call the "load"
-    // $op. It might be preferable to move this to Views integration somehow.
-    if (!empty($items['data']) && is_string($items[$delta]['data'])) {
-      $item['data'] = unserialize($item['data']);
-    }
-    // Temporary fix to unserialize data serialized multiple times.
+    // Get the 'data' column stored by CCK into an array. This is necessary
+    // for Views, which doesn't call the "load" $op and to fix an issue with
+    // CCK double-serializing data.
     // See the FileField issue http://drupal.org/node/402860.
     // And the CCK issue http://drupal.org/node/407446.
     while (!empty($items[$delta]['data']) && is_string($items[$delta]['data'])) {
       $items[$delta]['data'] = unserialize($items[$delta]['data']);
     }
 
+    // Load the complete file if a filepath is not available.
+    if (!empty($item['fid']) && empty($item['filepath'])) {
+      $file = (array) field_file_load($item['fid']);
+      if (isset($file['data'])) {
+        $file['data'] = array_merge($file['data'], $items[$delta]['data']);
+      }
+      $items[$delta] = array_merge($file, $items[$delta]);
+    }
+
     // Verify the file exists on the server.
     if (!empty($item['filepath']) && !file_exists($item['filepath'])) {
       watchdog('filefield', 'FileField was trying to display the file %file, but it does not exist.', array('%file' => $item['filepath']), WATCHDOG_WARNING);