Пример #1
0
/**
 * Called by administrators; updates the content stored on the "Fields" tab in the Edit Form pages.
 *
 * @param integer $form_id the unique form ID
 * @param array $infohash a hash containing the contents of the Edit Form Display tab
 * @return array returns array with indexes:<br/>
 *               [0]: true/false (success / failure)<br/>
 *               [1]: message string<br/>
 */
function ft_update_form_fields_tab($form_id, $infohash)
{
    global $g_table_prefix, $g_root_url, $g_root_dir, $g_debug, $LANG, $g_field_sizes;
    $success = true;
    $message = $LANG["notify_field_changes_saved"];
    $infohash = ft_sanitize($infohash);
    extract(ft_process_hook_calls("start", compact("infohash", "form_id"), array("infohash")), EXTR_OVERWRITE);
    // stores the cleaned-up version of the POST content
    $field_info = array();
    $sortable_id = $infohash["sortable_id"];
    $field_ids = explode(",", $infohash["{$sortable_id}_sortable__rows"]);
    $order = $infohash["sortable_row_offset"];
    $new_sort_groups = explode(",", $infohash["{$sortable_id}_sortable__new_groups"]);
    foreach ($field_ids as $field_id) {
        $is_new_field = preg_match("/^NEW/", $field_id) ? true : false;
        $display_name = isset($infohash["field_{$field_id}_display_name"]) ? $infohash["field_{$field_id}_display_name"] : "";
        $form_field_name = isset($infohash["field_{$field_id}_name"]) ? $infohash["field_{$field_id}_name"] : "";
        $include_on_redirect = isset($infohash["field_{$field_id}_include_on_redirect"]) ? "yes" : "no";
        $field_size = isset($infohash["field_{$field_id}_size"]) ? $infohash["field_{$field_id}_size"] : "";
        $col_name = isset($infohash["col_{$field_id}_name"]) ? $infohash["col_{$field_id}_name"] : "";
        $old_field_size = isset($infohash["old_field_{$field_id}_size"]) ? $infohash["old_field_{$field_id}_size"] : "";
        $old_col_name = isset($infohash["old_col_{$field_id}_name"]) ? $infohash["old_col_{$field_id}_name"] : "";
        $is_system_field = in_array($field_id, $infohash["system_fields"]) ? "yes" : "no";
        // this is only sent for non-system fields
        $field_type_id = isset($infohash["field_{$field_id}_type_id"]) ? $infohash["field_{$field_id}_type_id"] : "";
        // won't be defined for new fields
        $old_field_type_id = isset($infohash["old_field_{$field_id}_type_id"]) ? $infohash["old_field_{$field_id}_type_id"] : "";
        $field_info[] = array("is_new_field" => $is_new_field, "field_id" => $field_id, "display_name" => $display_name, "form_field_name" => $form_field_name, "field_type_id" => $field_type_id, "old_field_type_id" => $old_field_type_id, "include_on_redirect" => $include_on_redirect, "is_system_field" => $is_system_field, "list_order" => $order, "is_new_sort_group" => in_array($field_id, $new_sort_groups) ? "yes" : "no", "col_name" => $col_name, "old_col_name" => $old_col_name, "col_name_changed" => $col_name != $old_col_name ? "yes" : "no", "field_size" => $field_size, "old_field_size" => $old_field_size, "field_size_changed" => $field_size != $old_field_size ? "yes" : "no");
        $order++;
    }
    reset($infohash);
    // delete any extended field settings for those fields whose field type just changed. Two comments:
    //   1. this is compatible with editing the fields in the dialog window. When that happens & the user updates
    //      it, the code updates the old_field_type_id info in the page so this is never called.
    //   2. with the addition of Shared Characteristics, this only deletes fields that aren't mapped between the
    //      two fields types (old and new)
    $changed_fields = array();
    foreach ($field_info as $curr_field_info) {
        if ($curr_field_info["is_new_field"] || $curr_field_info["is_system_field"] == "yes" || $curr_field_info["field_type_id"] == $curr_field_info["old_field_type_id"]) {
            continue;
        }
        $changed_fields[] = $curr_field_info;
    }
    if (!empty($changed_fields)) {
        $field_type_settings_shared_characteristics = ft_get_settings("field_type_settings_shared_characteristics");
        $field_type_map = ft_get_field_type_id_to_identifier();
        $shared_settings = array();
        foreach ($changed_fields as $changed_field_info) {
            $field_id = $changed_field_info["field_id"];
            $shared_settings[] = ft_get_shared_field_setting_info($field_type_map, $field_type_settings_shared_characteristics, $field_id, $changed_field_info["field_type_id"], $changed_field_info["old_field_type_id"]);
            ft_delete_extended_field_settings($field_id);
            ft_delete_field_validation($field_id);
        }
        foreach ($shared_settings as $setting) {
            foreach ($setting as $setting_info) {
                $field_id = $setting_info["field_id"];
                $setting_id = $setting_info["new_setting_id"];
                $setting_value = ft_sanitize($setting_info["setting_value"]);
                mysql_query("\n          INSERT INTO {$g_table_prefix}field_settings (field_id, setting_id, setting_value)\n          VALUES ({$field_id}, {$setting_id}, '{$setting_value}')\n        ");
            }
        }
    }
    // the database column name and size field both affect the form's actual database table structure. If either
    // of those changed, we need to update the database
    $db_col_changes = array();
    $db_col_change_hash = array();
    // added later. Could use refactoring...
    $table_name = "{$g_table_prefix}form_{$form_id}";
    foreach ($field_info as $curr_field_info) {
        if ($curr_field_info["col_name_changed"] == "no" && $curr_field_info["field_size_changed"] == "no") {
            continue;
        }
        if ($curr_field_info["is_new_field"]) {
            continue;
        }
        $field_id = $curr_field_info["field_id"];
        $old_col_name = $curr_field_info["old_col_name"];
        $new_col_name = $curr_field_info["col_name"];
        $new_field_size = $curr_field_info["field_size"];
        $new_field_size_sql = $g_field_sizes[$new_field_size]["sql"];
        list($is_success, $err_message) = _ft_alter_table_column($table_name, $old_col_name, $new_col_name, $new_field_size_sql);
        if ($is_success) {
            $db_col_changes[$field_id] = array("col_name" => $new_col_name, "field_size" => $new_field_size);
        } else {
            // if there have already been successful database column name changes already made,
            // update the database. This helps prevent things getting out of whack
            if (!empty($db_col_changes)) {
                while (list($field_id, $changes) = each($db_col_changes)) {
                    $col_name = $changes["col_name"];
                    $field_size = $changes["field_size"];
                    @mysql_query("\n            UPDATE {$g_table_prefix}form_fields\n            SET    col_name   = '{$col_name}',\n                   field_size = '{$field_size}'\n            WHERE  field_id = {$field_id}\n                      ");
                }
            }
            $message = $LANG["validation_db_not_updated_invalid_input"];
            if ($g_debug) {
                $message .= " \"{$err_message}\"";
            }
            return array(false, $message);
        }
    }
    // now update the fields, and, if need be, the form's database table
    foreach ($field_info as $field) {
        if ($field["is_new_field"]) {
            continue;
        }
        $field_id = $field["field_id"];
        $display_name = $field["display_name"];
        $field_name = $field["form_field_name"];
        $field_type_id = $field["field_type_id"];
        $include_on_redirect = $field["include_on_redirect"];
        $is_system_field = $field["is_system_field"];
        $field_size = $field["field_size"];
        $col_name = $field["col_name"];
        $list_order = $field["list_order"];
        $is_new_sort_group = $field["is_new_sort_group"];
        if ($is_system_field == "yes") {
            $query = "\n        UPDATE {$g_table_prefix}form_fields\n        SET    field_title = '{$display_name}',\n               include_on_redirect = '{$include_on_redirect}',\n               list_order = {$list_order},\n               is_new_sort_group = '{$is_new_sort_group}'\n        WHERE  field_id = {$field_id}\n                  ";
        } else {
            $query = "\n        UPDATE {$g_table_prefix}form_fields\n        SET    field_name = '{$field_name}',\n               field_title = '{$display_name}',\n               field_size = '{$field_size}',\n               col_name = '{$col_name}',\n               field_type_id  = '{$field_type_id}',\n               include_on_redirect = '{$include_on_redirect}',\n               list_order = {$list_order},\n               is_new_sort_group = '{$is_new_sort_group}'\n        WHERE  field_id = {$field_id}\n                  ";
        }
        mysql_query($query) or ft_handle_error("Failed query in <b>" . __FUNCTION__ . "</b>, line " . __LINE__ . ": <i>{$query}</i>", mysql_error());
    }
    // if any of the database column names just changed we need to update any View filters that relied on them
    if (!empty($db_col_changes)) {
        while (list($field_id, $changes) = each($db_col_changes)) {
            ft_update_field_filters($field_id);
        }
    }
    // okay! now add any new fields that the user just added
    $new_fields = array();
    foreach ($field_info as $curr_field) {
        if ($curr_field["is_new_field"]) {
            $new_fields[] = $curr_field;
        }
    }
    if (!empty($new_fields)) {
        list($is_success, $error) = ft_add_form_fields($form_id, $new_fields);
        // if there was a problem adding any of the new fields, inform the user
        if (!$is_success) {
            $success = false;
            $message = $error;
        }
    }
    // Lastly, delete the specified fields. Since some field types (e.g. files) may have additional functionality
    // needed at this stage (e.g. deleting the actual files that had been uploaded via the form). This occurs regardless
    // of whether the add fields step worked or not
    $deleted_field_ids = explode(",", $infohash["{$sortable_id}_sortable__deleted_rows"]);
    extract(ft_process_hook_calls("delete_fields", compact("deleted_field_ids", "infohash", "form_id"), array()), EXTR_OVERWRITE);
    // now actually delete the fields
    ft_delete_form_fields($form_id, $deleted_field_ids);
    extract(ft_process_hook_calls("end", compact("infohash", "field_info", "form_id"), array("success", "message")), EXTR_OVERWRITE);
    return array($success, $message);
}
Пример #2
0
/**
 * This is called when the user updates the field type on the Edit Field Options page. It deletes all old
 * now-irrelevant settings, but retains values that will not change based on field type.
 *
 * @param integer $form_id
 * @param integer $field_id
 * @param string $new_field_type
 */
