function smarty_function_view_fields($params, &$smarty) { global $LANG; if (empty($params["name_id"])) { $smarty->trigger_error("assign: missing 'name_id' parameter. This is used to give the select field a name and id value."); return; } if (empty($params["form_id"])) { $smarty->trigger_error("assign: missing 'form_id' parameter."); return; } if (empty($params["view_id"])) { $smarty->trigger_error("assign: missing 'view_id' parameter."); return; } $default_value = isset($params["default"]) ? $params["default"] : ""; $onchange = isset($params["onchange"]) ? $params["onchange"] : ""; $style = isset($params["style"]) ? $params["style"] : ""; $blank_option = isset($params["blank_option"]) ? $params["blank_option"] : ""; $view_id = $params["view_id"]; $form_id = $params["form_id"]; $attributes = array("id" => $params["name_id"], "name" => $params["name_id"], "onchange" => $onchange, "style" => $style); $attribute_str = ""; while (list($key, $value) = each($attributes)) { if (!empty($value)) { $attribute_str .= " {$key}=\"{$value}\""; } } $view_fields = ft_get_view_fields($view_id); $rows = array(); if (!empty($blank_option)) { $rows[] = "<option value=\"\">{$blank_option}</option>"; } foreach ($view_fields as $field_info) { $field_title = $field_info["field_title"]; $field_id = $field_info["field_id"]; $selected = $default_value == $field_id ? "selected" : ""; $rows[] = "<option value=\"{$field_id}\" {$selected}>{$field_title}</option>"; } $dd = "<select {$attribute_str}>" . join("\n", $rows) . "</select>"; return $dd; }
/** * Retrieves everything about a form submission. It contains a lot of meta-information about the field, * from the form_fields and view_tabs. If the optional view_id parameter is included, only the fields * in the View are returned (AND all system fields, if they're not included). * * @param integer $form_id the unique form ID * @param integer $submission_id the unique submission ID * @param integer $view_id an optional view ID parameter * @return array Returns an array of hashes. Each index is a separate form field and its value is * a hash of information about it, such as value, field type, field size, etc. */ function ft_get_submission($form_id, $submission_id, $view_id = "") { global $g_table_prefix; $return_arr = array(); $form_fields = ft_get_form_fields($form_id); $submission = ft_get_submission_info($form_id, $submission_id); $view_fields = !empty($view_id) ? ft_get_view_fields($view_id) : array(); if (empty($submission)) { return array(); } $view_field_ids = array(); foreach ($view_fields as $view_field) { $view_field_ids[] = $view_field["field_id"]; } // for each field, combine the meta form info (like field size, type, data type etc) from $form_fields // with the info about the submission itself. Also, if there's a View specified, filter out any fields // that aren't used in the View foreach ($form_fields as $field_info) { $field_id = $field_info["field_id"]; // if we're looking at this submission through a View, if (!empty($view_id) && !in_array($field_id, $view_field_ids)) { continue; } // if the submission contains contents for this field, add it if (array_key_exists($field_info['col_name'], $submission)) { $field_info["content"] = $submission[$field_info['col_name']]; } // if a view ID is specified, return the view-specific field info as well if (!empty($view_id)) { $field_view_info = ft_get_view_field($view_id, $field_id); if (!empty($field_view_info)) { foreach ($field_view_info as $key => $value) { $field_info[$key] = $value; } } } $return_arr[] = $field_info; } // finally, if a View is specified, ensure that the order in which the submission fields are returned // is determined by the View. [NOT efficient!] if (!empty($view_id)) { $ordered_return_arr = array(); foreach ($view_fields as $view_field_info) { $field_id = $view_field_info["field_id"]; foreach ($return_arr as $field_info) { if ($field_info["field_id"] == $field_id) { $ordered_return_arr[] = $field_info; break; } } } $return_arr = $ordered_return_arr; } extract(ft_process_hook_calls("end", compact("form_id", "submission_id", "view_id", "return_arr"), array("return_arr")), EXTR_OVERWRITE); return $return_arr; }
/** * This handy function figures out the various components of an email and returns them in a hash: * from, reply_to, to, cc, bcc, subject, html_content and text_content * * This is used both when sending the emails but also for testing. This should be the only place that * email content is actually constructed. All other email functions should be using it, regardless of * what mechanism actually sends the email. * * @param integer $form_id * @param mixed $submission_id for non-test emails, this is included. For testing, it may be blank. * @param integer $email_id * @return array */ function ft_get_email_components($form_id, $submission_id = "", $email_id, $is_test = false, $test_settings = array()) { global $g_table_prefix, $g_root_dir, $LANG, $g_default_theme; $email_template = ft_get_email_template($email_id); // if the administrator limited the email content to fields in a particular View, pass those fields to the // template - NOT all of the form fields (which is the default) $fields_for_email_template = array(); if (!empty($email_template["limit_email_content_to_fields_in_view"])) { $view_fields = ft_get_view_fields($email_template["limit_email_content_to_fields_in_view"]); // here, $view_fields just contains the info from the view_fields table. We need the info from the form_fields // table instead - since it contains presentation information likely to be needed in the email templates $fields_for_email_template = array(); foreach ($view_fields as $view_field_info) { $fields_for_email_template[] = ft_get_form_field($view_field_info["field_id"], array("include_field_type_info" => true)); } } else { $fields_for_email_template = ft_get_form_fields($form_id, array("include_field_type_info" => true)); } // this returns a hash with three keys: html_content, text_content and submission_id $templates = _ft_get_email_template_content($form_id, $submission_id, $email_template, $is_test, $test_settings); $submission_id = $templates["submission_id"]; // unfortunately we need this, even though it was just called in _ft_get_email_template_content() $submission_info = ft_get_submission($form_id, $submission_id); // retrieve the placeholders and their substitutes $submission_placeholders = ft_get_submission_placeholders($form_id, $submission_id); $admin_info = ft_get_admin_info(); $file_info = array(); $updated_fields_for_email_template = array(); foreach ($fields_for_email_template as $field_info) { if ($field_info["is_file_field"] == "yes") { $field_id = $field_info["field_id"]; $field_settings = ft_get_field_settings($field_id); $field_info["folder_url"] = $field_settings["folder_url"]; $field_info["folder_path"] = $field_settings["folder_path"]; $filename = $field_info["field_name"]; $field_info["answer"] = $submission_placeholders["FILENAME_{$filename}"]; } $updated_fields_for_email_template[] = $field_info; } $fields_for_email_template = $updated_fields_for_email_template; $updated_fields_for_email_template = array(); foreach ($fields_for_email_template as $field_info) { while (list($placeholder, $value) = each($submission_placeholders)) { if ($placeholder != "ANSWER_{$field_info["field_name"]}") { continue; } $field_info["answer"] = $value; break; } reset($submission_placeholders); $updated_fields_for_email_template[] = $field_info; } $fields_for_email_template = $updated_fields_for_email_template; $return_info = array(); $return_info["email_id"] = $email_id; $return_info["attachments"] = array(); $smarty = new Smarty(); $smarty->template_dir = "{$g_root_dir}/global/smarty/"; $smarty->compile_dir = "{$g_root_dir}/themes/{$g_default_theme}/cache/"; $smarty->assign("LANG", $LANG); $smarty->assign("fields", $fields_for_email_template); if (!empty($templates["text"])) { list($templates["text"], $attachments) = _ft_extract_email_attachment_info($templates["text"], $form_id, $submission_placeholders); foreach ($attachments as $attachment_info) { if (!in_array($attachment_info, $return_info["attachments"])) { $return_info["attachments"][] = $attachment_info; } } $smarty->assign("eval_str", $templates["text"]); while (list($key, $value) = each($submission_placeholders)) { $smarty->assign($key, $value); } reset($submission_placeholders); $return_info["text_content"] = $smarty->fetch("eval.tpl"); } if (!empty($templates["html"])) { list($templates["html"], $attachments) = _ft_extract_email_attachment_info($templates["html"], $form_id, $submission_placeholders); foreach ($attachments as $attachment_info) { if (!in_array($attachment_info, $return_info["attachments"])) { $return_info["attachments"][] = $attachment_info; } } $smarty->assign("eval_str", $templates["html"]); while (list($key, $value) = each($submission_placeholders)) { // convert any newlines chars to page breaks for any answer fields. Hmm... if (strpos($key, "ANSWER_") === 0) { $value = nl2br($value); } $smarty->assign($key, $value); } $return_info["html_content"] = $smarty->fetch("eval.tpl"); } // compile the "to" / "from" / "reply-to" recipient list, based on this form submission. Virtually // everything is already stored in $email_template["recipients"], but needs to be extracted. // The notable exception is the FORM EMAIL FIELD information: that has to be constructed separately $return_info["to"] = array(); $return_info["cc"] = array(); $return_info["bcc"] = array(); foreach ($email_template["recipients"] as $recipient_info) { $recipient_type_key = $recipient_info["recipient_type"]; if ($recipient_info["recipient_type"] == "" || $recipient_info["recipient_type"] == "main") { $recipient_type_key = "to"; } if ($recipient_info["recipient_user_type"] == "form_email_field") { $header_info = _ft_get_form_email_field_headers($recipient_info["form_email_id"], $submission_info); $user_recipient = $header_info["recipient_line"]; $user_first_name = $header_info["first_name"]; $user_last_name = $header_info["last_name"]; $user_email = $header_info["email"]; $curr_recipient_info = array("recipient_line" => $user_recipient, "name" => "{$user_first_name} {$user_last_name}", "email" => $user_email); } else { $curr_recipient_info = array("recipient_line" => $recipient_info["final_recipient"], "name" => $recipient_info["final_name"], "email" => $recipient_info["final_email"]); } if (!empty($curr_recipient_info["email"])) { $return_info[$recipient_type_key][] = $curr_recipient_info; } } $return_info["from"] = array(); switch ($email_template["email_from"]) { case "admin": $return_info["from"] = array("recipient_line" => "{$admin_info["first_name"]} {$admin_info["last_name"]} <{$admin_info["email"]}>", "name" => "{$admin_info["first_name"]} {$admin_info["last_name"]}", "email" => $admin_info["email"]); break; case "client": $client_info = ft_get_account_info($email_template["email_from_account_id"]); $return_info["from"] = array("recipient_line" => "{$client_info["first_name"]} {$client_info["last_name"]} <{$client_info["email"]}>", "name" => "{$client_info["first_name"]} {$client_info["last_name"]}", "email" => $client_info["email"]); break; case "form_email_field": $header_info = _ft_get_form_email_field_headers($email_template["email_from_form_email_id"], $submission_info); $user_recipient = $header_info["recipient_line"]; $user_first_name = $header_info["first_name"]; $user_last_name = $header_info["last_name"]; $user_email = $header_info["email"]; $return_info["from"] = array("recipient_line" => $user_recipient, "name" => "{$user_first_name} {$user_last_name}", "email" => $user_email); break; case "custom": $return_info["from"] = array("recipient_line" => "{$email_template["custom_from_name"]} <{$email_template["custom_from_email"]}>", "name" => $email_template["custom_from_name"], "email" => $email_template["custom_from_email"]); break; } $return_info["reply_to"] = array(); switch ($email_template["email_reply_to"]) { case "admin": $return_info["reply_to"] = array("recipient_line" => "{$admin_info["first_name"]} {$admin_info["last_name"]} <{$admin_info["email"]}>", "name" => "{$admin_info["first_name"]} {$admin_info["last_name"]}", "email" => $admin_info["email"]); break; case "client": $client_info = ft_get_account_info($email_template["email_reply_to_account_id"]); $return_info["reply_to"] = array("recipient_line" => "{$client_info["first_name"]} {$client_info["last_name"]} <{$client_info["email"]}>", "name" => "{$client_info["first_name"]} {$client_info["last_name"]}", "email" => $client_info["email"]); break; case "form_email_field": $form_email_id = $email_template["email_reply_to_form_email_id"]; $header_info = _ft_get_form_email_field_headers($form_email_id, $submission_info); $user_recipient = $header_info["recipient_line"]; $user_first_name = $header_info["first_name"]; $user_last_name = $header_info["last_name"]; $user_email = $header_info["email"]; $return_info["reply_to"] = array("recipient_line" => $user_recipient, "name" => "{$user_first_name} {$user_last_name}", "email" => $user_email); break; case "custom": $return_info["reply_to"] = array("recipient_line" => "{$email_template["custom_reply_to_name"]} <{$email_template["custom_reply_to_email"]}>", "name" => $email_template["custom_reply_to_name"], "email" => $email_template["custom_reply_to_email"]); break; } $return_info["subject"] = ft_eval_smarty_string($email_template["subject"], $submission_placeholders); return array(true, $return_info); }
/** * Returns all the column names for a particular form. The optional $view_id field lets you return * only those columns that are associated with a particular View. The second optional setting * lets you only return custom form fields (everything excep submission ID, submission date, * last modified date, IP address and is_finalized) * * N.B. Updated in 2.0.0 to query the form_fields table instead of the actual form table and extract * the form column names from that. This should be quicker & allows us to return the columns in the * appropriate list_order. * * @param integer $form_id the unique form ID * @param integer $view_id (optional) if supplied, returns only those columns that appear in a * particular View * @param boolean $omit_system_fields * @return array A hash of form: [DB column name] => [column display name]. If the database * column doesn't have a display name (like with submission_id) the value is set to the same * as the key. */ function ft_get_form_column_names($form_id, $view_id = "", $omit_system_fields = false) { global $g_table_prefix; $result = mysql_query("\n SELECT col_name, field_title, is_system_field\n FROM {$g_table_prefix}form_fields\n WHERE form_id = {$form_id}\n ORDER BY list_order\n "); $view_col_names = array(); if (!empty($view_id)) { $view_fields = ft_get_view_fields($view_id); foreach ($view_fields as $field_info) { $view_col_names[] = $field_info["col_name"]; } } $col_names = array(); while ($col_info = mysql_fetch_assoc($result)) { if ($col_info["is_system_field"] == "yes" && $omit_system_fields) { continue; } if (!empty($view_id) && !in_array($col_info["col_name"], $view_col_names)) { continue; } $col_names[$col_info["col_name"]] = $col_info["field_title"]; } return $col_names; }
function smarty_function_form_view_fields_dropdown($params, &$smarty) { global $LANG; if (empty($params["name_id"])) { $smarty->trigger_error("assign: missing 'name_id' parameter. This is used to give the select field a name and id value."); return; } if (empty($params["form_id"])) { $smarty->trigger_error("assign: missing 'form_id' parameter."); return; } if (empty($params["view_id"])) { $smarty->trigger_error("assign: missing 'view_id' parameter."); return; } if (empty($params["field_types"])) { $smarty->trigger_error("assign: missing 'field_types' parameter."); return; } $default_value = isset($params["default"]) ? $params["default"] : ""; $onchange = isset($params["onchange"]) ? $params["onchange"] : ""; $style = isset($params["style"]) ? $params["style"] : ""; $blank_option_value = isset($params["blank_option_value"]) ? $params["blank_option_value"] : ""; $blank_option_text = isset($params["blank_option_text"]) ? $params["blank_option_text"] : ""; $view_id = $params["view_id"]; $form_id = $params["form_id"]; $field_types = $params["field_types"]; $attributes = array("id" => $params["name_id"], "name" => $params["name_id"], "onchange" => $onchange, "style" => $style); $attribute_str = ""; while (list($key, $value) = each($attributes)) { if (!empty($value)) { $attribute_str .= " {$key}=\"{$value}\""; } } $view_fields = ft_get_view_fields($view_id); $rows = array(); // find out which field type IDs are date fields $date_field_type_ids = array(); foreach ($field_types as $field_type_info) { if ($field_type_info["is_date_field"] == "yes") { $date_field_type_ids[] = $field_type_info["field_type_id"]; } } if (!empty($blank_option_value) && !empty($blank_option_text)) { $rows[] = "<option value=\"{$blank_option_value}\">{$blank_option_text}</option>"; } foreach ($view_fields as $field_info) { if ($field_info["is_searchable"] != "yes") { continue; } $col_name = $field_info["col_name"]; $field_title = $field_info["field_title"]; $is_date_field = in_array($field_info["field_type_id"], $date_field_type_ids) ? true : false; $suffix = ""; if ($is_date_field) { $suffix = "|date"; $selected = $default_value == "{$col_name}|date" ? "selected" : ""; } else { $selected = $default_value == $col_name ? "selected" : ""; } $rows[] = "<option value=\"{$col_name}{$suffix}\" {$selected}>{$field_title}</option>"; } $dd = "<select {$attribute_str}>" . join("\n", $rows) . "</select>"; return $dd; }
/** * This is the main server-side validation function, called whenever updating a submission. The current version (Core 2.1.9) * only performs a subset of the total validation rules; namely, those non-custom ones that * * @param array $editable_field_ids - this contains ALL editable field IDs in the form * @param array $request * @return array an array of errors, or an empty array if no errors */ function ft_validate_submission($form_id, $editable_field_ids, $request) { if (empty($editable_field_ids)) { return array(); } // get the validation rules for the current page. The use of $request["field_ids"] is a fix for bug #339; this should be handled // a lot better. The calling page (edit_submission.php amongst other) should be figuring out what fields are editable on that particular // page and passing THAT info as $editable_field_ids $editable_field_ids_on_tab = explode(",", $request["field_ids"]); // return all validation rules for items on tab, including those marked as editable == "no" $rules = ft_get_php_field_validation_rules($editable_field_ids_on_tab); // gets all form fields in this View $form_fields = ft_get_view_fields($request["view_id"]); // reorganize $form_fields to be a hash of field_id => array(form_name => "", field_tield => "") $field_info = array(); foreach ($form_fields as $curr_field_info) { $field_info[$curr_field_info["field_id"]] = array("field_name" => $curr_field_info["field_name"], "field_title" => $curr_field_info["field_title"], "is_editable" => $curr_field_info["is_editable"]); } // construct the RSV-friendly validation $validation = array(); foreach ($rules as $rule_info) { $rule = $rule_info["rsv_rule"]; $field_id = $rule_info["field_id"]; $field_name = $field_info[$field_id]["field_name"]; $field_title = $field_info[$field_id]["field_title"]; $error_message = $rule_info["error_message"]; // if this field is marked as non-editable, ignore it. We don't need to validate it if ($field_info[$field_id]["is_editable"] == "no") { continue; } $placeholders = array("field" => $field_title, "field_name" => $field_name); $error_message = ft_eval_smarty_string($error_message, $placeholders); $validation[] = "{$rule},{$field_name},{$error_message}"; } $errors = array(); if (!empty($validation)) { $form_vals = ft_sanitize($request); $errors = validate_fields($form_vals, $validation); } return $errors; }
/** * Returns all Views for a form, grouped appropriately. This function introduces a new way of handling * loads of optional params (should have implemented this a long time ago!). The second $custom_params * * @param integer $form_id * @param array a hash with any of the following keys: * account_id => if this is specified, the results will only return View groups * that have Views that a client account has access to * omit_empty_groups => (default: false) * omit_hidden_views => (default: false) * include_client => (default: false). If yes, returns assorted client information * for those that are mapped to the View * @param boolean $omit_empty_groups */ function ft_get_grouped_views($form_id, $custom_params = array()) { global $g_table_prefix; // figure out what settings $params = array("account_id" => isset($custom_params["account_id"]) ? $custom_params["account_id"] : "", "omit_empty_groups" => isset($custom_params["omit_empty_groups"]) ? $custom_params["omit_empty_groups"] : true, "omit_hidden_views" => isset($custom_params["omit_hidden_views"]) ? $custom_params["omit_hidden_views"] : false, "include_clients" => isset($custom_params["include_clients"]) ? $custom_params["include_clients"] : false); $group_query = mysql_query("\r\n SELECT group_id, group_name\r\n FROM {$g_table_prefix}list_groups lg\r\n WHERE group_type = 'form_{$form_id}_view_group'\r\n ORDER BY lg.list_order\r\n "); $info = array(); while ($row = mysql_fetch_assoc($group_query)) { $group_id = $row["group_id"]; $hidden_views_clause = $params["omit_hidden_views"] ? " AND v.access_type != 'hidden'" : ""; if (empty($params["account_id"])) { $view_query = mysql_query("\r\n SELECT *\r\n FROM {$g_table_prefix}views v\r\n WHERE v.group_id = {$group_id}\r\n {$hidden_views_clause}\r\n ORDER BY v.view_order\r\n "); } else { $view_query = mysql_query("\r\n SELECT v.*\r\n FROM {$g_table_prefix}views v\r\n WHERE v.form_id = {$form_id} AND\r\n v.group_id = {$group_id} AND\r\n (v.access_type = 'public' OR v.view_id IN (\r\n SELECT cv.view_id\r\n FROM {$g_table_prefix}client_views cv\r\n WHERE account_id = {$params["account_id"]}\r\n )) AND\r\n v.view_id NOT IN (\r\n SELECT view_id\r\n FROM {$g_table_prefix}public_view_omit_list\r\n WHERE account_id = {$params["account_id"]}\r\n )\r\n {$hidden_views_clause}\r\n ORDER BY v.view_order\r\n "); } $views = array(); while ($view_info = mysql_fetch_assoc($view_query)) { $view_id = $view_info["view_id"]; if ($params["include_clients"]) { $view_info["client_info"] = ft_get_view_clients($view_id); $view_info["client_omit_list"] = ft_get_public_view_omit_list($view_id); } $view_info["columns"] = ft_get_view_columns($view_id); $view_info["fields"] = ft_get_view_fields($view_id); $view_info["tabs"] = ft_get_view_tabs($view_id, true); $view_info["filters"] = ft_get_view_filters($view_id, "all"); $views[] = $view_info; } if (count($views) > 0 || !$params["omit_empty_groups"]) { $curr_group = array("group" => $row, "views" => $views); $info[] = $curr_group; } } return $info; }