/** * This function is called after creating a new form (ft_finalize_form), and creates a default * View - one containing all fields and assigned to all clients that are assigned to the form. * * Notes: I'm not terribly happy about the relationship between the list_groups table and whatever * they're grouping - here, Views. The issue is that to make the entries in the list_groups table * have additional meaning, I customize the group_type value to something like "form_X_view_group" * where "X" is the form name. ... * * @param integer $form_id */ function ft_add_default_view($form_id) { global $g_table_prefix, $LANG; // 1. create the new View $form_info = ft_get_form($form_id); $num_submissions_per_page = isset($_SESSION["ft"]["settings"]["num_submissions_per_page"]) ? $_SESSION["ft"]["settings"]["num_submissions_per_page"] : 10; mysql_query("\r\n INSERT INTO {$g_table_prefix}views (form_id, view_name, view_order, num_submissions_per_page,\r\n default_sort_field, default_sort_field_order)\r\n VALUES ({$form_id}, '{$LANG["phrase_all_submissions"]}', '1', {$num_submissions_per_page}, 'submission_date', 'desc')\r\n "); $view_id = mysql_insert_id(); // 2. create the View group and update the view record we just created (blurgh!) mysql_query("\r\n INSERT INTO {$g_table_prefix}list_groups (group_type, group_name, list_order)\r\n VALUES ('form_{$form_id}_view_group', '{$LANG["word_views"]}', 1)\r\n "); $group_id = mysql_insert_id(); mysql_query("UPDATE {$g_table_prefix}views SET group_id = {$group_id} WHERE view_id = {$view_id}"); // 3. add the default tabs [N.B. this table should eventually be dropped altogether and data moved to list_groups] $view_tab_inserts = array("({$view_id}, 1, '{$LANG["phrase_default_tab_label"]}')", "({$view_id}, 2, '')", "({$view_id}, 3, '')", "({$view_id}, 4, '')", "({$view_id}, 5, '')", "({$view_id}, 6, '')"); $view_tab_insert_str = implode(",\n", $view_tab_inserts); mysql_query("INSERT INTO {$g_table_prefix}view_tabs VALUES {$view_tab_insert_str}"); // now populate the new View fields and the View columns _ft_populate_new_view_fields($form_id, $view_id); // assign the View to all clients attached to this form $client_info = $form_info["client_info"]; foreach ($client_info as $user) { $account_id = $user["account_id"]; mysql_query("\r\n INSERT INTO {$g_table_prefix}client_views (account_id, view_id)\r\n VALUES ({$account_id}, {$view_id})\r\n "); } return array(true, $LANG["notify_new_default_view_created"]); }
function smarty_function_display_form_name($params, &$smarty) { $form_id = isset($params["form_id"]) ? $params["form_id"] : ""; if (empty($form_id)) { return; } $form_info = ft_get_form($form_id); return $form_info["form_name"]; }
// determine whether the page contains any editable fields $editable_field_ids = _ft_get_editable_view_fields($view_id); // update the submission $failed_validation = false; if (isset($_POST) && !empty($_POST)) { $_SESSION["ft"]["new_search"] = "yes"; $request["view_id"] = $view_id; $request["editable_field_ids"] = $editable_field_ids; list($g_success, $g_message) = ft_update_submission($form_id, $submission_id, $request); // if there was any problem udpating this submission, make a special note of it: we'll use that info to merge the current POST request // info with the original field values to ensure the page contains the latest data (i.e. for cases where they fail server-side validation) if (!$g_success) { $failed_validation = true; } } $form_info = ft_get_form($form_id); $view_info = ft_get_view($view_id); // this is crumby $has_tabs = false; foreach ($view_info["tabs"] as $tab_info) { if (!empty($tab_info["tab_label"])) { $has_tabs = true; break; } } if ($has_tabs) { $tab_number = ft_load_field("tab", "view_{$view_id}_current_tab", 1); } else { $tab_number = ""; } $grouped_fields = ft_get_grouped_view_fields($view_id, $tab_number, $form_id, $submission_id);
/** * Deletes multiple form submissions at once. * * If required, deletes any files that were uploaded along with the original submissions. If one or * more files associated with this submission couldn't be deleted (either because they didn't exist * or because they didn't have permissions) the submission IS deleted, but it returns an error * indicating which files caused problems. * * @param integer $form_id the unique form ID * @param mixed $delete_ids a single submission ID / an array of submission IDs / "all". This column * determines which submissions will be deleted * @param integer $view_id (optional) this is only needed if $delete_ids is set to "all". With the advent * of Views, it needs to know which submissions to delete. * @return array returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> */ function ft_delete_submissions($form_id, $view_id, $submissions_to_delete, $omit_list, $search_fields, $is_admin) { global $g_table_prefix, $LANG; $submission_ids = array(); if ($submissions_to_delete == "all") { // get the list of searchable columns for this View. This is needed to ensure that ft_get_search_submission_ids receives // the correct info to determine what submission IDs are appearing in this current search. $searchable_columns = ft_get_view_searchable_fields($view_id); $submission_ids = ft_get_search_submission_ids($form_id, $view_id, "all", "submission_id-ASC", $search_fields, $searchable_columns); $submission_ids = array_diff($submission_ids, $omit_list); } else { $submission_ids = $submissions_to_delete; } $submissions_to_delete = $submission_ids; extract(ft_process_hook_calls("start", compact("form_id", "view_id", "submissions_to_delete", "omit_list", "search_fields", "is_admin"), array("submission_ids")), EXTR_OVERWRITE); $form_info = ft_get_form($form_id); $form_fields = ft_get_form_fields($form_id); $auto_delete_submission_files = $form_info["auto_delete_submission_files"]; $submission_ids_qry = array(); foreach ($submission_ids as $submission_id) { $submission_ids_qry[] = "submission_id = {$submission_id}"; } $where_clause = "WHERE " . join(" OR ", $submission_ids_qry); // loop the form templates to find out if there are any file fields. If there are - and the user // configured it - delete any associated files $file_delete_problems = array(); $form_has_file_field = false; if ($auto_delete_submission_files == "yes") { $file_field_type_ids = ft_get_file_field_type_ids(); $file_fields_to_delete = array(); foreach ($submissions_to_delete as $submission_id) { foreach ($form_fields as $field_info) { $field_type_id = $field_info["field_type_id"]; if (!in_array($field_type_id, $file_field_type_ids)) { continue; } $form_has_file_field = true; $submission_info = ft_get_submission_info($form_id, $submission_id); $filename = $submission_info[$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" => $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_submissions"); } } // now delete the submission mysql_query("DELETE FROM {$g_table_prefix}form_{$form_id} {$where_clause}"); if ($auto_delete_submission_files == "yes") { if (empty($file_delete_problems)) { $success = true; if (count($submission_ids) > 1) { $message = $form_has_file_field ? $LANG["notify_submissions_and_files_deleted"] : $LANG["notify_submissions_deleted"]; } else { $message = $form_has_file_field ? $LANG["notify_submission_and_files_deleted"] : $LANG["notify_submission_deleted"]; } } else { $success = false; if (count($submission_ids) > 1) { $message = $LANG["notify_submissions_deleted_with_problems"] . "<br /><br />"; } else { $message = $LANG["notify_submission_deleted_with_problems"] . "<br /><br />"; } foreach ($file_delete_problems as $problem) { $message .= "• <b>{$problem["filename"]}</b>: {$problem["error"]}<br />\n"; } } } else { $success = true; if (count($submission_ids) > 1) { $message = $LANG["notify_submissions_deleted"]; } else { $message = $LANG["notify_submission_deleted"]; } } // TODO update sessions to ensure the first submission date and num submissions for this form View are correct _ft_cache_form_stats($form_id); _ft_cache_view_stats($form_id, $view_id); $_SESSION["ft"]["form_{$form_id}_select_all_submissions"] = ""; $_SESSION["ft"]["form_{$form_id}_selected_submissions"] = array(); $_SESSION["ft"]["form_{$form_id}_all_submissions_selected_omit_list"] = array(); // loop through all submissions deleted and send any emails reset($submission_ids); foreach ($submission_ids as $submission_id) { ft_send_emails("on_delete", $form_id, $submission_id); } $submissions_to_delete = $submission_ids; extract(ft_process_hook_calls("end", compact("form_id", "view_id", "submissions_to_delete", "omit_list", "search_fields", "is_admin"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
/** * Retrieves information about all forms associated with a particular account. Since 2.0.0 * this function lets you SEARCH the forms, but it still returns all results - not a page worth * (the reason being: the vast majority of people use Form Tools for a small number of forms < 100) * so the form tables are displaying via DHTML, with all results actually returned and hidden in the * page ready to be displayed. * * @param integer $account_id if blank, return all finalized forms, otherwise returns the forms * associated with this particular client. * @param boolean $is_admin whether or not the user retrieving the data is an administrator or not. * If it is, ALL forms are retrieved - even those that aren't yet finalized. * @param array $search_criteria an optional hash with any of the following keys: * "status" - (string) online / offline * "keyword" - (any string) * "order" - (string) form_id-DESC, form_id-ASC, form_name-DESC, form-name-ASC, * status-DESC, status-ASC * @return array returns an array of form hashes */ function ft_search_forms($account_id = "", $is_admin = false, $search_criteria = array()) { global $g_table_prefix; extract(ft_process_hook_calls("start", compact("account_id", "is_admin", "search_criteria"), array("search_criteria")), EXTR_OVERWRITE); $search_criteria["account_id"] = $account_id; $search_criteria["is_admin"] = $is_admin; $results = _ft_get_search_form_sql_clauses($search_criteria); // get the form IDs. All info about the forms will be retrieved in a separate query $form_query = mysql_query("\n SELECT form_id\n FROM {$g_table_prefix}forms\n {$results["where_clause"]}\n {$results["order_clause"]}\n "); // now retrieve the basic info (id, first and last name) about each client assigned to this form. This // takes into account whether it's a public form or not and if so, what clients are in the omit list $client_omitted_from_public_forms = $results["client_omitted_from_public_forms"]; $form_info = array(); while ($row = mysql_fetch_assoc($form_query)) { $form_id = $row["form_id"]; // if this was a search for a single client, filter out those public forms which include their account ID // on the form omit list if (!empty($client_omitted_from_public_forms) && in_array($form_id, $client_omitted_from_public_forms)) { continue; } $form_info[] = ft_get_form($form_id); } extract(ft_process_hook_calls("end", compact("account_id", "is_admin", "search_criteria", "form_info"), array("form_info")), EXTR_OVERWRITE); return $form_info; }
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}\""; } $best_guesses_js = implode(",\n", $best_guesses); $field_id_str = implode(",", $field_ids);
/** * Deletes unwanted form fields. Called by administrator when creating an external form and when * editing a form. * * Note: field types that require additional functionality when deleting a field type (e.g. * file fields which need to delete uploaded files), they need to define the appropriate hook. * Generally this means the "delete_fields" hook in the ft_update_form_fields_tab() function. * * @param integer $form_id * @param array an array of field IDs to delete * @return array Returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> */ function ft_delete_form_fields($form_id, $field_ids) { global $g_table_prefix, $LANG; // default return values $success = true; $message = ""; // find out if the form exists and is complete $form_info = ft_get_form($form_id); $form_table_exists = $form_info["is_complete"] == "yes" ? true : false; // stores the Views IDs of any View that is affected by deleting one of the form field, regardless of the field or form $affected_views = array(); $removed_field_ids = array(); $deleted_field_info = array(); foreach ($field_ids as $field_id) { $field_id = trim($field_id); if (empty($field_id)) { continue; } // ignore brand new fields - nothing to delete! if (preg_match("/^NEW/", $field_id)) { continue; } $old_field_info = ft_get_form_field($field_id); $deleted_field_info[] = $old_field_info; @mysql_query("DELETE FROM {$g_table_prefix}form_fields WHERE field_id = {$field_id}"); if (!$form_table_exists) { continue; } mysql_query("DELETE FROM {$g_table_prefix}new_view_submission_defaults WHERE field_id = {$field_id}"); // see if this field had been flagged as an email field (either as the email field, first or last name). // if it's the email field, delete the whole row. If it's either the first or last name, just empty the value $query = mysql_query("SELECT form_email_id FROM {$g_table_prefix}form_email_fields WHERE email_field_id = {$field_id}"); while ($row = mysql_fetch_assoc($query)) { ft_unset_field_as_email_field($row["email_form_id"]); } mysql_query("UPDATE {$g_table_prefix}form_email_fields SET first_name_field_id = '' WHERE first_name_field_id = {$field_id}"); mysql_query("UPDATE {$g_table_prefix}form_email_fields SET last_name_field_id = '' WHERE last_name_field_id = {$field_id}"); // get a list of any Views that referenced this form field $view_query = mysql_query("SELECT view_id FROM {$g_table_prefix}view_fields WHERE field_id = {$field_id}"); while ($row = mysql_fetch_assoc($view_query)) { $affected_views[] = $row["view_id"]; ft_delete_view_field($row["view_id"], $field_id); } $drop_column = $old_field_info["col_name"]; mysql_query("ALTER TABLE {$g_table_prefix}form_{$form_id} DROP {$drop_column}"); // if any Views had this field as the default sort order, reset them to having the submission_date // field as the default sort order mysql_query("\n UPDATE {$g_table_prefix}views\n SET default_sort_field = 'submission_date',\n default_sort_field_order = 'desc'\n WHERE default_sort_field = '{$drop_column}' AND\n form_id = {$form_id}\n "); $removed_field_ids[] = $field_id; } // update the list_order of this form's fields if ($form_table_exists) { ft_auto_update_form_field_order($form_id); } // update the order of any Views that referenced this field foreach ($affected_views as $view_id) { ft_auto_update_view_field_order($view_id); } // determine the return message if (count($removed_field_ids) > 1) { $message = $LANG["notify_form_fields_removed"]; } else { $message = $LANG["notify_form_field_removed"]; } extract(ft_process_hook_calls("end", compact("deleted_field_info", "form_id", "field_ids", "success", "message"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
/** * Generates the placeholders for a particular form submission. This is used in the email templates, and here and there * for providing placeholder functionality to fields (like the "Edit Submission Label" textfield for a form, where they can * enter placeholders populated here). * * This returns ALL available placeholders for a form, regardless of View. * * @param integer $form_id * @param integer $submission_id * @param array $client_info a hash of information about the appropriate user (optional) * @return array a hash of placeholders and their replacement values (e.g. $arr["FORMURL"] => 17) */ function ft_get_submission_placeholders($form_id, $submission_id, $client_info = "") { global $g_root_url; $placeholders = array(); $settings = ft_get_settings(); $form_info = ft_get_form($form_id); $submission_info = ft_get_submission($form_id, $submission_id); $admin_info = ft_get_admin_info(); $file_field_type_ids = ft_get_file_field_type_ids(); $field_types = ft_get_field_types(true); // now loop through the info stored for this particular submission and for this particular field, // add the custom submission responses to the placeholder hash $form_field_params = array("include_field_type_info" => true, "include_field_settings" => true, "evaluate_dynamic_settings" => true); $form_fields = ft_get_form_fields($form_id, $form_field_params); foreach ($submission_info as $field_info) { $field_id = $field_info["field_id"]; $field_name = $field_info["field_name"]; $field_type_id = $field_info["field_type_id"]; if ($field_info["is_system_field"] == "no") { $placeholders["QUESTION_{$field_name}"] = $field_info["field_title"]; } if (in_array($field_type_id, $file_field_type_ids)) { $field_settings = ft_get_field_settings($field_id); $placeholders["FILENAME_{$field_name}"] = $field_info["content"]; $placeholders["FILEURL_{$field_name}"] = "{$field_settings["folder_url"]}/{$field_info["content"]}"; } else { $detailed_field_info = array(); foreach ($form_fields as $curr_field_info) { if ($curr_field_info["field_id"] != $field_id) { continue; } $detailed_field_info = $curr_field_info; break; } $params = array("form_id" => $form_id, "submission_id" => $submission_id, "value" => $field_info["content"], "field_info" => $detailed_field_info, "field_types" => $field_types, "settings" => $settings, "context" => "email_template"); $value = ft_generate_viewable_field($params); $placeholders["ANSWER_{$field_name}"] = $value; // for backward compatibility if ($field_name == "core__submission_date") { $placeholders["SUBMISSIONDATE"] = $value; } else { if ($field_name == "core__last_modified") { $placeholders["LASTMODIFIEDDATE"] = $value; } else { if ($field_name == "core__ip_address") { $placeholders["IPADDRESS"] = $value; } } } } } // other misc placeholders $placeholders["ADMINEMAIL"] = $admin_info["email"]; $placeholders["FORMNAME"] = $form_info["form_name"]; $placeholders["FORMURL"] = $form_info["form_url"]; $placeholders["SUBMISSIONID"] = $submission_id; $placeholders["LOGINURL"] = $g_root_url . "/index.php"; if (!empty($client_info)) { $placeholders["EMAIL"] = $client_info["email"]; $placeholders["FIRSTNAME"] = $client_info["first_name"]; $placeholders["LASTNAME"] = $client_info["last_name"]; $placeholders["COMPANYNAME"] = $client_info["company_name"]; } extract(ft_process_hook_calls("end", compact("placeholders"), array("placeholders")), EXTR_OVERWRITE); return $placeholders; }
/** * Processes a form submission, either for a single page of a multi-page form or the entire form itself. If the * "submit_button_name key exists in $params (i.e. if the user just submitted the form), it updates the database for * the submission ID. * * Assumption: the ft_api_init_form_page function has been called on the page prior to calling this function. * * @param array $params * * Required keys: * "submit_button": the "name" attribute value of the form submit button * "form_data": the contents of $_POST (or $_GET, if "method" setting is set to "GET" ... ) * "file_data": the contents of $_FILES (only needed if your form contained file fields) * * Optional keys: * "next_page": the URL (relative or absolute) of which page to redirect to (e.g. the next page * in the form or the "thankyou" page). * "finalize": this tells the function to finalize the submission. This prevents it being subsequently * editable via this function and makes the submission appear in the Form Tools UI. * "no_sessions_url": for multi-page forms it's a good idea to pass along this value. It should be the URL * of a page (usually the FIRST page in the form sequence) where the user will be redirected to if * they didn't start the form from the first page. It ensures the form submission gets created & * submitted properly. * "may_update_finalized_submissions": true / false (true by default) * "namespace": if you specified a custom namespace for ft_api_init_form_page, for where the form values will * be stored temporarily in sessions, you need to pass that same value to this function - otherwise * it won't be able to retrieve the form and submission ID * "send_emails": (boolean). By default, Form Tools will trigger any emails that have been attached to the * "on submission" event ONLY when the submission is finalized (finalize=true). This setting provides * you with direct control over when the emails get sent. If not specified, will use the default * behaviour. * * @return mixed ordinarily, this function will just redirect the user to whatever URL is specified in the * "next_page" key. But if that value isn't set, it returns an array: * [0] success / false * [1] if failure, the API Error Code, otherwise blank */ function ft_api_process_form($params) { global $g_table_prefix, $g_multi_val_delimiter, $LANG, $g_api_debug, $g_api_recaptcha_private_key, $g_api_recaptcha_error; // the form data parameter must ALWAYS be defined if (!isset($params["form_data"])) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 306, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 306); } } // special case: if "form_tools_delete_image_field__[fieldname]" exists, the user is just deleting an image // already uploaded through the form using the HTML generated by the ft_api_display_image_field function. // In this case, we process the page normally - even though the form data wasn't submitted & the page may // contain nothing in $form_data $is_deleting_file = false; $file_field_to_delete = ""; $namespace = isset($params["namespace"]) ? $params["namespace"] : "form_tools_form"; $form_id = isset($_SESSION[$namespace]["form_tools_form_id"]) ? $_SESSION[$namespace]["form_tools_form_id"] : ""; $submission_id = isset($_SESSION[$namespace]["form_tools_submission_id"]) ? $_SESSION[$namespace]["form_tools_submission_id"] : ""; while (list($key, $value) = each($params["form_data"])) { if (preg_match("/form_tools_delete_image_field__(.*)\$/", $key, $matches)) { $file_field_to_delete = $matches[1]; $is_deleting_file = true; $field_id = ft_get_form_field_id_by_field_name($file_field_to_delete, $form_id); ft_delete_file_submission($form_id, $submission_id, $field_id, true); unset($_SESSION[$namespace][$file_field_to_delete]); unset($params["form_data"][$key]); } } // check the submission exists if (is_numeric($form_id) && is_numeric($submission_id) && !ft_check_submission_exists($form_id, $submission_id)) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 305, "error_type" => "user", "debugging" => "{$LANG["phrase_submission_id"]}: {$submission_id}"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 305); } } // extract the submission ID and form ID from sessions $form_data = $params["form_data"]; $form_id = isset($_SESSION[$namespace]["form_tools_form_id"]) ? $_SESSION[$namespace]["form_tools_form_id"] : ""; $submission_id = isset($_SESSION[$namespace]["form_tools_submission_id"]) ? $_SESSION[$namespace]["form_tools_submission_id"] : ""; $has_captcha = isset($form_data["recaptcha_response_field"]) ? true : false; $no_sessions_url = isset($params["no_sessions_url"]) ? $params["no_sessions_url"] : false; if (!isset($_GET["ft_sessions_url_override"]) && (empty($form_id) || empty($submission_id))) { if (!empty($no_sessions_url)) { header("location: {$no_sessions_url}"); exit; } else { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 300, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 300); } } } // if the user is neither deleting a file or making a regular form submission, it means they've just // arrived at the page. Cool! Do nothing! if (!$is_deleting_file && !isset($params["form_data"][$params["submit_button"]])) { return; } $submit_button_name = $params["submit_button"]; $next_page = isset($params["next_page"]) ? $params["next_page"] : ""; $file_data = isset($params["file_data"]) ? $params["file_data"] : array(); $finalize = isset($params["finalize"]) ? $params["finalize"] : false; $namespace = isset($params["namespace"]) ? $params["namespace"] : "form_tools_form"; $may_update_finalized_submissions = isset($params["may_update_finalized_submissions"]) ? $params["may_update_finalized_submissions"] : true; // if we're in test mode, we don't do anything with the database - just store the fields in // sessions to emulate if ($form_id == "test" || $submission_id == "test") { reset($form_data); while (list($field_name, $value) = each($form_data)) { $_SESSION[$namespace][$field_name] = $value; } } else { if (isset($_SESSION[$namespace]["form_tools_initialize_form"])) { // only process the form if this submission is being set to be finalized if ($finalize) { // if the user is just putting through a test submission and we've reached the finalization step, // overwrite $form_data with ALL the $all_form_data = array_merge($_SESSION[$namespace], $form_data); ft_initialize_form($all_form_data); } reset($form_data); while (list($field_name, $value) = each($form_data)) { $_SESSION[$namespace][$field_name] = $value; } } else { // check the form ID is valid if (!ft_check_form_exists($form_id)) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 301, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 301); } } // check the submission ID isn't finalized if (!$may_update_finalized_submissions && ft_check_submission_finalized($form_id, $submission_id)) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 302, "error_type" => "user", "debugging" => "{$LANG["phrase_submission_id"]}: {$submission_id}"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 302); } } $form_info = ft_get_form($form_id); // check to see if this form has been disabled if ($form_info["is_active"] == "no") { if (isset($form_data["form_tools_inactive_form_redirect_url"])) { header("location: {$form_data["form_tools_inactive_form_redirect_url"]}"); exit; } if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 303, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 303); } } // now we sanitize the data (i.e. get it ready for the DB query) $form_data = ft_sanitize($form_data); extract(ft_process_hook_calls("start", compact("form_info", "form_id", "form_data"), array("form_data")), EXTR_OVERWRITE); // get a list of the custom form fields (i.e. non-system) for this form $form_fields = ft_get_form_fields($form_id, array("include_field_type_info" => true)); $custom_form_fields = array(); $file_fields = array(); foreach ($form_fields as $field_info) { $field_id = $field_info["field_id"]; $is_system_field = $field_info["is_system_field"]; $field_name = $field_info["field_name"]; // ignore system fields if ($is_system_field == "yes") { continue; } if ($field_info["is_file_field"] == "no") { $custom_form_fields[$field_name] = array("field_id" => $field_id, "col_name" => $field_info["col_name"], "field_title" => $field_info["field_title"], "include_on_redirect" => $field_info["include_on_redirect"], "field_type_id" => $field_info["field_type_id"], "is_date_field" => $field_info["is_date_field"]); } else { $file_fields[] = array("field_id" => $field_id, "field_info" => $field_info); } } // now examine the contents of the POST/GET submission and get a list of those fields // which we're going to update $valid_form_fields = array(); while (list($form_field, $value) = each($form_data)) { if (array_key_exists($form_field, $custom_form_fields)) { $curr_form_field = $custom_form_fields[$form_field]; $cleaned_value = $value; if (is_array($value)) { if ($form_info["submission_strip_tags"] == "yes") { for ($i = 0; $i < count($value); $i++) { $value[$i] = strip_tags($value[$i]); } } $cleaned_value = implode("{$g_multi_val_delimiter}", $value); } else { if ($form_info["submission_strip_tags"] == "yes") { $cleaned_value = strip_tags($value); } } $valid_form_fields[$curr_form_field["col_name"]] = "'{$cleaned_value}'"; } } $now = ft_get_current_datetime(); $ip_address = $_SERVER["REMOTE_ADDR"]; $is_finalized = $finalize ? "yes" : "no"; $set_query = ""; while (list($col_name, $value) = each($valid_form_fields)) { $set_query .= "{$col_name} = {$value},\n"; } // in this section, we update the database submission info & upload files. Note: we don't do ANYTHING // if the form_tools_ignore_submission key is set in the POST data if (!isset($form_data["form_tools_ignore_submission"])) { // construct our query. Note that we do TWO queries: one if there was no CAPTCHA sent with this // post (which automatically finalizes the result), and one if there WAS. For the latter, the submission // is finalized later if ($has_captcha && $finalize) { $query = "\n UPDATE {$g_table_prefix}form_{$form_id}\n SET {$set_query}\n last_modified_date = '{$now}',\n ip_address = '{$ip_address}'\n WHERE submission_id = {$submission_id}\n "; } else { // only update the is_finalized setting if $may_update_finalized_submissions === false if (!$finalize && $may_update_finalized_submissions) { $is_finalized_clause = ""; } else { $is_finalized_clause = ", is_finalized = '{$is_finalized}'"; } $query = "\n UPDATE {$g_table_prefix}form_{$form_id}\n SET {$set_query}\n last_modified_date = '{$now}',\n ip_address = '{$ip_address}'\n {$is_finalized_clause}\n WHERE submission_id = {$submission_id}\n "; } // only process the query if the form_tools_ignore_submission key isn't defined if (!mysql_query($query)) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 304, "error_type" => "system", "debugging" => "Failed query in <b>" . __FUNCTION__ . ", " . __FILE__ . "</b>, line " . __LINE__ . ": <i>" . nl2br($query) . "</i> " . mysql_error()); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 304); } } // used for uploading files. The error handling is incomplete here, like previous versions. Although the hooks // are permitted to return values, they're not used extract(ft_process_hook_calls("manage_files", compact("form_id", "submission_id", "file_fields", "namespace"), array("success", "message")), EXTR_OVERWRITE); } // store all the info in sessions reset($form_data); while (list($field_name, $value) = each($form_data)) { $_SESSION[$namespace][$field_name] = $value; } } } // was there a reCAPTCHA response? If so, a recaptcha was just submitted, check it was entered correctly $passes_captcha = true; if ($has_captcha) { $passes_captcha = false; $recaptcha_challenge_field = $form_data["recaptcha_challenge_field"]; $recaptcha_response_field = $form_data["recaptcha_response_field"]; $folder = dirname(__FILE__); require_once "{$folder}/recaptchalib.php"; $resp = recaptcha_check_answer($g_api_recaptcha_private_key, $_SERVER["REMOTE_ADDR"], $recaptcha_challenge_field, $recaptcha_response_field); if ($resp->is_valid) { $passes_captcha = true; // if the developer wanted the submission to be finalized at this step, do so - it wasn't earlier! if ($finalize) { mysql_query("\n UPDATE {$g_table_prefix}form_{$form_id}\n SET is_finalized = 'yes'\n WHERE submission_id = {$submission_id}\n "); } } else { // register the recaptcha as a global, which can be picked up silently by ft_api_display_captcha to // let them know they entered it wrong $g_api_recaptcha_error = $resp->error; } } if ($passes_captcha && !empty($next_page) && !$is_deleting_file) { // if the user wasn't putting through a test submission or initializing the form, we can send safely // send emails at this juncture, but ONLY if it was just finalized OR if the send_emails parameter // allows for it if ($form_id != "test" && $submission_id != "test" && !isset($_SESSION[$namespace]["form_tools_initialize_form"]) && !isset($form_data["form_tools_ignore_submission"])) { // send any emails attached to the on_submission trigger if (isset($params["send_emails"]) && $params["send_emails"] === true) { ft_send_emails("on_submission", $form_id, $submission_id); } else { if ($is_finalized == "yes" && (!isset($params["send_emails"]) || $params["send_emails"] !== false)) { ft_send_emails("on_submission", $form_id, $submission_id); } } } header("location: {$next_page}"); exit; } return array(true, ""); }
function ft_preload_values($source, $form_id = "") { global $request, $submission_type; $page_values = array(); switch ($source) { case "new_form": $page_values["client_info"] = array(); $page_values["form_name"] = ""; $page_values["form_url"] = ""; $page_values["is_multi_page_form"] = "no"; $page_values["multi_page_form_urls"] = array(); $page_values["redirect_url"] = ""; $page_values["access_type"] = "admin"; $page_values["hidden_fields"] = "<input type=\"hidden\" name=\"add_form\" value=\"1\" />"; break; case "post": $page_values["form_name"] = $request["form_name"]; $page_values["form_url"] = $request["form_url"]; $page_values["is_multi_page_form"] = isset($request["is_multi_page_form"]) ? "yes" : "no"; $page_values["redirect_url"] = $request["redirect_url"]; $page_values["access_type"] = $request["access_type"]; $page_values["client_info"] = array(); if (!empty($form_id)) { $page_values["hidden_fields"] = "\n <input type=\"hidden\" name=\"update_form\" value=\"1\" />\n <input type=\"hidden\" name=\"form_id\" value=\"{$form_id}\" />"; } else { $page_values["hidden_fields"] = "<input type=\"hidden\" name=\"add_form\" value=\"1\" />"; } break; case "database": if (empty($form_id)) { return; } $form_info = ft_get_form($form_id); $submission_type = $form_info["submission_type"]; $page_values["form_name"] = $form_info["form_name"]; $page_values["form_url"] = $form_info["form_url"]; $page_values["is_multi_page_form"] = $form_info["is_multi_page_form"]; $page_values["multi_page_form_urls"] = $form_info["multi_page_form_urls"]; $page_values["redirect_url"] = $form_info["redirect_url"]; $page_values["access_type"] = $form_info["access_type"]; $page_values["client_info"] = $form_info["client_info"]; $page_values["hidden_fields"] = "\n <input type=\"hidden\" name=\"update_form\" value=\"1\" />\n <input type=\"hidden\" name=\"form_id\" value=\"{$form_id}\" />"; break; } return $page_values; }
/** * This function processes the form submissions, after the form has been set up in the database. */ function ft_process_form($form_data) { global $g_table_prefix, $g_multi_val_delimiter, $g_query_str_multi_val_separator, $g_root_dir, $LANG, $g_api_version, $g_api_recaptcha_private_key; // ensure the incoming values are escaped $form_data = ft_sanitize($form_data); $form_id = $form_data["form_tools_form_id"]; $form_info = ft_get_form($form_id); // do we have a form for this id? if (!ft_check_form_exists($form_id)) { $page_vars = array("message_type" => "error", "message" => $LANG["processing_invalid_form_id"]); ft_display_page("error.tpl", $page_vars); exit; } extract(ft_process_hook_calls("start", compact("form_info", "form_id", "form_data"), array("form_data")), EXTR_OVERWRITE); // check to see if this form has been completely set up if ($form_info["is_complete"] == "no") { $page_vars = array("message_type" => "error", "message" => $LANG["processing_form_incomplete"]); ft_display_page("error.tpl", $page_vars); exit; } // check to see if this form has been disabled if ($form_info["is_active"] == "no") { if (isset($form_data["form_tools_inactive_form_redirect_url"])) { header("location: {$form_data["form_tools_inactive_form_redirect_url"]}"); exit; } $page_vars = array("message_type" => "error", "message" => $LANG["processing_form_disabled"]); ft_display_page("error.tpl", $page_vars); exit; } // do we have a form for this id? if (!ft_check_form_exists($form_id)) { $page_vars = array("message_type" => "error", "message" => $LANG["processing_invalid_form_id"]); ft_display_page("error.tpl", $page_vars); exit; } // was there a reCAPTCHA response? If so, a recaptcha was just submitted. This generally implies the // form page included the API, so check it was entered correctly. If not, return the user to the webpage if (isset($g_api_version) && isset($form_data["recaptcha_response_field"])) { $passes_captcha = false; $recaptcha_challenge_field = $form_data["recaptcha_challenge_field"]; $recaptcha_response_field = $form_data["recaptcha_response_field"]; $folder = dirname(__FILE__); require_once "{$folder}/global/api/recaptchalib.php"; $resp = recaptcha_check_answer($g_api_recaptcha_private_key, $_SERVER["REMOTE_ADDR"], $recaptcha_challenge_field, $recaptcha_response_field); if ($resp->is_valid) { $passes_captcha = true; } else { // since we need to pass all the info back to the form page we do it by storing the data in sessions. Enable 'em. @ft_api_start_sessions(); $_SESSION["form_tools_form_data"] = $form_data; $_SESSION["form_tools_form_data"]["api_recaptcha_error"] = $resp->error; // if there's a form_tools_form_url specified, redirect to that if (isset($form_data["form_tools_form_url"])) { header("location: {$form_data["form_tools_form_url"]}"); exit; } else { if (isset($_SERVER["HTTP_REFERER"])) { header("location: {$_SERVER["HTTP_REFERER"]}"); exit; } else { $page_vars = array("message_type" => "error", "message" => $LANG["processing_no_form_url_for_recaptcha"]); ft_display_page("error.tpl", $page_vars); exit; } } } } // get a list of the custom form fields (i.e. non-system) for this form $form_fields = ft_get_form_fields($form_id, array("include_field_type_info" => true)); $custom_form_fields = array(); $file_fields = array(); foreach ($form_fields as $field_info) { $field_id = $field_info["field_id"]; $is_system_field = $field_info["is_system_field"]; $field_name = $field_info["field_name"]; // ignore system fields if ($is_system_field == "yes") { continue; } if ($field_info["is_file_field"] == "no") { $custom_form_fields[$field_name] = array("field_id" => $field_id, "col_name" => $field_info["col_name"], "field_title" => $field_info["field_title"], "include_on_redirect" => $field_info["include_on_redirect"], "field_type_id" => $field_info["field_type_id"], "is_date_field" => $field_info["is_date_field"]); } else { $file_fields[] = array("field_id" => $field_id, "field_info" => $field_info); } } // now examine the contents of the POST/GET submission and get a list of those fields // which we're going to update $valid_form_fields = array(); while (list($form_field, $value) = each($form_data)) { // if this field is included, store the value for adding to DB if (array_key_exists($form_field, $custom_form_fields)) { $curr_form_field = $custom_form_fields[$form_field]; $cleaned_value = $value; if (is_array($value)) { if ($form_info["submission_strip_tags"] == "yes") { for ($i = 0; $i < count($value); $i++) { $value[$i] = strip_tags($value[$i]); } } $cleaned_value = implode("{$g_multi_val_delimiter}", $value); } else { if ($form_info["submission_strip_tags"] == "yes") { $cleaned_value = strip_tags($value); } } $valid_form_fields[$curr_form_field["col_name"]] = "'{$cleaned_value}'"; } } $now = ft_get_current_datetime(); $ip_address = $_SERVER["REMOTE_ADDR"]; $col_names = array_keys($valid_form_fields); $col_names_str = join(", ", $col_names); if (!empty($col_names_str)) { $col_names_str .= ", "; } $col_values = array_values($valid_form_fields); $col_values_str = join(", ", $col_values); if (!empty($col_values_str)) { $col_values_str .= ", "; } // build our query $query = "\r\n INSERT INTO {$g_table_prefix}form_{$form_id} ({$col_names_str} submission_date, last_modified_date, ip_address, is_finalized)\r\n VALUES ({$col_values_str} '{$now}', '{$now}', '{$ip_address}', 'yes')\r\n "; // add the submission to the database (if form_tools_ignore_submission key isn't set by either the form or a module) $submission_id = ""; if (!isset($form_data["form_tools_ignore_submission"])) { $result = mysql_query($query); if (!$result) { $page_vars = array("message_type" => "error", "error_code" => 304, "error_type" => "system", "debugging" => "Failed query in <b>" . __FUNCTION__ . ", " . __FILE__ . "</b>, line " . __LINE__ . ": <i>" . nl2br($query) . "</i>", mysql_error()); ft_display_page("error.tpl", $page_vars); exit; } $submission_id = mysql_insert_id(); extract(ft_process_hook_calls("end", compact("form_id", "submission_id"), array()), EXTR_OVERWRITE); } $redirect_query_params = array(); // build the redirect query parameter array foreach ($form_fields as $field_info) { if ($field_info["include_on_redirect"] == "no" || $field_info["is_file_field"] == "yes") { continue; } switch ($field_info["col_name"]) { case "submission_id": $redirect_query_params[] = "submission_id={$submission_id}"; break; case "submission_date": $settings = ft_get_settings(); $submission_date_formatted = ft_get_date($settings["default_timezone_offset"], $now, $settings["default_date_format"]); $redirect_query_params[] = "submission_date=" . rawurlencode($submission_date_formatted); break; case "last_modified_date": $settings = ft_get_settings(); $submission_date_formatted = ft_get_date($settings["default_timezone_offset"], $now, $settings["default_date_format"]); $redirect_query_params[] = "last_modified_date=" . rawurlencode($submission_date_formatted); break; case "ip_address": $redirect_query_params[] = "ip_address={$ip_address}"; break; default: $field_name = $field_info["field_name"]; // if $value is an array, convert it to a string, separated by $g_query_str_multi_val_separator if (isset($form_data[$field_name])) { if (is_array($form_data[$field_name])) { $value_str = join($g_query_str_multi_val_separator, $form_data[$field_name]); $redirect_query_params[] = "{$field_name}=" . rawurlencode($value_str); } else { $redirect_query_params[] = "{$field_name}=" . rawurlencode($form_data[$field_name]); } } break; } } // only upload files & send emails if we're not ignoring the submission if (!isset($form_data["form_tools_ignore_submission"])) { // now process any file fields. This is placed after the redirect query param code block above to allow whatever file upload // module to append the filename to the query string, if needed extract(ft_process_hook_calls("manage_files", compact("form_id", "submission_id", "file_fields", "redirect_query_params"), array("success", "message", "redirect_query_params")), EXTR_OVERWRITE); // send any emails ft_send_emails("on_submission", $form_id, $submission_id); } // if the redirect URL has been specified either in the database or as part of the form // submission, redirect the user [form submission form_tools_redirect_url value overrides // database value] if (!empty($form_info["redirect_url"]) || !empty($form_data["form_tools_redirect_url"])) { // build redirect query string $redirect_url = isset($form_data["form_tools_redirect_url"]) && !empty($form_data["form_tools_redirect_url"]) ? $form_data["form_tools_redirect_url"] : $form_info["redirect_url"]; $query_str = ""; if (!empty($redirect_query_params)) { $query_str = join("&", $redirect_query_params); } if (!empty($query_str)) { // only include the ? if it's not already there if (strpos($redirect_url, "?")) { $redirect_url .= "&" . $query_str; } else { $redirect_url .= "?" . $query_str; } } header("Location: " . $redirect_url); exit; } // the user should never get here! This means that the no redirect URL has been specified $page_vars = array("message_type" => "error", "message" => $LANG["processing_no_redirect_url"]); ft_display_page("error.tpl", $page_vars); exit; }