示例#1
0
/**
 * Retrieves everything about a form submission. It contains a lot of meta-information about the field,
 * from the form_fields and view_tabs. If the optional view_id parameter is included, only the fields
 * in the View are returned (AND all system fields, if they're not included).
 *
 * @param integer $form_id the unique form ID
 * @param integer $submission_id the unique submission ID
 * @param integer $view_id an optional view ID parameter
 * @return array Returns an array of hashes. Each index is a separate form field and its value is
 *           a hash of information about it, such as value, field type, field size, etc.
 */
function ft_get_submission($form_id, $submission_id, $view_id = "")
{
    global $g_table_prefix;
    $return_arr = array();
    $form_fields = ft_get_form_fields($form_id);
    $submission = ft_get_submission_info($form_id, $submission_id);
    $view_fields = !empty($view_id) ? ft_get_view_fields($view_id) : array();
    if (empty($submission)) {
        return array();
    }
    $view_field_ids = array();
    foreach ($view_fields as $view_field) {
        $view_field_ids[] = $view_field["field_id"];
    }
    // for each field, combine the meta form info (like field size, type, data type etc) from $form_fields
    // with the info about the submission itself. Also, if there's a View specified, filter out any fields
    // that aren't used in the View
    foreach ($form_fields as $field_info) {
        $field_id = $field_info["field_id"];
        // if we're looking at this submission through a View,
        if (!empty($view_id) && !in_array($field_id, $view_field_ids)) {
            continue;
        }
        // if the submission contains contents for this field, add it
        if (array_key_exists($field_info['col_name'], $submission)) {
            $field_info["content"] = $submission[$field_info['col_name']];
        }
        // if a view ID is specified, return the view-specific field info as well
        if (!empty($view_id)) {
            $field_view_info = ft_get_view_field($view_id, $field_id);
            if (!empty($field_view_info)) {
                foreach ($field_view_info as $key => $value) {
                    $field_info[$key] = $value;
                }
            }
        }
        $return_arr[] = $field_info;
    }
    // finally, if a View is specified, ensure that the order in which the submission fields are returned
    // is determined by the View. [NOT efficient!]
    if (!empty($view_id)) {
        $ordered_return_arr = array();
        foreach ($view_fields as $view_field_info) {
            $field_id = $view_field_info["field_id"];
            foreach ($return_arr as $field_info) {
                if ($field_info["field_id"] == $field_id) {
                    $ordered_return_arr[] = $field_info;
                    break;
                }
            }
        }
        $return_arr = $ordered_return_arr;
    }
    extract(ft_process_hook_calls("end", compact("form_id", "submission_id", "view_id", "return_arr"), array("return_arr")), EXTR_OVERWRITE);
    return $return_arr;
}
示例#2
0
文件: views.php 项目: jdearaujo/core
/**
 * Return all fields in a View. If this is being on the edit submission page, the second optional
 * parameter is used to limit the results to ONLY those groups on the appropriate tab.
 *
 * @param integer $view_id
 * @param integer $tab_number
 * @param integer $form_id       - this is optional. If this and the next $submission_id param is defined,
 *                                 details about the actual form submission is returned as well
 * @param integer $submission_id
 * @return array
 */
