/** * Used in generating the filenames; this builds most of the placeholder values (the date-oriented ones) * to which the form and export-specific placeholders are added. * * @return array the placeholder array */ function exp_get_export_filename_placeholder_hash() { $offset = ft_get_current_timezone_offset(); $date_str = ft_get_date($offset, ft_get_current_datetime(), "Y|y|F|M|m|n|d|D|j|g|h|H|i|s|U|a|G|i"); list($Y, $y, $F, $M, $m, $n, $d, $D, $j, $g, $h, $H, $i, $s, $U, $a, $G, $i) = explode("|", $date_str); $placeholders = array("datetime" => "{$Y}-{$m}-{$d}.{$H}-{$i}-{$s}", "date" => "{$Y}-{$m}-{$d}", "time" => "{$H}-{$i}-{$s}", "Y" => $Y, "y" => $y, "F" => $F, "M" => $M, "m" => $m, "G" => $G, "i" => $i, "n" => $n, "d" => $d, "D" => $D, "j" => $j, "g" => $g, "h" => $h, "H" => $H, "s" => $s, "U" => $U, "a" => $a); return $placeholders; }
/** * Updates an individual form submission. Called by both clients and administrator. * * @param array $infohash This parameter should be a hash (e.g. $_POST or $_GET) containing the * various fields from the update submission page. The contents of it change for each * form and form View, of course. * @return array Returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> */ function ft_update_submission($form_id, $submission_id, $infohash) { global $g_table_prefix, $g_multi_val_delimiter, $LANG; $success = true; $message = $LANG["notify_form_submission_updated"]; $infohash = ft_sanitize($infohash); extract(ft_process_hook_calls("start", compact("form_id", "submission_id", "infohash"), array("infohash")), EXTR_OVERWRITE); $field_ids = array(); if (!empty($infohash["field_ids"])) { $field_ids = explode(",", $infohash["field_ids"]); } // perform any server-side validation $errors = ft_validate_submission($form_id, $infohash["editable_field_ids"], $infohash); // if there are any problems, return right away if (!empty($errors)) { $success = false; array_walk($errors, create_function('&$el', '$el = "• " . $el;')); $message = implode("<br />", $errors); return array($success, $message); } $form_fields = ft_get_form_fields($form_id); $field_types_processing_info = ft_get_field_type_processing_info(); // this gets all settings for the fields, taking into account whatever has been overridden $field_settings = ft_get_form_field_field_type_settings($field_ids, $form_fields); $db_column_names = array(); $now = ft_get_current_datetime(); $query = array(); $query[] = "last_modified_date = '{$now}'"; $file_fields = array(); foreach ($form_fields as $row) { $field_id = $row["field_id"]; // if the field ID isn't in the page's tab, ignore it if (!in_array($field_id, $field_ids)) { continue; } // if the field ID isn't editable, the person's being BAD and trying to hack a field value. Ignore it. if (!in_array($field_id, $infohash["editable_field_ids"])) { continue; } // if this is a FILE field that doesn't have any overridden PHP processing code, just store the info // about the field. Presumably, the module / field type has registered the appropriate hooks for // processing the file. Without it, the module wouldn't work. We pass that field + file into to the hook. if ($field_types_processing_info[$row["field_type_id"]]["is_file_field"] == "yes") { $file_data = array("field_id" => $field_id, "field_info" => $row, "data" => $infohash, "code" => $field_types_processing_info[$row["field_type_id"]]["php_processing"], "settings" => $field_settings[$field_id]); if (empty($field_types_processing_info[$row["field_type_id"]]["php_processing"])) { $file_fields[] = $file_data; continue; } else { $value = ft_process_form_field($file_data); $query[] = $row["col_name"] . " = '{$value}'"; } } if ($row["field_name"] == "core__submission_date" || $row["col_name"] == "core__last_modified") { if (!isset($infohash[$row["field_name"]]) || empty($infohash[$row["field_name"]])) { continue; } } // see if this field type has any special PHP processing to do if (!empty($field_types_processing_info[$row["field_type_id"]]["php_processing"])) { $data = array("field_info" => $row, "data" => $infohash, "code" => $field_types_processing_info[$row["field_type_id"]]["php_processing"], "settings" => $field_settings[$field_id], "account_info" => isset($_SESSION["ft"]["account"]) ? $_SESSION["ft"]["account"] : array()); $value = ft_process_form_field($data); $query[] = $row["col_name"] . " = '{$value}'"; } else { if (isset($infohash[$row["field_name"]])) { if (is_array($infohash[$row["field_name"]])) { $query[] = $row["col_name"] . " = '" . implode("{$g_multi_val_delimiter}", $infohash[$row["field_name"]]) . "'"; } else { $query[] = $row["col_name"] . " = '" . $infohash[$row["field_name"]] . "'"; } } else { $query[] = $row["col_name"] . " = ''"; } } } $set_query = join(",\n", $query); $query = "\n UPDATE {$g_table_prefix}form_{$form_id}\n SET {$set_query}\n WHERE submission_id = {$submission_id}\n "; $result = mysql_query($query); // if there was a problem updating the submission, don't even bother calling the file upload hook. Just exit right away if (!$result) { return array(false, $LANG["notify_submission_not_updated"]); } // now process any file fields extract(ft_process_hook_calls("manage_files", compact("form_id", "submission_id", "file_fields"), array("success", "message")), EXTR_OVERWRITE); // send any emails ft_send_emails("on_edit", $form_id, $submission_id); extract(ft_process_hook_calls("end", compact("form_id", "submission_id", "infohash"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
/** * This function sets up the main form values in preparation for a test submission by the actual * form. It is called from step 2 of the form creation page for totally new forms - forms that don't * have an * * @param array $info this parameter should be a hash (e.g. $_POST or $_GET) containing the * various fields from the step 1 add form page. * @return array Returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> * [2]: new form ID (success only) */ function ft_setup_form($info) { global $g_table_prefix, $g_debug, $LANG; $success = true; $message = ""; $info = ft_sanitize($info); // check required $info fields. This changes depending on the form type (external / internal). Validation // for the internal forms is handled separately [inelegant!] $rules = array(); if ($info["form_type"] == "external") { $rules[] = "required,form_name,{$LANG["validation_no_form_name"]}"; $rules[] = "required,access_type,{$LANG["validation_no_access_type"]}"; } $errors = validate_fields($info, $rules); // if there are errors, piece together an error message string and return it if (!empty($errors)) { $success = false; array_walk($errors, create_function('&$el', '$el = "• " . $el;')); $message = join("<br />", $errors); return array($success, $message, ""); } // extract values $form_type = $info["form_type"]; $access_type = $info["access_type"]; $submission_type = isset($info["submission_type"]) ? "'{$info["submission_type"]}'" : "NULL"; $user_ids = isset($info["selected_client_ids"]) ? $info["selected_client_ids"] : array(); $form_name = trim($info["form_name"]); $is_multi_page_form = isset($info["is_multi_page_form"]) ? $info["is_multi_page_form"] : "no"; $redirect_url = isset($info["redirect_url"]) ? trim($info["redirect_url"]) : ""; $phrase_edit_submission = ft_sanitize($LANG["phrase_edit_submission"]); if ($is_multi_page_form == "yes") { $form_url = $info["multi_page_urls"][0]; } else { // this won't be defined for Internal forms $form_url = isset($info["form_url"]) ? $info["form_url"] : ""; } $now = ft_get_current_datetime(); $query = "\n INSERT INTO {$g_table_prefix}forms (form_type, access_type, submission_type, date_created, is_active, is_complete,\n is_multi_page_form, form_name, form_url, redirect_url, edit_submission_page_label)\n VALUES ('{$form_type}', '{$access_type}', {$submission_type}, '{$now}', 'no', 'no', '{$is_multi_page_form}', '{$form_name}',\n '{$form_url}', '{$redirect_url}', '{$phrase_edit_submission}')\n "; $result = mysql_query($query) or ft_handle_error("Failed query in <b>" . __FUNCTION__ . "</b>, line " . __LINE__ . ": <i>{$query}</i>", mysql_error()); $new_form_id = mysql_insert_id(); // now store which clients are assigned to this form [remove any old ones first] foreach ($user_ids as $user_id) { $query = mysql_query("\n INSERT INTO {$g_table_prefix}client_forms (account_id, form_id)\n VALUES ({$user_id}, {$new_form_id})\n "); } // if this is a multi-page form, add the list of pages in the form mysql_query("DELETE FROM {$g_table_prefix}multi_page_form_urls WHERE form_id = {$new_form_id}"); if ($is_multi_page_form == "yes") { $page_num = 1; foreach ($info["multi_page_urls"] as $url) { if (empty($url)) { continue; } mysql_query("INSERT INTO {$g_table_prefix}multi_page_form_urls (form_id, form_url, page_num) VALUES ({$new_form_id}, '{$url}', {$page_num})"); $page_num++; } } return array($success, $message, $new_form_id); }
/** * Updates the last logged in date for an account. * * @param $account_id */ function ft_update_last_logged_in($account_id) { global $g_table_prefix; $account_id = ft_sanitize($account_id); if (!is_numeric($account_id)) { return; } $now = ft_get_current_datetime(); @mysql_query("\r\n UPDATE {$g_table_prefix}accounts\r\n SET last_logged_in = '{$now}'\r\n WHERE account_id = {$account_id}\r\n "); }
/** * 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, ""); }
/** * 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; }
/** * This function is called from the main Modules page. It upgrades an individual * module. */ function ft_upgrade_module($module_id) { global $LANG, $g_root_url, $g_root_dir, $g_table_prefix; $module_info = ft_get_module($module_id); $module_folder = $module_info["module_folder"]; $module_name = $module_info["module_name"]; $old_module_version_date = $module_info["module_date"]; $current_db_version = $module_info["version"]; $info = ft_get_module_info_file_contents($module_folder); $new_version = $info["version"]; if ($current_db_version == $new_version) { return array(false, ""); } // if the module has its own upgrade function, call it. In Oct 2011, a BIG problem was identified // in the way modules were being updated. For backward compatibility, the new upgrade function // must be named [module folder]__update (not ...__upgrade). if the __update function is defined, // it will be called instead of the older __upgrade one. @(include_once "{$g_root_dir}/modules/{$module_folder}/library.php"); // NEW "update" function $update_function_name = "{$module_folder}__update"; if (function_exists($update_function_name)) { list($success, $message) = $update_function_name($module_info, $info); if (!$success) { return array($success, $message); } } else { // OLD "upgrade" function $upgrade_function_name = "{$module_folder}__upgrade"; if (function_exists($upgrade_function_name)) { $upgrade_function_name($current_db_version, $new_version); } } // now, update the main module record $info = ft_sanitize($info); // we're assuming the module developer hasn't removed any of the required fields... // now check the language file contains the two required fields: module_name and module_description $lang_file = "{$g_root_dir}/modules/{$module_folder}/lang/{$info["origin_language"]}.php"; $lang_info = _ft_get_module_lang_file_contents($lang_file); $lang_info = ft_sanitize($lang_info); // check the required language file fields if (!isset($lang_info["module_name"]) || empty($lang_info["module_name"]) || (!isset($lang_info["module_description"]) || empty($lang_info["module_description"]))) { return; } $author = $info["author"]; $author_email = $info["author_email"]; $author_link = $info["author_link"]; $module_version = $info["version"]; $module_date = $info["date"]; $origin_language = $info["origin_language"]; $nav = $info["nav"]; $module_name = $lang_info["module_name"]; $module_description = $lang_info["module_description"]; // convert the date into a MySQL datetime list($year, $month, $day) = explode("-", $module_date); $timestamp = mktime(null, null, null, $month, $day, $year); $module_datetime = ft_get_current_datetime($timestamp); @mysql_query("\n UPDATE {$g_table_prefix}modules\n SET origin_language = '{$origin_language}',\n module_name = '{$module_name}',\n version = '{$module_version}',\n author = '{$author}',\n author_email = '{$author_email}',\n author_link = '{$author_link}',\n description = '{$module_description}',\n module_date = '{$module_datetime}'\n WHERE module_id = {$module_id}\n ") or die(mysql_error()); // remove and update the navigation links for this module @mysql_query("DELETE FROM {$g_table_prefix}module_menu_items WHERE module_id = {$module_id}"); $order = 1; while (list($lang_file_key, $info) = each($nav)) { $url = $info[0]; $is_submenu = $info[1] ? "yes" : "no"; if (empty($lang_file_key) || empty($url)) { continue; } $display_text = isset($lang_info[$lang_file_key]) ? $lang_info[$lang_file_key] : $LANG[$lang_file_key]; mysql_query("\n INSERT INTO {$g_table_prefix}module_menu_items (module_id, display_text, url, is_submenu, list_order)\n VALUES ({$module_id}, '{$display_text}', '{$url}', '{$is_submenu}', {$order})\n ") or die(mysql_error()); $order++; } // And we're done! inform the user that it's been upgraded $placeholders = array("module" => $module_name, "version" => $new_version, "link" => "{$g_root_url}/modules/{$module_folder}"); $message = ft_eval_smarty_string($LANG["notify_module_updated"], $placeholders); return array(true, $message); }