/** * This constructs and sends the email from an individual email template for a single form * submission. * * @param integer $form_id * @param integer $submission_id * @param integer $email_id */ function ft_process_email_template($form_id, $submission_id, $email_id) { list($success, $email_components) = ft_get_email_components($form_id, $submission_id, $email_id); if (!$success) { return array(false, "Email components not returned properly (ft_get_email_components)."); } extract(ft_process_hook_calls("start", compact("form_id", "submission_id", "email_id", "email_components"), array("email_components")), EXTR_OVERWRITE); // if Swift Mailer is enabled, send the emails with that $continue = true; if (ft_check_module_enabled("swift_mailer")) { $sm_settings = ft_get_module_settings("", "swift_mailer"); if (isset($sm_settings["swiftmailer_enabled"]) && $sm_settings["swiftmailer_enabled"] == "yes") { ft_include_module("swift_mailer"); list($success, $message) = swift_send_email($email_components); $continue = false; } } // if it was sent (or was attempted to have been sent) by the Swift Mailer module, stop here if (!$continue) { return array($success, $message); } $eol = _ft_get_email_eol_char(); $recipient_list = array(); foreach ($email_components["to"] as $to_info) { $recipient_list[] = $to_info["recipient_line"]; } $to = join(", ", $recipient_list); $to = htmlspecialchars_decode($to); if (empty($to)) { return array(false, "No main recipient specified."); } $headers = "MIME-Version: 1.0{$eol}"; if (!empty($email_components["from"])) { $from = htmlspecialchars_decode($email_components["from"]["recipient_line"]); $headers .= "From: {$from}{$eol}"; } if (!empty($email_components["reply_to"])) { $reply_to = htmlspecialchars_decode($email_components["reply_to"]["recipient_line"]); $headers .= "Reply-to: {$reply_to}{$eol}"; } if (!empty($email_components["cc"])) { $cc_list = array(); foreach ($email_components["cc"] as $cc_info) { $cc_list[] = $cc_info["recipient_line"]; } $cc = join(", ", $cc_list); $cc = htmlspecialchars_decode($cc); $headers .= "Cc: {$cc}{$eol}"; } if (!empty($email_components["bcc"])) { $bcc_list = array(); foreach ($email_components["bcc"] as $bcc_info) { $bcc_list[] = $bcc_info["recipient_line"]; } $bcc = join(", ", $bcc_list); $bcc = htmlspecialchars_decode($bcc); $headers .= "Bcc: {$bcc}{$eol}"; } $message = ""; $html_content = isset($email_components["html_content"]) ? $email_components["html_content"] : ""; $text_content = isset($email_components["text_content"]) ? $email_components["text_content"] : ""; $html_content = trim($html_content); $text_content = trim($text_content); // if there's no TO line or there's no email content for either types, we can't send the email if (empty($html_content) && empty($text_content)) { return array(false, "No text or HTML email content specified"); } if (!empty($html_content) && !empty($text_content)) { $headers .= _ft_get_multipart_message($html_content, $text_content, $eol); } else { if (!empty($html_content)) { $message = $html_content; $headers .= "Content-type: text/html; charset=UTF-8"; } else { if (!empty($text_content)) { $message = $text_content; $headers .= "Content-type: text/plain; charset=UTF-8"; } } } $subject = $email_components["subject"]; // send the email $email_sent = @mail("{$to}", $subject, $message, $headers); if ($email_sent) { return array(true, ""); } else { return array(false, "The mail() function failed to send the email."); } }
<?php require "../../global/session_start.php"; // this just checks that SOMEONE's logged in - even someone via the Submission Accounts module ft_check_permission("user"); ft_include_module("pages"); $request = array_merge($_POST, $_GET); $page_id = $request["id"]; $page_info = pg_get_page($page_id); // check permissions! The above code handles booting a user out if they're not logged in, // so the only case we're worried about $account_type = isset($_SESSION["ft"]["account"]["account_type"]) ? $_SESSION["ft"]["account"]["account_type"] : ""; $account_id = isset($_SESSION["ft"]["account"]["account_id"]) ? $_SESSION["ft"]["account"]["account_id"] : ""; if ($account_type == "client" && $page_info["access_type"] == "private") { if (!in_array($account_id, $page_info["clients"])) { ft_handle_error("Sorry, you do not have permissions to see this page."); exit; } } $content = $page_info["content"]; switch ($page_info["content_type"]) { case "php": ob_start(); eval($page_info["content"]); $content = ob_get_contents(); ob_end_clean(); break; case "smarty": $content = ft_eval_smarty_string($page_info["content"]); break; }
<?php /** * Export.php * * This file does the actual generation of the content for view / display by the user. It calls the * export.tpl found in the /modules/export_manager/templates folder. */ require_once realpath(dirname(__FILE__) . "/../../global/session_start.php"); ft_include_module("export_manager"); $request = array_merge($_POST, $_GET); // passed in explicitly via POST or GET $export_group_id = isset($request["export_group_id"]) ? $request["export_group_id"] : ""; $export_type_id = isset($request["export_type_id"]) ? $request["export_type_id"] : ""; $results = isset($request["export_group_{$export_group_id}_results"]) ? $request["export_group_{$export_group_id}_results"] : "all"; // drawn from sessions $form_id = isset($_SESSION["ft"]["curr_form_id"]) ? $_SESSION["ft"]["curr_form_id"] : ""; $view_id = isset($_SESSION["ft"]["form_{$form_id}_view_id"]) ? $_SESSION["ft"]["form_{$form_id}_view_id"] : ""; $order = isset($_SESSION["ft"]["current_search"]["order"]) ? $_SESSION["ft"]["current_search"]["order"] : ""; $search_fields = isset($_SESSION["ft"]["current_search"]["search_fields"]) ? $_SESSION["ft"]["current_search"]["search_fields"] : array(); $export_group_results = ft_load_module_field("export_manager", "export_group_{$export_group_id}_results", "export_group_{$export_group_id}_results"); // if any of the required fields weren't entered, just output a simple blank message if (empty($form_id) || empty($view_id) || empty($order) || empty($search_fields) || empty($export_group_id)) { echo $LANG["export_manager"]["notify_export_incomplete_fields"]; exit; } set_time_limit(300); // if the user only wants to display the currently selected rows, limit the query to those submission IDs $submission_ids = array(); if ($results == "selected") { $submission_ids = $_SESSION["ft"]["form_{$form_id}_selected_submissions"];
/** * Builds a dropdown of available pages for a client. This is used by the administrator * to display the list of pages available for the clients menus, etc. * * @param string $selected * @param array $attributes * @param array $omit_pages */ function ft_get_client_menu_pages_dropdown($selected, $attributes, $omit_pages = array()) { global $LANG; // stores the non-option lines of the select box: <select>, </select> and the optgroups $select_lines = array(); $select_lines[] = array("type" => "select_open"); if (!in_array("", $omit_pages)) { $select_lines[] = array("type" => "option", "v" => $LANG["phrase_please_select"]); } if (!in_array("custom_url", $omit_pages)) { $select_lines[] = array("type" => "optgroup_open", "label" => $LANG["word_custom"]); $select_lines[] = array("type" => "option", "k" => "custom_url", "v" => $LANG["phrase_custom_url"]); $select_lines[] = array("type" => "optgroup_close"); } $select_lines[] = array("type" => "optgroup_open", "label" => $LANG["word_main"]); if (!in_array("client_forms", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "client_forms", "v" => $LANG["word_forms"]); } if (!in_array("client_form_submissions", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "client_form_submissions", "v" => $LANG["phrase_form_submissions"]); } if (!in_array("client_account", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "client_account", "v" => $LANG["word_account"]); } if (!in_array("client_account_login", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "client_account_login", "v" => $LANG["phrase_login_info"]); } if (!in_array("client_account_settings", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "client_account_settings", "v" => $LANG["phrase_account_settings"]); } if (!in_array("logout", $omit_pages)) { $select_lines[] = array("type" => "option", "k" => "logout", "v" => $LANG["word_logout"]); } $select_lines[] = array("type" => "optgroup_close"); // if the Pages module is enabled, display any custom pages that have been defined. Only show the optgroup // if there's at least ONE page defined if (ft_check_module_enabled("pages")) { ft_include_module("pages"); $pages_info = pg_get_pages("all"); $pages = $pages_info["results"]; if (count($pages) > 0) { $select_lines[] = array("type" => "optgroup_open", "label" => $LANG["phrase_pages_module"]); foreach ($pages as $page) { $page_id = $page["page_id"]; $page_name = $page["page_name"]; $select_lines[] = array("type" => "option", "k" => "page_{$page_id}", "v" => $page_name); } $select_lines[] = array("type" => "optgroup_close"); } } extract(ft_process_hook_calls("middle", compact("select_lines"), array("select_lines")), EXTR_OVERWRITE); $select_lines[] = array("type" => "select_close"); // now build the HTML $dd = ""; foreach ($select_lines as $line) { switch ($line["type"]) { case "select_open": $attribute_str = ""; while (list($key, $value) = each($attributes)) { $attribute_str .= " {$key}=\"{$value}\""; } $dd .= "<select {$attribute_str}>"; break; case "select_close": $dd .= "</select>"; break; case "optgroup_open": $dd .= "<optgroup label=\"{$line["label"]}\">"; break; case "optgroup_close": $dd .= "</optgroup>"; break; case "option": $key = $line["k"]; $value = $line["v"]; $dd .= "<option value=\"{$key}\"" . ($selected == $key ? " selected" : "") . ">{$value}</option>\n"; break; } } return $dd; }
/** * Used by the "forget password?" page to have a client's login information sent to them. * * @param array $info the $_POST containing a "username" key. That value is used to find the user * account information to email them. * @return array [0]: true/false (success / failure) * [1]: message string */ function ft_send_password($info) { global $g_root_url, $g_root_dir, $g_table_prefix, $LANG; $info = ft_sanitize($info); extract(ft_process_hook_calls("start", compact("info"), array("info")), EXTR_OVERWRITE); $success = true; $message = $LANG["notify_login_info_emailed"]; if (!isset($info["username"]) || empty($info["username"])) { $success = false; $message = $LANG["validation_no_username_or_js"]; return array($success, $message); } $username = $info["username"]; $query = mysql_query("\r\n SELECT *\r\n FROM {$g_table_prefix}accounts\r\n WHERE username = '******'\r\n "); // not found if (!mysql_num_rows($query)) { $success = false; $message = $LANG["validation_account_not_recognized_info"]; return array($success, $message); } $account_info = mysql_fetch_assoc($query); $email = $account_info["email"]; // one final check: confirm the email is defined & valid if (empty($email) || !ft_is_valid_email($email)) { $success = false; $message = $LANG["validation_email_not_found_or_invalid"]; return array($success, $message); } $account_id = $account_info["account_id"]; $username = $account_info["username"]; $new_password = ft_generate_password(); $encrypted_password = md5(md5($new_password)); // update the database with the new password (encrypted). As of 2.1.0 there's a second field to store the // temporary generated password, leaving the original password intact. This prevents a situation arising when // someone other than the admin / client uses the "Forget Password" feature and invalidates a valid, known password. // Any time the user successfully logs in, mysql_query("\r\n UPDATE {$g_table_prefix}accounts\r\n SET temp_reset_password = '******'\r\n WHERE account_id = {$account_id}\r\n "); // now build and sent the email // 1. build the email content $placeholders = array("login_url" => "{$g_root_url}/?id={$account_id}", "email" => $email, "username" => $username, "new_password" => $new_password); $smarty_template_email_content = file_get_contents("{$g_root_dir}/global/emails/forget_password.tpl"); $email_content = ft_eval_smarty_string($smarty_template_email_content, $placeholders); // 2. build the email subject line $placeholders = array("program_name" => ft_get_settings("program_name")); $smarty_template_email_subject = file_get_contents("{$g_root_dir}/global/emails/forget_password_subject.tpl"); $email_subject = trim(ft_eval_smarty_string($smarty_template_email_subject, $placeholders)); // if Swift Mailer is enabled, send the emails with that. In case there's a problem sending the message with // Swift, it falls back the default mail() function. $swift_mail_error = false; $swift_mail_enabled = ft_check_module_enabled("swift_mailer"); if ($swift_mail_enabled) { $sm_settings = ft_get_module_settings("", "swift_mailer"); if ($sm_settings["swiftmailer_enabled"] == "yes") { ft_include_module("swift_mailer"); // get the admin info. We'll use that info for the "from" and "reply-to" values. Note // that we DON'T use that info for the regular mail() function. This is because retrieving // the password is important functionality and we don't want to cause problems that could // prevent the email being sent. Many servers don't all the 4th headers parameter of the mail() // function $admin_info = ft_get_admin_info(); $admin_email = $admin_info["email"]; $email_info = array(); $email_info["to"] = array(); $email_info["to"][] = array("email" => $email); $email_info["from"] = array(); $email_info["from"]["email"] = $admin_email; $email_info["subject"] = $email_subject; $email_info["text_content"] = $email_content; list($success, $sm_message) = swift_send_email($email_info); // if the email couldn't be sent, display the appropriate error message. Otherwise // the default success message is used if (!$success) { $swift_mail_error = true; $message = $sm_message; } } } // if there was an error sending with Swift, or if it wasn't installed, send it by mail() if (!$swift_mail_enabled || $swift_mail_error) { // send email [note: the double quotes around the email recipient and content are intentional: some systems fail without it] if (!@mail("{$email}", $email_subject, $email_content)) { $success = false; $message = $LANG["notify_email_not_sent"]; return array($success, $message); } } extract(ft_process_hook_calls("end", compact("success", "message", "info"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
/** * This function lets you display the content generated from an export type into a webpage. You can * use this function on any export type in the database - even the ones that have been marked as "hidden". Note: * this function requires the Export Manager to be installed and enabled. * * @param integer $form_id * @param integer $view_id * @param integer $export_type_id * @param integer $page_num (defaults to 1) * @param array $options optional parameter that lets you configure the appearance of the data in a variety of ways. * * num_per_page - (integer) by default, it returns the number of results per page specified by * the View. This setting overrides that. * submission_ids - (integer or array of integers) this limits the results returned to the submission ID * or submission IDs specified in this field * order - (string) the database column name with a -DESC or -ASC suffix (e.g. col_1-ASC). * page_num_identifier - (string) passed via the query string to denote what page it's on (default: "page") * show_columns_only - (boolean) limits the fields that are displayed to those fields marked as "Column" * in the View. Defaults to false. * return_as_string - (boolean) if this value is set to true, instead of outputting the result it returns * the HTML as a string. * pagination_theme - (string) the pagination links (<< 1 2 3 ...) HTML is generated by the pagination.tpl * template, found in each of the theme folders. Generally this file is the same for * all themes, but in case it isn't, this setting lets you choose the theme folder with * which to render the HTML. * pagination_location - (string) accepts the values "top" (the default), "bottom", "both" or "none". This * determines where (if anywhere) the pagination links should appear. By default it only * appears at the top of the page, but you can set this value to either "both" or "bottom" * to have it appear there instead / as well. * * @return mixed the return value of this function depends on the API settings & the options passed to it. Namely: * * If error: * if $g_api_debug == true, the error page will be displayed displaying the error code. * if $g_api_debug == false, it returns an array with two indexes: * [0] false * [1] the API error code * If successful: * if "return_as_string" option key is set, it returns an array with two indexes: * [0] true * [1] the HTML content * if "return_as_string" not set, it just prints the HTML to the page (the default behaviour) */ function ft_api_show_submissions($form_id, $view_id, $export_type_id, $page_num = 1, $options = array()) { global $g_table_prefix, $LANG, $g_api_debug, $g_smarty; // sanitize all incoming data $form_id = ft_sanitize($form_id); $view_id = ft_sanitize($view_id); $export_type_id = ft_sanitize($export_type_id); $page_num = ft_sanitize($page_num); $options = ft_sanitize($options); // check the Export Manager module is enabled if (ft_check_module_enabled("export_manager")) { ft_include_module("export_manager"); } else { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 400, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 400); } } // check the form ID, View ID and export ID are valid $form_query = mysql_query("SELECT count(*) as c FROM {$g_table_prefix}forms WHERE form_id = {$form_id}"); $result = mysql_fetch_assoc($form_query); $form_found = $result["c"] == 1 ? true : false; if (!$form_found) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 401, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 401); } } $view_query = mysql_query("SELECT count(*) as c FROM {$g_table_prefix}views WHERE form_id = {$form_id} AND view_id = {$view_id}"); $result = mysql_fetch_assoc($view_query); $view_found = $result["c"] == 1 ? true : false; if (!$view_found) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 402, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 402); } } $export_type_query = mysql_query("SELECT count(*) as c FROM {$g_table_prefix}module_export_types WHERE export_type_id = {$export_type_id}"); $result = mysql_fetch_assoc($export_type_query); $export_type_found = $result["c"] == 1 ? true : false; if (!$export_type_found) { if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 403, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 403); } } // okay, now lets figure out what needs to be displayed & rendered $form_info = ft_get_form($form_id); $form_fields = ft_get_form_fields($form_id, array("include_field_type_info" => true, "include_field_settings" => true)); $view_info = ft_get_view($view_id); $export_type_info = exp_get_export_type($export_type_id); $export_group_id = $export_type_info["export_group_id"]; $export_group_info = exp_get_export_group($export_group_id); // number of submissions per page (an integer or "all") $num_per_page = $view_info["num_submissions_per_page"]; if (isset($options["num_per_page"])) { $num_per_page = $options["num_per_page"]; } $order = "{$view_info["default_sort_field"]}-{$view_info["default_sort_field_order"]}"; if (isset($options["order"])) { $order = $options["order"]; } $display_fields = array(); $columns = "all"; if (isset($options["show_columns_only"]) && $options["show_columns_only"]) { $columns = array(); foreach ($view_info["columns"] as $view_field_info) { $curr_field_id = $view_field_info["field_id"]; foreach ($form_fields as $form_field_info) { if ($form_field_info["field_id"] != $curr_field_id) { continue; } $display_fields[] = array_merge($form_field_info, $view_field_info); $columns[] = $form_field_info["col_name"]; } } } else { foreach ($view_info["fields"] as $view_field_info) { $curr_field_id = $view_field_info["field_id"]; foreach ($form_fields as $form_field_info) { if ($form_field_info["field_id"] != $curr_field_id) { continue; } $display_fields[] = array_merge($form_field_info, $view_field_info); } } } /* $columns = "all"; if (isset($options["show_columns_only"]) && $options["show_columns_only"]) { $columns = array(); foreach ($view_info["columns"] as $view_col_info) { foreach ($display_fields as $field_info) { if ($field_info["field_id"] == $view_col_info["field_id"]) { $columns[] = $field_info["col_name"]; } } } } */ $submission_ids = array(); if (isset($options["submission_ids"])) { if (is_numeric($options["submission_ids"])) { $submission_ids[] = $options["submission_ids"]; } else { if (is_array($submission_ids)) { $submission_ids = $options["submission_ids"]; } } } // perform the almighty search query $results_info = ft_search_submissions($form_id, $view_id, $num_per_page, $page_num, $order, $columns, array(), $submission_ids); $search_num_results = $results_info["search_num_results"]; $settings = ft_get_settings(); // now build the list of information we're going to send to the export type smarty template $placeholders = exp_get_export_filename_placeholder_hash(); $placeholders["export_group_id"] = $export_group_id; $placeholders["export_type_id"] = $export_type_id; $placeholders["export_group_results"] = "all"; $placeholders["same_page"] = ft_get_clean_php_self(); $placeholders["display_fields"] = $display_fields; $placeholders["submissions"] = $results_info["search_rows"]; $placeholders["num_results"] = $results_info["search_num_results"]; $placeholders["view_num_results"] = $results_info["view_num_results"]; $placeholders["form_info"] = $form_info; $placeholders["view_info"] = $view_info; $placeholders["field_types"] = ft_get_field_types(true); $placeholders["settings"] = $settings; // ... $placeholders["date_format"] = $settings["default_date_format"]; $placeholders["timezone_offset"] = $settings["timezone_offset"]; // pull out a few things into top level placeholders for easy use $placeholders["form_name"] = $form_info["form_name"]; $placeholders["form_id"] = $form_id; $placeholders["form_url"] = $form_info["form_url"]; $placeholders["view_name"] = $view_info["view_name"]; $placeholders["view_id"] = $view_id; $placeholders["export_group_name"] = ft_create_slug(ft_eval_smarty_string($export_group_info["group_name"])); $placeholders["export_group_type"] = ft_create_slug(ft_eval_smarty_string($export_type_info["export_type_name"])); $placeholders["filename"] = ft_eval_smarty_string($export_type_info["filename"], $placeholders, "", $g_smarty->plugins_dir); $template = $export_type_info["export_type_smarty_template"]; $placeholders["export_type_name"] = $export_type_info["export_type_name"]; $export_type_smarty_template = ft_eval_smarty_string($template, $placeholders, "", $g_smarty->plugins_dir); // if we're not displaying all results on the single page, generate the pagination HTML $pagination = ""; if ($num_per_page != "all") { $page_num_identifier = isset($options["page_num_identifier"]) ? $options["page_num_identifier"] : "page"; $theme = isset($options["pagination_theme"]) ? $options["pagination_theme"] : $settings["default_theme"]; $pagination = ft_get_page_nav($search_num_results, $num_per_page, $page_num, "", $page_num_identifier, $theme); } $pagination_location = isset($options["pagination_location"]) ? $options["pagination_location"] : "top"; switch ($pagination_location) { case "top": $html = $pagination . $export_type_smarty_template; break; case "both": $html = $pagination . $export_type_smarty_template . $pagination; break; case "bottom": $html = $export_type_smarty_template . $pagination; break; case "none": $html = $export_type_smarty_template; break; // this is in case the user entered an invalid value // this is in case the user entered an invalid value default: if ($g_api_debug) { $page_vars = array("message_type" => "error", "error_code" => 404, "error_type" => "user"); ft_display_page("error.tpl", $page_vars); exit; } else { return array(false, 404); } break; } if (isset($options["return_as_string"]) && $options["return_as_string"]) { return array(true, $html); } else { echo $html; } }