/** * 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); }
<?php require "../../../global/session_start.php"; ft_check_permission("admin"); $form_id = ft_load_field("form_id", "add_form_form_id", ""); $sortable_id = "add_form_step4"; // go to next page if (!empty($_POST) && isset($_POST["next_step"])) { // reorder fields and rename their column names, as per their new order $_POST["sortable_id"] = $sortable_id; ft_update_form_fields($form_id, $_POST, true); $deleted_rows = explode(",", $_POST["{$sortable_id}_sortable__deleted_rows"]); ft_delete_form_fields($form_id, $deleted_rows); session_write_close(); header("location: step5.php?form_id={$form_id}"); exit; } $form_fields = ft_get_form_fields($form_id); $form_setup = ft_get_form($form_id); // build the best guesses and list of field IDs $best_guesses = array(); $field_ids = array(); foreach ($form_fields as $field) { $field_ids[] = $field["field_id"]; if ($field["is_system_field"] == "yes") { continue; } // best guess at generating an appropriate Display Name $temp = preg_replace("/_/", " ", $field["field_name"]); $display_name_guess = ucwords($temp); $best_guesses[] = "\"{$field['field_id']}\": \"{$display_name_guess}\"";