diff --git a/components/file.inc b/components/file.inc index eabd07f90199f1206bbd2c066627845d131a591c..70a39b3f6d910bab346cff794431ce21349cb03f 100644 --- a/components/file.inc +++ b/components/file.inc @@ -21,6 +21,7 @@ function _webform_defaults_file() { 'addextensions' => '', 'size' => '2 MB', ), + 'rename' => '', 'scheme' => 'public', 'directory' => '', 'progress_indicator' => 'throbber', @@ -156,6 +157,15 @@ function _webform_edit_file($component) { '#field_prefix' => 'webform/', ); + $form['extra']['rename'] = array( + '#type' => 'textfield', + '#title' => t('Rename files'), + '#default_value' => $component['extra']['rename'], + '#description' => t('You may optionally use tokens to create a pattern used to rename files upon submission. Omit the extension; it will be added automatically.').' '.theme('webform_token_help', array('groups' => array('node', 'submission'))), + '#weight' => 6, + '#element_validate' => array('_webform_edit_file_rename_validate'), + ); + $form['display']['progress_indicator'] = array( '#type' => 'radios', '#title' => t('Progress indicator'), @@ -187,6 +197,18 @@ function _webform_edit_file($component) { return $form; } +/** + * A Form API element validate function to ensure that the rename string is + * either empty or contains at least one token. + */ +function _webform_edit_file_rename_validate($element, &$form_state, $form) { + $rename = trim($form_state['values']['extra']['rename']); + form_set_value($element, $rename, $form_state); + if (strlen($rename) && !count(token_scan($rename))) { + form_error($element, t('To create unique file names, use at least one token in the file name pattern.')); + } +} + /** * A Form API element validate function to check filesize is valid. */ @@ -542,3 +564,60 @@ function webform_file_usage_adjust($submission) { } } } + +/** + * Rename any files which are eligible for renaming, if this submission is being + * submitted for the first time. + */ +function webform_file_rename($node, $submission) { + if (isset($submission->file_usage)) { + foreach ($submission->file_usage['renameable'] as $cid => $fids) { + foreach ($fids as $fid) { + webform_file_process_rename($node, $submission, $node->webform['components'][$cid], $fid); + } + } + } +} + + +/** + * Renames the uploaded file name using tokens. + * + * @param $node + * The webform node object. + * @param $submission + * The webform submission object. + * @param $component + * Component settings array for which fid is going to be processed. + * @param $fid + * A file id to be processed. + */ +function webform_file_process_rename($node, $submission, $component, $fid) { + $file = webform_get_file($fid); + + if ($file) { + // Get the destination uri. + $destination_dir = $component['extra']['scheme'] . '://webform/' . drupal_strtolower(webform_replace_tokens($component['extra']['directory'], $node)); + $destination_dir = file_stream_wrapper_uri_normalize($destination_dir); + + // Get the file extension. + $info = pathinfo($file->uri); + $extension = $info['extension']; + + // Prepare new file name without extension. + $new_file_name = webform_replace_tokens($component['extra']['rename'], $node, $submission, NULL, TRUE); + $new_file_name = trim($new_file_name); + $new_file_name = _webform_transliterate($new_file_name); + $new_file_name = str_replace('/', '_', $new_file_name); + $new_file_name = preg_replace('/[^a-zA-Z0-9_\- ]/', '', $new_file_name); + if (strlen($new_file_name)) { + // Prepare the new uri with new filename. + $destination = "$destination_dir/$new_file_name.$extension"; + + // Compare the uri and Rename the file name. + if ($file->uri != $destination) { + file_move($file, $destination, FILE_EXISTS_RENAME); + } + } + } +} diff --git a/webform.module b/webform.module index c886be379a26c5c180a17ca4bf00546b7760e994..ed0f7138ca74b56d00d7f7b6392b0d8462e3ef2e 100644 --- a/webform.module +++ b/webform.module @@ -1224,6 +1224,7 @@ function webform_webform_submission_presave($node, &$submission) { $has_file_components = FALSE; $new_fids = array(); $old_fids = array(); + $renameable = array(); foreach ($node->webform['components'] as $cid => $component) { if ($component['type'] == 'file') { @@ -1233,6 +1234,9 @@ function webform_webform_submission_presave($node, &$submission) { if (empty($value)) { unset($submission->data[$cid][$key]); } + if (strlen($component['extra']['rename'])) { + $renameable[$cid][] = $value; + } } $new_fids = array_merge($new_fids, $submission->data[$cid]); } @@ -1254,13 +1258,20 @@ function webform_webform_submission_presave($node, &$submission) { } } + // Only rename files if this is the first time the submission is being saved as finished. + if ($submission->is_draft || (isset($old_submission) && !$old_submission->is_draft)) { + $renameable = array(); + } + // Save the list of added or removed files so we can add usage in // hook_webform_submission_insert() or _update(). $submission->file_usage = array( // Diff the old against new to determine what files were deleted. 'deleted_fids' => array_diff($old_fids, $new_fids), // Diff the new files against old to determine new uploads. - 'added_fids' => array_diff($new_fids, $old_fids) + 'added_fids' => array_diff($new_fids, $old_fids), + // A list of files which need renaming with tokens. + 'renameable' => $renameable, ); } } @@ -1272,6 +1283,7 @@ function webform_webform_submission_insert($node, $submission) { if (isset($submission->file_usage)) { webform_component_include('file'); webform_file_usage_adjust($submission); + webform_file_rename($node, $submission); } } @@ -1282,6 +1294,7 @@ function webform_webform_submission_update($node, $submission) { if (isset($submission->file_usage)) { webform_component_include('file'); webform_file_usage_adjust($submission); + webform_file_rename($node, $submission); } } @@ -4041,26 +4054,31 @@ function theme_webform_token_help($variables) { return render($help); } +/** + * Convert a name into an identifier that is safe for machine names, classes, + * and other ASCII uses. + */ function _webform_safe_name($name) { $new = trim($name); - - // If transliteration is available, use it to convert names to ASCII. - if (function_exists('transliteration_get')) { - $new = transliteration_get($new, ''); - $new = str_replace(array(' ', '-', '/'), array('_', '_', '_'), $new); - } - else { - $new = str_replace( - array(' ', '-', '/', '€', 'ƒ', 'Š', 'Ž', 'š', 'ž', 'Ÿ', '¢', '¥', 'µ', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Œ', 'œ', 'Æ', 'Ð', 'Þ', 'ß', 'æ', 'ð', 'þ'), - array('_', '_', '_', 'E', 'f', 'S', 'Z', 's', 'z', 'Y', 'c', 'Y', 'u', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'), - $new); - } - + $new = _webform_transliterate($new); + $new = str_replace(array(' ', '-', '/'), array('_', '_', '_'), $new); $new = drupal_strtolower($new); $new = preg_replace('/[^a-z0-9_]/', '', $new); return $new; } +/** + * Transliterate common non-English characters to 7-bit ASCII. + */ +function _webform_transliterate($name) { + // If transliteration is available, use it to convert names to ASCII. + return function_exists('transliteration_get') + ? transliteration_get($name, '') + : str_replace(array('€', 'ƒ', 'Š', 'Ž', 'š', 'ž', 'Ÿ', '¢', '¥', 'µ', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Œ', 'œ', 'Æ', 'Ð', 'Þ', 'ß', 'æ', 'ð', 'þ'), + array('E', 'f', 'S', 'Z', 's', 'z', 'Y', 'c', 'Y', 'u', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'), + $name); +} + /** * Given an email address and a name, format an e-mail address. *