Index: filefield_sources.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield_sources/filefield_sources.module,v
retrieving revision 1.8
diff -u -r1.8 filefield_sources.module
--- filefield_sources.module 7 Aug 2010 19:28:25 -0000 1.8
+++ filefield_sources.module 9 Aug 2010 04:09:04 -0000
@@ -229,6 +229,7 @@
function filefield_sources_info() {
$info = module_invoke_all('filefield_sources_info');
drupal_alter('filefield_sources_info', $info);
+ uasort($info, '_filefield_sources_sort');
return $info;
}
@@ -280,6 +281,45 @@
}
/**
+ * Clean up the file name, munging extensions and transliterating.
+ *
+ * @param $filepath
+ * A string containing a file name or full path. Only the file name will
+ * actually be modified.
+ * @return
+ * A file path with a cleaned-up file name.
+ */
+function filefield_sources_clean_filename($filepath) {
+ global $user;
+
+ $filename = basename($filepath);
+
+ if (module_exists('transliteration')) {
+ module_load_include('inc', 'transliteration');
+
+ $langcode = NULL;
+ if (!empty($_POST['language'])) {
+ $languages = language_list();
+ $langcode = isset($languages[$_POST['language']]) ? $_POST['language'] : NULL;
+ }
+ $filename = transliteration_clean_filename($filename, $langcode);
+ }
+
+ // Because this transfer mechanism does not use file_save_upload(), we need
+ // to manually munge the filename to prevent dangerous extensions.
+ // See file_save_upload().
+ $extensions = '';
+ foreach ($user->roles as $rid => $name) {
+ $extensions .= ' '. variable_get("upload_extensions_$rid",
+ variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp'));
+ }
+ $filename = file_munge_filename($filename, $extensions);
+
+ $directory = dirname($filepath);
+ return ($directory ? $directory . '/' : $directory) . $filename;
+}
+
+/**
* Theme the display of the sources list.
*/
function theme_filefield_sources_list($element, $sources) {
@@ -340,9 +380,9 @@
/**
* Generate help text based on the $element['#upload_validators'] property.
*/
-function filefield_sources_element_validation_help($element) {
+function filefield_sources_element_validation_help($validators) {
$desc = array();
- foreach ($element['#upload_validators'] as $callback => $arguments) {
+ foreach ($validators as $callback => $arguments) {
$help_func = $callback .'_help';
if (function_exists($help_func)) {
$desc[] = call_user_func_array($help_func, $arguments);
@@ -350,3 +390,12 @@
}
return empty($desc) ? '' : implode('
', $desc);
}
+
+/**
+ * Custom sort function for ordering sources.
+ */
+function _filefield_sources_sort($a, $b) {
+ $a = (array)$a + array('weight' => 0, 'label' => '');
+ $b = (array)$b + array('weight' => 0, 'label' => '');
+ return $a['weight'] < $b['weight'] ? -1 : ($a['weight'] > $b['weight'] ? 1 : strnatcasecmp($a['label'], $b['label']));
+}
Index: filefield_sources.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield_sources/filefield_sources.css,v
retrieving revision 1.1
diff -u -r1.1 filefield_sources.css
--- filefield_sources.css 17 Apr 2009 00:20:12 -0000 1.1
+++ filefield_sources.css 9 Aug 2010 04:09:04 -0000
@@ -2,9 +2,14 @@
/* Generic display for all sources. */
-div.filefield-source input.form-text {
+div.filefield-source input.form-text,
+div.filefield-source select.form-select {
display: inline;
- width: 28em;
+ width: 20em;
+}
+
+div.filefield-source .form-item {
+ white-space: normal;
}
div.filefield-source input.hint {
Index: sources/reference.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield_sources/sources/reference.inc,v
retrieving revision 1.5
diff -u -r1.5 reference.inc
--- sources/reference.inc 17 Jun 2010 00:10:20 -0000 1.5
+++ sources/reference.inc 9 Aug 2010 04:09:04 -0000
@@ -23,6 +23,7 @@
'description' => t('Reuse an existing file by entering its file name.'),
'process' => 'filefield_source_reference_process',
'value' => 'filefield_source_reference_value',
+ 'weight' => 1,
);
return $source;
}
@@ -70,7 +71,8 @@
$return['sources_reference'] = array(
'#title' => t('Autocomplete reference options'),
'#type' => 'fieldset',
- '#collapsible' => FALSE,
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
);
$return['sources_reference']['filefield_source_autocomplete'] = array(
@@ -105,7 +107,7 @@
$element['filefield_reference']['autocomplete'] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'filefield/reference/' . $element['#type_name'] . '/' . $element['#field_name'],
- '#description' => filefield_sources_element_validation_help($element),
+ '#description' => filefield_sources_element_validation_help($element['#upload_validators']),
);
$element['filefield_reference']['select'] = array(
Index: sources/remote.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield_sources/sources/remote.inc,v
retrieving revision 1.8
diff -u -r1.8 remote.inc
--- sources/remote.inc 8 Aug 2010 22:42:29 -0000 1.8
+++ sources/remote.inc 9 Aug 2010 04:09:05 -0000
@@ -144,6 +144,7 @@
$url_info = parse_url($url);
$pathinfo = pathinfo($url_info['path']);
$filename = rawurldecode(basename($url_info['path']));
+ $filename = filefield_sources_clean_filename($filename);
$filepath = file_create_filename($filename, file_directory_temp());
if (empty($pathinfo['extension'])) {
Index: sources/imce.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filefield_sources/sources/imce.inc,v
retrieving revision 1.4
diff -u -r1.4 imce.inc
--- sources/imce.inc 2 Mar 2010 20:01:27 -0000 1.4
+++ sources/imce.inc 9 Aug 2010 04:09:04 -0000
@@ -32,6 +32,7 @@
'description' => t('Select a file to use from a file browser.'),
'process' => 'filefield_source_imce_process',
'value' => 'filefield_source_imce_value',
+ 'weight' => -1,
);
return $source;
}
@@ -67,10 +68,10 @@
$field = content_fields($element['#field_name'], $element['#type_name']);
$element['filefield_imce'] = array(
- '#weight' => 100.3,
+ '#weight' => 100.5,
'#access' => empty($element['fid']['#value']),
'#theme' => 'filefield_source_imce_element',
- '#description' => filefield_sources_element_validation_help($element),
+ '#description' => filefield_sources_element_validation_help($element['#upload_validators']),
);
$filepath_id = $element['#id'] . '-imce-path';
Index: sources/attach.inc
===================================================================
RCS file: sources/attach.inc
diff -N sources/attach.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sources/attach.inc 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,266 @@
+ t('File attach from server directory'),
+ 'label' => t('File attach'),
+ 'description' => t('Select a file from a directory on the server.'),
+ 'process' => 'filefield_source_attach_process',
+ 'value' => 'filefield_source_attach_value',
+ 'weight' => 3,
+ );
+ return $source;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function filefield_source_attach_theme() {
+ return array(
+ 'filefield_source_attach_element' => array(
+ 'arguments' => array('element' => NULL),
+ 'file' => 'sources/attach.inc',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_filefield_source_settings().
+ */
+function filefield_source_attach_settings($op, $field) {
+ $return = array();
+
+ if ($op == 'form') {
+ $return['source_attach'] = array(
+ '#title' => t('File attach settings'),
+ '#type' => 'fieldset',
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#description' => t('File attach allows for selecting a file from a directory on the server, commonly used in combination with FTP.') . ' ' . t('This file source will ignore file size checking when used.') . '',
+ '#element_validate' => array('_filefield_source_attach_file_path_validate'),
+ '#weight' => 3,
+ );
+ $return['source_attach']['filefield_source_attach_path'] = array(
+ '#type' => 'textfield',
+ '#title' => t('File attach path'),
+ '#default_value' => empty($field['filefield_source_attach_path']) ? 'file_attach' : $field['filefield_source_attach_path'],
+ '#size' => 60,
+ '#maxlength' => 128,
+ '#description' => t('The directory within the File attach location that will contain attachable files.'),
+ );
+ $return['source_attach']['filefield_source_attach_absolute'] = array(
+ '#type' => 'radios',
+ '#title' => t('File attach location'),
+ '#options' => array(
+ 0 => t('Within the files directory'),
+ 1 => t('Absolute server path'),
+ ),
+ '#default_value' => isset($field['filefield_source_attach_absolute']) ? $field['filefield_source_attach_absolute'] : 0,
+ '#description' => t('The File attach path may be with the files directory (%file_directory) or from the root of your server. If an absolute path is used and it does not start with a "/" your path will be relative to your site directory: %realpath.', array('%file_directory' => file_directory_path(), '%realpath' => realpath('./'))),
+ );
+ $return['source_attach']['filefield_source_attach_mode'] = array(
+ '#type' => 'radios',
+ '#title' => t('Attach method'),
+ '#options' => array(
+ 'move' => t('Move the file directly to the final location'),
+ 'copy' => t('Leave a copy of the file in the attach directory'),
+ ),
+ '#default_value' => isset($field['filefield_source_attach_mode']) ? $field['filefield_source_attach_mode'] : 'move',
+ '#description' => t(),
+ );
+ $return['source_attach']['tokens'] = array(
+ '#type' => 'markup',
+ '#value' => theme('token_help', 'user'),
+ );
+ }
+ elseif ($op == 'save') {
+ $return[] = 'filefield_source_attach_path';
+ $return[] = 'filefield_source_attach_absolute';
+ $return[] = 'filefield_source_attach_mode';
+ }
+
+ return $return;
+}
+
+function _filefield_source_attach_file_path_validate($element, &$form_state) {
+ // Strip slashes from the end of the file path.
+ $filepath = rtrim($element['filefield_source_attach_path']['#value'], '\\/');
+ form_set_value($element['filefield_source_attach_path'], $filepath, $form_state);
+
+ $filepath = _filefield_source_attach_directory($form_state['values']);
+
+ // Check that the directory exists and is writable.
+ if (!field_file_check_directory($filepath, FILE_CREATE_DIRECTORY)) {
+ form_error($element['filefield_source_attach_path'], t('Specified file attach path must exist or be writable.'));
+ }
+}
+
+/**
+ * A #process callback to extend the filefield_widget element type.
+ */
+function filefield_source_attach_process($element, $edit, &$form_state, $form) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+
+ $element['filefield_attach'] = array(
+ '#theme' => 'filefield_source_attach_element',
+ '#weight' => 100.5,
+ '#access' => empty($element['fid']['#value']),
+ );
+
+ $path = _filefield_source_attach_directory($field['widget']);
+ $options = _filefield_source_attach_options($path);
+
+ $description = t('This method may be used to attach files that exceed the file size limit. Files may be attached from the %directory directory on the server, usually uploaded through FTP.', array('%directory' => realpath($path)));
+
+ // Error messages.
+ if ($options === FALSE || empty($field['widget']['filefield_source_attach_path'])) {
+ $attach_message = t('A file attach directory could not be located.');
+ $attach_description = t('Please check your settings for the %field field.', array('%field' => $field['widget']['label']));
+ }
+ elseif (!count($options)) {
+ $attach_message = t('There currently no files to attach.');
+ $attach_description = $description;
+ }
+
+ if (isset($attach_message)) {
+ $element['filefield_attach']['attach_message'] = array(
+ '#value' => $attach_message,
+ );
+ $element['filefield_attach']['#description'] = $attach_description;
+ }
+ else {
+ $validators = $element['#upload_validators'];
+ if (isset($validators['filefield_validate_size'])) {
+ unset($validators['filefield_validate_size']);
+ }
+ $description .= '
' . filefield_sources_element_validation_help($validators);
+ $element['filefield_attach']['filename'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ );
+ $element['filefield_attach']['#description'] = $description;
+ }
+
+ $element['filefield_attach']['attach'] = array(
+ '#type' => 'submit',
+ '#value' => $attach_message ? t('Refresh') : t('Attach'),
+ '#submit' => array('node_form_submit_build_node'),
+ '#ahah' => array(
+ 'path' => 'filefield/ahah/'. $element['#type_name'] .'/'. $element['#field_name'] .'/'. $element['#delta'],
+ 'wrapper' => $element['#id'] .'-ahah-wrapper',
+ 'method' => 'replace',
+ 'effect' => 'fade',
+ ),
+ );
+
+ return $element;
+}
+
+function _filefield_source_attach_options($path) {
+ if (!field_file_check_directory($path, FILE_CREATE_DIRECTORY)) {
+ drupal_set_message(t('Specified file attach path must exist or be writable.'), 'error');
+ return FALSE;
+ }
+
+ $options = array();
+ $file_attach = file_scan_directory($path, '.*', array('.', '..', 'CVS', '.svn'), 0, TRUE, 'filename', 0, 0);
+
+ if (count($file_attach)) {
+ $options = array('' => t('-- Select file --'));
+ foreach ($file_attach as $filename => $fileinfo) {
+ $filename = basename($filename);
+ $options[$filename] = $filename;
+ }
+ }
+
+ natcasesort($options);
+ return $options;
+}
+
+/**
+ * A #filefield_value_callback function.
+ */
+function filefield_source_attach_value($element, &$item) {
+ if (!empty($item['filefield_attach']['filename'])) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ $attach_path = _filefield_source_attach_directory($field['widget']);
+ $filepath = $attach_path . '/' . $item['filefield_attach']['filename'];
+
+ // Clean up the file name extensions and transliterate.
+ $original_filepath = $filepath;
+ $new_filepath = filefield_sources_clean_filename($filepath);
+ rename($filepath, $new_filepath);
+ $filepath = $new_filepath;
+
+ // Run all the normal validations, minus file size restrictions.
+ $validators = $element['#upload_validators'];
+ if (isset($validators['filefield_validate_size'])) {
+ unset($validators['filefield_validate_size']);
+ }
+
+ // Save the file to the new location.
+ if ($file = field_file_save_file($filepath, $validators, filefield_widget_file_path($field))) {
+ $item = array_merge($item, $file);
+
+ // Delete the original file if "moving" the file instead of copying.
+ if (empty($field['widget']['filefield_source_attach_mode']) || $field['widget']['filefield_source_attach_mode'] !== 'copy') {
+ @unlink($filepath);
+ }
+ }
+
+ // Restore the original file name if the file still exists.
+ if (file_exists($filepath) && $filepath != $original_filepath) {
+ rename($filepath, $original_filepath);
+ }
+ }
+
+ $item['filefield_attach']['filename'] = '';
+}
+
+/**
+ * Theme the output of the autocomplete field.
+ */
+function theme_filefield_source_attach_element($element) {
+ if (isset($element['attach_message'])) {
+ $output = $element['attach_message']['#value'];
+ }
+ else {
+ $select = '';
+ $size = $element['#size'] ? ' size="'. $element['filename']['#size'] .'"' : '';
+ _form_set_class($element['filename'], array('form-select'));
+ $multiple = $element['#multiple'];
+ $output = '';
+ }
+ $output .= theme('submit', $element['attach']);
+ $element['#type'] = 'item';
+ return '