function ft_get_grouped_view_fields($view_id, $tab_number = "", $form_id = "", $submission_id = "")
{
    global $g_table_prefix;
    $tab_clause = !empty($tab_number) ? "AND custom_data = {$tab_number}" : "";
    $group_query = mysql_query("\r\n    SELECT *\r\n    FROM  {$g_table_prefix}list_groups\r\n    WHERE  group_type = 'view_fields_{$view_id}'\r\n           {$tab_clause}\r\n    ORDER BY list_order\r\n      ");
    if (!empty($submission_id)) {
        $submission_info = ft_get_submission_info($form_id, $submission_id);
    }
    $grouped_info = array();
    while ($group_info = mysql_fetch_assoc($group_query)) {
        $group_id = $group_info["group_id"];
        $field_query = mysql_query("\r\n      SELECT *, vf.list_order as list_order, vf.is_new_sort_group as view_field_is_new_sort_group\r\n      FROM   {$g_table_prefix}view_fields vf, {$g_table_prefix}form_fields ff\r\n      WHERE  group_id = {$group_id} AND\r\n             vf.field_id = ff.field_id\r\n      ORDER BY vf.list_order\r\n    ");
        $fields_info = array();
        $field_ids = array();
        while ($row = mysql_fetch_assoc($field_query)) {
            $field_ids[] = $row["field_id"];
            $fields_info[] = $row;
        }
        // for efficiency reasons, we just do a single query to find all validation rules for the all relevant fields
        if (!empty($field_ids)) {
            $field_ids_str = implode(",", $field_ids);
            $validation_query = mysql_query("\r\n        SELECT *\r\n        FROM   {$g_table_prefix}field_validation fv, {$g_table_prefix}field_type_validation_rules ftvr\r\n        WHERE  fv.field_id IN ({$field_ids_str}) AND\r\n               fv.rule_id = ftvr.rule_id\r\n      ");
            $rules_by_field_id = array();
            while ($rule_info = mysql_fetch_assoc($validation_query)) {
                $field_id = $rule_info["field_id"];
                if (!array_key_exists($field_id, $rules_by_field_id)) {
                    $rules_by_field_id[$field_id]["is_required"] = false;
                    $rules_by_field_id[$field_id]["rules"] = array();
                }
                $rules_by_field_id[$field_id]["rules"][] = $rule_info;
                if ($rule_info["rsv_rule"] == "required" || $rule_info["rsv_rule"] == "function" && $rule_info["custom_function_required"] == "yes") {
                    $rules_by_field_id[$field_id]["is_required"] = true;
                }
            }
        }
        // now merge the original field info with the new validation rules. "required" is a special validation rule: that's
        // used to determine whether or not an asterix should appear next to the field. As such, we pass along a
        // custom "is_required" key
        $updated_field_info = array();
        foreach ($fields_info as $field_info) {
            $curr_field_id = $field_info["field_id"];
            $field_info["validation"] = array_key_exists($curr_field_id, $rules_by_field_id) ? $rules_by_field_id[$curr_field_id]["rules"] : array();
            $field_info["is_required"] = array_key_exists($curr_field_id, $rules_by_field_id) ? $rules_by_field_id[$curr_field_id]["is_required"] : false;
            $updated_field_info[] = $field_info;
        }
        $fields_info = $updated_field_info;
        // now, if the submission ID is set it returns an additional submission_value key
        if (!empty($field_ids)) {
            // do a single query to get a list of ALL settings for any of the field IDs we're dealing with
            $field_id_str = implode(",", $field_ids);
            $field_settings_query = mysql_query("\r\n        SELECT *\r\n        FROM   {$g_table_prefix}field_settings\r\n        WHERE  field_id IN ({$field_id_str})\r\n      ");
            $field_settings = array();
            while ($row = mysql_fetch_assoc($field_settings_query)) {
                $field_id = $row["field_id"];
                if (!array_key_exists($field_id, $field_settings)) {
                    $field_settings[$field_id] = array();
                }
                $field_settings[$field_id][] = array($row["setting_id"] => $row["setting_value"]);
            }
            // now append the submission info to the field info that we already have stored
            $updated_fields_info = array();
            foreach ($fields_info as $curr_field_info) {
                $curr_col_name = $curr_field_info["col_name"];
                $curr_field_id = $curr_field_info["field_id"];
                $curr_field_info["field_settings"] = array_key_exists($curr_field_id, $field_settings) ? $field_settings[$curr_field_id] : array();
                if (!empty($submission_id)) {
                    $curr_field_info["submission_value"] = $submission_info[$curr_col_name];
                }
                $updated_fields_info[] = $curr_field_info;
            }
            $fields_info = $updated_fields_info;
        }
        $grouped_info[] = array("group" => $group_info, "fields" => $fields_info);
    }
    return $grouped_info;
}
示例#3
0
/**
 * Completely removes a form from the database. This includes deleting all form fields, emails, Views,
 * View fields, View tabs, View filters, client-form, client-view and public omit list (form & View),
 * and anything else !
 *
 * It also includes an optional parameter to remove all files that were uploaded through file fields in the
 * form; defaulted to FALSE.
 *
 * @param integer $form_id the unique form ID
 * @param boolean $remove_associated_files A boolean indicating whether or not all files that were
 *              uploaded via file fields in this form should be removed as well.
 */
