Issue #1090216: Add MIME type icon compatibility for kml/kmz files.
[project/filefield.git] / filefield_widget.inc
index dafe78e..4970721 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * @file
@@ -17,14 +16,15 @@ function filefield_widget_settings_form($widget) {
 
   // Convert the extensions list to be a human-friendly comma-separated list.
   $extensions = is_string($widget['file_extensions']) ? $widget['file_extensions'] : 'txt';
-  $extensions = implode(', ', explode(' ', $extensions));
   $form['file_extensions'] = array(
     '#type' => 'textfield',
     '#title' => t('Permitted upload file extensions'),
     '#default_value' => $extensions,
     '#size' => 64,
+    '#maxlength' => 512,
     '#description' => t('Extensions a user can upload to this field. Separate extensions with a space and do not include the leading dot. Leaving this blank will allow users to upload a file with any extension.'),
     '#element_validate' => array('_filefield_widget_settings_extensions_validate'),
+    '#pre_render' => array('_filefield_widget_settings_extensions_value'),
     '#weight' => 1,
   );
 
@@ -71,7 +71,7 @@ function filefield_widget_settings_form($widget) {
     '#default_value' => is_string($widget['max_filesize_per_file'])
                         ? $widget['max_filesize_per_file']
                          : '',
-    '#description' => t('Specify the size limit that applies to each file separately. Enter a value like "512" (bytes), "80K" (kilobytes) or "50M" (megabytes) in order to restrict the allowed file size. If you leave this this empty the file sizes will be limited only by PHP\'s maximum post and file upload sizes (current limit <strong>%limit</strong>).', array('%limit' => format_size(file_upload_max_size()))),
+    '#description' => t('Specify the size limit that applies to each file separately. Enter a value like "512" (bytes), "80K" (kilobytes) or "50M" (megabytes) in order to restrict the allowed file size. If you leave this empty the file sizes will be limited only by PHP\'s maximum post and file upload sizes (current limit <strong>%limit</strong>).', array('%limit' => format_size(file_upload_max_size()))),
     '#element_validate' => array('_filefield_widget_settings_max_filesize_per_file_validate'),
   );
   $form['max_filesize']['max_filesize_per_node'] = array(
@@ -94,9 +94,21 @@ function filefield_widget_settings_save($widget) {
   return array('file_extensions', 'file_path', 'progress_indicator', 'max_filesize_per_file', 'max_filesize_per_node');
 }
 
+/**
+ * A FAPI #pre_render() function to set a cosmetic default value for extensions.
+ */
+function _filefield_widget_settings_extensions_value($element) {
+  $element['#value'] = implode(', ', array_filter(explode(' ', str_replace(',', ' ', $element['#value']))));
+  return $element;
+}
+
+/**
+ * A FAPI #element_validate callback to strip commas from extension lists.
+ */
 function _filefield_widget_settings_extensions_validate($element, &$form_state) {
-  // Remove commas from file extensions.
+  // Remove commas and leading dots from file extensions.
   $value = str_replace(',', ' ', $element['#value']);
+  $value = str_replace(' .', ' ', $value);
   $value = array_filter(explode(' ', $value));
   $value = implode(' ', $value);
   form_set_value($element, $value, $form_state);
@@ -173,7 +185,7 @@ function filefield_widget_file_path($field, $account = NULL) {
  *   The FAPI element whose values are being saved.
  */
 function filefield_save_upload($element) {
-  $upload_name = $element['#field_name'] .'_'. $element['#delta'];
+  $upload_name = implode('_', $element['#array_parents']);
   $field = content_fields($element['#field_name'], $element['#type_name']);
 
   if (empty($_FILES['files']['name'][$upload_name])) {
@@ -204,7 +216,7 @@ function filefield_widget_value($element, $edit = FALSE) {
     $item = $element['#default_value'];
   }
   else {
-    $item = array_merge($element['#default_value'], $edit);
+    $item = $edit;
     $field = content_fields($element['#field_name'], $element['#type_name']);
 
     // Uploads take priority over value of fid text field.
@@ -222,11 +234,12 @@ function filefield_widget_value($element, $edit = FALSE) {
     }
 
     // Load file if the FID has changed so that it can be saved by CCK.
-    $file = field_file_load($item['fid']);
+    $file = isset($item['fid']) ? field_file_load($item['fid']) : NULL;
 
     // If the file entry doesn't exist, don't save anything.
     if (empty($file)) {
       $item = array();
+      $file = array();
     }
 
     // Checkboxes loose their value when empty.
@@ -236,6 +249,9 @@ function filefield_widget_value($element, $edit = FALSE) {
     }
   }
   // Merge file and item data so it is available to all widgets.
+  if (isset($item['data']) && isset($file['data'])) {
+    $file['data'] = array_merge($item['data'], $file['data']);
+  }
   $item = array_merge($item, $file);
 
   return $item;
@@ -248,8 +264,7 @@ function filefield_widget_value($element, $edit = FALSE) {
  * remove buttons, and the description field.
  */
 function filefield_widget_process($element, $edit, &$form_state, $form) {
-  // The widget is being presented, so apply the JavaScript.
-  drupal_add_js(drupal_get_path('module', 'filefield') .'/filefield.js');
+  static $settings_added;
 
   $item = $element['#value'];
   $field_name = $element['#field_name'];
@@ -258,6 +273,18 @@ function filefield_widget_process($element, $edit, &$form_state, $form) {
 
   $field = $form['#field_info'][$field_name];
 
+  // The widget is being presented, so apply the JavaScript.
+  drupal_add_js(drupal_get_path('module', 'filefield') .'/filefield.js');
+  if (!isset($settings_added[$field_name]) && isset($element['#upload_validators']['filefield_validate_extensions'])) {
+    $settings_added[$field_name] = TRUE;
+    $settings = array(
+      'filefield' => array(
+        $field_name => $element['#upload_validators']['filefield_validate_extensions'][0],
+      ),
+    );
+    drupal_add_js($settings, 'setting');
+  }
+
   // Title is not necessary for each individual field.
   if ($field['multiple'] > 0) {
     unset($element['#title']);
@@ -360,6 +387,11 @@ function filefield_widget_process($element, $edit, &$form_state, $form) {
     );
   }
 
+  // Grant access to temporary files.
+  if ($item['fid'] && isset($item['status']) && $item['status'] == 0 && variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
+    $_SESSION['filefield_access'][] = $item['fid'];
+  }
+
   // placeholder.. will be serialized into the data column. this is a place for widgets
   // to put additional data.
   $element['data'] = array(
@@ -398,14 +430,12 @@ function filefield_widget_process($element, $edit, &$form_state, $form) {
       $desc[] = call_user_func_array($help_func, $arguments);
     }
   }
+
   $element['upload'] = array(
-    '#name' => 'files['. $element['#field_name'] .'_'. $element['#delta'] .']',
+    '#name' => 'files[' . implode('_', $element['#array_parents']) . ']',
     '#type' => 'file',
     '#description' => implode('<br />', $desc),
     '#size' => 22,
-    '#attributes' => array(
-      'accept' => implode(',', array_filter(explode(' ', $field['widget']['file_extensions']))),
-    ),
     '#access' => empty($item['fid']),
   );
 
@@ -428,10 +458,7 @@ function filefield_widget_validate(&$element, &$form_state) {
     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'])));
         }
       }
@@ -446,6 +473,7 @@ function filefield_widget_validate(&$element, &$form_state) {
  * FormAPI theme function. Theme the output of an image field.
  */
 function theme_filefield_widget($element) {
+  $element['#id'] .= '-upload'; // Link the label to the upload field.
   return theme('form_element', $element, $element['#children']);
 }
 
@@ -532,12 +560,12 @@ function filefield_node_form_validate($form, &$form_state) {
       }
     }
 
-    if (!$valid && $field['required']) {
+    if (!$valid && $field['required'] && filefield_edit_access($field['type_name'], $field_name, $form['#node'])) {
       form_set_error($field_name, t('%title field is required.', array('%title' => $field['widget']['label'])));
     }
     $max_filesize = parse_size($field['widget']['max_filesize_per_node']);
     if ($max_filesize && $total_filesize > $max_filesize) {
-      form_set_error($field_name, t('Total filesize for %title, %tsize,  exceeds field settings of %msize.',
+      form_set_error($field_name, t('Total filesize for %title, %tsize, exceeds field settings of %msize.',
                                     array(
                                       '%title' => $field['widget']['label'],
                                       '%tsize' => format_size($total_filesize),