/** * Uploads a file for a particular form submission field. This is called AFTER the submission has already been * added to the database so there's an available, valid submission ID. It uploads the file to the appropriate * folder then updates the database record. * * Since any submission file field can only ever store a single file at once, this function automatically deletes * the old file in the event of the new file being successfully uploaded. * * @param integer $form_id the unique form ID * @param integer $submission_id a unique submission ID * @param array $file_field_info * @return array returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> * [2]: If success, the filename of the uploaded file */ function ft_file_upload_submission_file($form_id, $submission_id, $file_field_info) { global $g_table_prefix, $g_filename_char_whitelist, $LANG; // get the column name and upload folder for this field $field_id = $file_field_info["field_id"]; $col_name = $file_field_info["field_info"]["col_name"]; // if the column name wasn't found, the $field_id passed in was invalid. Somethin' aint right... if (empty($col_name)) { return array(false, $LANG["notify_submission_no_field_id"]); } // clean up the filename according to the whitelist chars $field_name = $file_field_info["field_info"]["field_name"]; $fileinfo = $_FILES[$field_name]; $filename_parts = explode(".", $fileinfo["name"]); $extension = $filename_parts[count($filename_parts) - 1]; array_pop($filename_parts); $filename_without_extension = implode(".", $filename_parts); $valid_chars = preg_quote($g_filename_char_whitelist); $filename_without_ext_clean = preg_replace("/[^{$valid_chars}]/", "", $filename_without_extension); // unlikely, but...! if (empty($filename_without_ext_clean)) { $filename_without_ext_clean = "file"; } $filename = $filename_without_ext_clean . "." . $extension; $tmp_filename = $fileinfo["tmp_name"]; $filesize = $fileinfo["size"]; // always in BYTES $filesize_kb = $filesize / 1000; // pull a couple of values out of the field's settings (these are custom to the field) $file_upload_max_size = $file_field_info["settings"]["max_file_size"]; $file_upload_dir = $file_field_info["settings"]["folder_path"]; $permitted_file_types = $file_field_info["settings"]["permitted_file_types"]; // check file size if ($filesize_kb > $file_upload_max_size) { $placeholders = array("FILESIZE" => round($filesize_kb, 1), "MAXFILESIZE" => $file_upload_max_size); $error = ft_eval_smarty_string($LANG["notify_file_too_large"], $placeholders); return array(false, $error); } // check upload folder is valid and writable if (!is_dir($file_upload_dir) || !is_writable($file_upload_dir)) { return array(false, $LANG["notify_invalid_field_upload_folder"]); } // check file extension is valid. Note: this is "dumb" - it just tests for the file extension string, not // the actual file type based on it's header info [this is done because I want to allow users to permit // uploading of any file types, and I can't know about all header types] $is_valid_extension = true; if (!empty($permitted_file_types)) { $is_valid_extension = false; $raw_extensions = explode(",", $permitted_file_types); foreach ($raw_extensions as $ext) { // remove whitespace and periods $clean_extension = str_replace(".", "", trim($ext)); if (preg_match("/{$clean_extension}\$/i", $filename)) { $is_valid_extension = true; } } } // all checks out! if ($is_valid_extension) { // find out if there was already a file uploaded in this field. We make a note of this so that // in case the new file upload is successful, we automatically delete the old file $submission_info = ft_get_submission_info($form_id, $submission_id); $old_filename = !empty($submission_info[$col_name]) ? $submission_info[$col_name] : ""; // check for duplicate filenames and get a unique name $unique_filename = ft_get_unique_filename($file_upload_dir, $filename); // copy file to uploads folder and remove temporary file if (@rename($tmp_filename, "{$file_upload_dir}/{$unique_filename}")) { @chmod("{$file_upload_dir}/{$unique_filename}", 0777); // update the database $query = "\n UPDATE {$g_table_prefix}form_{$form_id}\n SET {$col_name} = '{$unique_filename}'\n WHERE submission_id = {$submission_id}\n "; $result = mysql_query($query); if ($result) { // if there was a file previously uploaded in this field, delete it! if (!empty($old_filename)) { @unlink("{$file_upload_dir}/{$old_filename}"); } return array(true, $LANG["notify_file_uploaded"], $unique_filename); } else { return array(false, $LANG["notify_file_not_uploaded"]); } } else { return array(false, $LANG["notify_file_not_uploaded"]); } } else { return array(false, $LANG["notify_unsupported_file_extension"]); } }
/** * A simple, no-frills file upload function. It: * - checks the folder exists & has write permissions * - ensures the file has a unique name & doesn't overwrite anything else * * @param string the folder to upload to * @param $filename the (desired) name to call the file (will be renamed if a file with the same * name exists) * @param $tmp_location the location of the temporary file * @return array Returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> * [2]: the unique filename (or empty, if not successful) */ function ft_upload_file($folder, $filename, $tmp_location) { global $g_table_prefix, $LANG; // check the folder is valid and writable if (!is_dir($folder) || !is_writable($folder)) { return array(false, $LANG["notify_invalid_upload_folder"], ""); } // ensure the filename is unique $unique_filename = ft_get_unique_filename($folder, $filename); // copy file to uploads folder and remove temporary file if (rename($tmp_location, "{$folder}/{$unique_filename}")) { @chmod("{$folder}/{$unique_filename}", 0777); return array(true, $LANG["notify_file_uploaded"], $unique_filename); } else { return array(false, $LANG["notify_file_not_uploaded"], ""); } }