Example #1
0
/**
 * 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"]);
    }
}
Example #2
0
/**
 * 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"], "");
    }
}