function ft_delete_form($form_id, $remove_associated_files = false)
{
    global $g_table_prefix;
    extract(ft_process_hook_calls("start", compact("form_id"), array()), EXTR_OVERWRITE);
    $form_fields = ft_get_form_fields($form_id, array("include_field_type_info" => true));
    $success = true;
    $message = "";
    $file_delete_problems = array();
    if ($remove_associated_files) {
        $submission_id_query = mysql_query("SELECT submission_id FROM {$g_table_prefix}form_{$form_id}");
        $file_fields_to_delete = array();
        while ($row = mysql_fetch_assoc($submission_id_query)) {
            $submission_id = $row["submission_id"];
            foreach ($form_fields as $form_field_info) {
                if ($form_field_info["is_file_field"] == "no") {
                    continue;
                }
                // I really don't like this... what should be done is do a SINGLE query after this loop is complete
                // to return a map of field_id to values. That would then update $file_fields_to_delete
                // with a fraction of the cost
                $submission_info = ft_get_submission_info($form_id, $submission_id);
                $filename = $submission_info[$form_field_info["col_name"]];
                // if no filename was stored, it was empty - just continue
                if (empty($filename)) {
                    continue;
                }
                $file_fields_to_delete[] = array("submission_id" => $submission_id, "field_id" => $form_field_info["field_id"], "field_type_id" => $field_type_id, "filename" => $filename);
            }
        }
        if (!empty($file_fields_to_delete)) {
            list($success, $file_delete_problems) = ft_delete_submission_files($form_id, $file_fields_to_delete, "ft_delete_form");
        }
    }
    // remove the table
    $query = "DROP TABLE IF EXISTS {$g_table_prefix}form_{$form_id}";
    mysql_query($query) or ft_handle_error("Failed query in <b>" . __FUNCTION__ . "</b>, line " . __LINE__ . ": <i>{$query}</i>", mysql_error());
    // remove any reference to the form in form_fields
    mysql_query("DELETE FROM {$g_table_prefix}form_fields WHERE form_id = {$form_id}") or ft_handle_error("Failed query in <b>" . __FUNCTION__ . "</b>, line " . __LINE__ . ": <i>{$query}</i>", mysql_error());
    // remove any reference to the form in forms table
    mysql_query("DELETE FROM {$g_table_prefix}forms WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}client_forms WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}form_export_templates WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}form_email_fields WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}public_form_omit_list WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}multi_page_form_urls WHERE form_id = {$form_id}");
    mysql_query("DELETE FROM {$g_table_prefix}list_groups WHERE group_type = 'form_{$form_id}_view_group'");
    // delete all email templates for the form
    $email_templates = ft_get_email_template_list($form_id);
    foreach ($email_templates as $email_template_info) {
        ft_delete_email_template($email_template_info["email_id"]);
    }
    // delete all form Views
    $views_result = mysql_query("SELECT view_id FROM {$g_table_prefix}views WHERE form_id = {$form_id}");
    while ($info = mysql_fetch_assoc($views_result)) {
        ft_delete_view($info["view_id"]);
    }
    // remove any field settings
    foreach ($form_fields as $field_info) {
        $field_id = $field_info["field_id"];
        mysql_query("DELETE FROM {$g_table_prefix}field_settings WHERE field_id = {$field_id}");
    }
    // as with many things in the script, potentially we need to return a vast range of information from this last function. But
    // we'l limit
    if (!$success) {
        $message = $file_delete_problems;
    }
    return array($success, $message);
}
示例#4
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"]);
    }
}