示例#1
0
/**
 * Added in 2.1.0, this creates an Internal form with a handful of custom settings.
 *
 * @param $info the POST request containing the form name, number of fields and access type.
 */
function ft_create_internal_form($request)
{
    global $LANG, $g_table_prefix;
    $rules = array();
    $rules[] = "required,form_name,{$LANG["validation_no_form_name"]}";
    $rules[] = "required,num_fields,{$LANG["validation_no_num_form_fields"]}";
    $rules[] = "digits_only,num_fields,{$LANG["validation_invalid_num_form_fields"]}";
    $rules[] = "required,access_type,{$LANG["validation_no_access_type"]}";
    $errors = validate_fields($request, $rules);
    if (!empty($errors)) {
        array_walk($errors, create_function('&$el', '$el = "•  " . $el;'));
        $message = join("<br />", $errors);
        return array(false, $message);
    }
    $info = ft_sanitize($request);
    $config = array("form_type" => "internal", "form_name" => $info["form_name"], "access_type" => $info["access_type"]);
    // set up the entry for the form
    list($success, $message, $new_form_id) = ft_setup_form($config);
    $form_data = array("form_tools_form_id" => $new_form_id, "form_tools_display_notification_page" => false);
    for ($i = 1; $i <= $info["num_fields"]; $i++) {
        $form_data["field{$i}"] = $i;
    }
    ft_initialize_form($form_data);
    $infohash = array();
    $form_fields = ft_get_form_fields($new_form_id);
    $order = 1;
    // if the user just added a form with a lot of fields (over 50), the database row size will be too
    // great. Varchar fields (which with utf-8 equates to 1220 bytes) in a table can have a combined row
    // size of 65,535 bytes, so 53 is the max. The client-side validation limits the number of fields to
    // 1000. Any more will throw an error.
    $field_size_clause = $info["num_fields"] > 50 ? ", field_size = 'small'" : "";
    $field_name_prefix = ft_sanitize($LANG["word_field"]);
    foreach ($form_fields as $field_info) {
        if (preg_match("/field(\\d+)/", $field_info["field_name"], $matches)) {
            $field_id = $field_info["field_id"];
            mysql_query("\n        UPDATE {$g_table_prefix}form_fields\n        SET    field_title = '{$field_name_prefix} {$order}',\n              col_name = 'col_{$order}'\n              {$field_size_clause}\n        WHERE  field_id = {$field_id}\n      ");
            $order++;
        }
    }
    ft_finalize_form($new_form_id);
    // if the form has an access type of "private" add whatever client accounts the user selected
    if ($info["access_type"] == "private") {
        $selected_client_ids = $info["selected_client_ids"];
        $queries = array();
        foreach ($selected_client_ids as $client_id) {
            $queries[] = "({$client_id}, {$new_form_id})";
        }
        if (!empty($queries)) {
            $insert_values = implode(",", $queries);
            mysql_query("\n        INSERT INTO {$g_table_prefix}client_forms (account_id, form_id)\n        VALUES {$insert_values}\n          ");
        }
    }
    return array(true, $LANG["notify_internal_form_created"], $new_form_id);
}
示例#2
0
/**
 * 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, "");
}
示例#3
0
// if the API is supplied, include it as well
$folder = dirname(__FILE__);
@(include_once "{$folder}/global/api/api.php");
// check we're receiving something
if (empty($_POST)) {
    $page_vars = array("message_type" => "error", "message" => $LANG["processing_no_post_vars"]);
    ft_display_page("error.tpl", $page_vars);
    exit;
} else {
    if (empty($_POST["form_tools_form_id"])) {
        $page_vars = array("message_type" => "error", "message" => $LANG["processing_no_form_id"]);
        ft_display_page("error.tpl", $page_vars);
        exit;
    } else {
        if (isset($_POST["form_tools_initialize_form"])) {
            ft_initialize_form($_POST);
        } else {
            ft_process_form($_POST);
        }
    }
}
// -------------------------------------------------------------------------------------------------
/**
 * 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"];