function ft_change_field_type($form_id, $field_id, $new_field_type)
{
    global $g_table_prefix;
    $field_info = ft_get_form_field($field_id);
    // if the field just changes from one multi-select field to another (radio, checkboxes, select or multi-select)
    // don't delete the field_option group: it's probable that they just wanted to switch the appearance.
    $old_field_type = $field_info["field_type"];
    $multi_select_types = array("select", "multi-select", "radio-buttons", "checkboxes");
    $clauses = array("field_type = '{$new_field_type}'");
    if (!in_array($old_field_type, $multi_select_types) || !in_array($new_field_type, $multi_select_types)) {
        $clauses[] = "field_group_id = NULL";
    }
    if ($new_field_type == "file") {
        $clauses[] = "field_size = 'medium'";
    }
    $clauses_str = implode(",", $clauses);
    mysql_query("DELETE FROM {$g_table_prefix}field_settings WHERE field_id = {$field_id}");
    mysql_query("\n    UPDATE {$g_table_prefix}form_fields\n    SET    {$clauses_str}\n    WHERE  field_id = {$field_id}\n      ") or die(mysql_error());
    // if the user just changed to a file type, ALWAYS set the database field size to "medium"
    if ($old_field_type != $new_field_type && $new_field_type == "file") {
        _ft_alter_table_column("{$g_table_prefix}form_{$form_id}", $field_info["col_name"], $field_info["col_name"], "VARCHAR(255)");
    }
}