/* * Written by: Adam Crownoble * Contact: adam@obledesign.com * Documentation: http://www.obledesign.com/form_processor * Created: 12/11/2005 * For: MODx cms (modxcms.com) * Name: FormProcessor * Version: 2 * Description: Sends form data via email and/or writes data to database * Properties: &form_chunk=Form Chunk Name;string; &form_required=Form Required Fields;string; &data_email_address=Data Email Address;string; &data_email_subject=Data Email Subject;string; &data_email_chunk=Data Email Chunk Name;string; &confirmation_page_chunk=Confirmation Page Chunk Name;string; &confirmation_email_from=Confirmation Email From Name;string; &confirmation_email_subject=Confirmation Email Subject;string; &write_database=Save in Database;int;1 */ /* License FormProcessor - A MODx snippet which sends form data via email and/or writes data to database Copyright (C) 2005 Adam Crownoble This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ if(!function_exists('check_requirements')) { // Check that all required fields have been filled function check_requirements($required, $form) { global $modx; // PSEUDO CONSTANTS $required_class = 'required'; $required_message = 'Missing [NAME]'; $required_messages = ''; $requirements_met = true; // Requirements are comma separated, turn them into an array if($required) { $required = explode(',',$required); } else { $required = array(); } foreach($required as $requirement) { if( (!isset($form[$requirement]) || !trim($form[$requirement])) && ($form[$requirement]!=='0')) { $requirement_clean = str_replace('_', ' ', $requirement); $this_required_message = str_replace('[NAME]', $requirement_clean, $required_message); // Set placeholders for the required class and message $modx->setPlaceholder("{$requirement}-required_class", $required_class); $modx->setPlaceholder("{$requirement}-required_message", $this_required_message); $required_messages .= "{$this_required_message}\n"; $requirements_met = false; } } if(!$requirements_met) { $modx->setPlaceholder('required_messages', $required_messages); } return $requirements_met; } } if(!function_exists('email_data')) { // Send an email with the collected data function email_data($to, $subject, $form, $chunk='') { global $modx; $body = ''; $today = date('l, F j'); $server_name = $_SERVER['SERVER_NAME']; $url = $modx->makeURL($modx->documentIdentifier); // Set default recipient and subject if not already set if(!$to) { $to = "webmaster@{$server_name}"; } $from = "{$modx->config['site_name']}"; if(!$subject) { $subject = "Submission from {$server_name}{$url}"; } if(isset($form['send_to'])) { unset($form['send_to']); } if(!$chunk) { // Set the body of the email message $body = << {$subject}

The following was sent from {$server_name}{$url} on {$today}.

EOD; foreach($form as $name=>$value) { $name = str_replace('_', ' ', $name); if(is_array($value)) { $value = implode(' ',$value); } $body .= << EOD; } $body .= << EOD; } else { // Get and prep the body $body = $modx->getChunk($chunk); $body = parse_string($body); } // Set the email headers $headers = "MIME-Version: 1.0\n". "Content-type: text/html; charset=iso-8859-1\n". "From: {$from}\n". "Reply-To: no-reply@{$site_name}\n". "X-Mailer: PHP/".phpversion(); // Send the email mail($to, $subject, $body, $headers); } } if(!function_exists('get_tables')) { // Get an array of tables function get_tables($like='') { global $modx; $tables = array(); $db = $modx->db->config['dbase']; $pre = $modx->db->config['table_prefix']; if($like) { $like = "LIKE '{$like}'"; } $tables_sql = "SHOW TABLES FROM {$db} {$like};"; $result = $modx->db->query($tables_sql); while($row = $modx->db->getRow($result)) { $tables[] = current($row); } return $tables; } } if(!function_exists('check_database')) { // Create database tables function check_database() { global $modx; $db_ok = false; $db_updated = false; $sql_manual = ''; $user = $modx->db->config['user']; $db = $modx->db->config['dbase']; $pre = $modx->db->config['table_prefix']; $tables = get_tables("{$pre}submission%"); if(!in_array("{$pre}submissions", $tables)) { $sql = <<db->query($sql); $sql_manual .= "{$sql}\n"; $db_updated = true; } if(!in_array("{$pre}submission_data", $tables)) { $sql = <<db->query($sql); $sql_manual .= "{$sql}\n"; $db_updated = true; } if($db_updated) { $tables = get_tables("{$pre}submission%"); } if(!in_array("{$pre}submissions", $tables) || !in_array("{$pre}submission_data", $tables)) { $modx->logEvent(0, 3, "

Unable to create tables for database storage.

Give CREATE TABLE rights to user {$user} or run the following SQL as a user with CREATE TABLE permissions

{$sql_manual}

", $source='Snippet: FormProcessor'); } else { $db_ok = true; } return $db_ok; } } if(!function_exists('write_database')) { // Write the collected data to the database function write_database($form_name, $form) { if(check_database()) { global $modx; $db = $modx->db->config['dbase']; $pre = $modx->db->config['table_prefix']; $url = $modx->makeURL($modx->documentIdentifier); $user_key = ($modx->getLoginUserID() ? $modx->getLoginUserID() : 0); $time = time(); // Remove the send_to FormProcessor stuff if it's still there if(isset($form['send_to'])) { unset($form['send_to']); } // Check that POST hasn't already been escaped by magic_quotes if(!get_magic_quotes_gpc()) { // Prep input for SQL insertion $form_name = $modx->db->escape($form_name); $url = $modx->db->escape($url); } $insert = array('form'=>$form_name, 'url'=>$url, 'user_key'=>$user_key, 'time'=>$time); $submission_key = $modx->db->insert($insert,"{$db}.{$pre}submissions"); if($submission_key) { foreach($form as $name=>$value) { if(is_array($value)) { $value = implode(' ', $value); } // Check that POST hasn't already been escaped by magic_quotes if(!get_magic_quotes_gpc()) { // Prep input for SQL insertion $name = $modx->db->escape($name); $value = $modx->db->escape($value); } $insert = array('submission_key'=>$submission_key, 'name'=>$name, 'value'=>$value); $modx->db->insert($insert,"{$db}.{$pre}submission_data"); } } } } } if(!function_exists('register_values')) { function register_values($form) { global $modx; // Remove the send_to FormProcessor stuff if it's still there if(isset($form['send_to'])) { unset($form['send_to']); } foreach($form as $key=>$values) { // Turn non-array values into arrays so we can handle all values the same if(!is_array($values)) { $values = array($values); } $value_count = count($values); for($i=0; $i<$value_count; $i++) { $title = $key; $value = $values[$i]; // If there are multiple values, number them if($value_count > 1) { // First time through set placeholder for combined array values if($i == 0) { $modx->setPlaceholder("{$title}-value", implode(' ',$values)); } $title = $key.'_'.($i+1); } $value_clean = strtolower($value); $value_clean = preg_replace(array('/\ /','/[^0-9a-z_]/'), array('_','') ,$value_clean); // If POST was auto escaped then unescape it if(get_magic_quotes_gpc()) { $value = preg_replace('/(\\\\)([^\\\\])/','\\2',$value); } $modx->setPlaceholder("{$title}-value", $value); $modx->setPlaceholder("{$title}-checked-{$value_clean}", ' checked="checked" '); $modx->setPlaceholder("{$title}-selected-{$value_clean}", ' selected="selected" '); } } } } if(!function_exists('render_form')) { // Output the HTML form function render_form($form_name, $form) { $html = '{{'.$form_name.'}}'; return $html; } } if(!function_exists('render_confirmation')) { // Output the HTML confirmation message function render_confirmation($confirmation) { global $modx; // If a confirmation chunk was given if($confirmation) { // Return the confirmation chunk $html = '{{'.$confirmation.'}}'; } else { $form_url = $modx->makeUrl($modx->documentIdentifier); $home_url = $modx->makeUrl($modx->config['site_start']); // Otherwise use a default confirmation message $html = <<Form submission complete

Thanks for taking the time to fill out the form.

EOD; } return $html; } } if(!function_exists('find_fields')) { function find_fields($form, $name_regexp='', $value_regexp='', $match_both=true) { $name_match = 0; $value_match = 0; $fields = array(); foreach($form as $name=>$value) { if(is_array($value)) { $value = implode(' ',$value); } if($name_regexp) { $name_match = preg_match($name_regexp, $name); } if($value_regexp) { $value_match = preg_match($value_regexp, $value); } // If name and value match if($name_match && $value_match) { $fields[$name] = $value; // If we don't have to match both and one matches } elseif(!$match_both && ($name_match || $value_match)) { $fields[$name] = $value; } } return $fields; } } if(!function_exists('parse_string')) { function parse_string($parse_me) { global $modx; // Replace no-cache snippets with normal snippet tags for processing $parse_me = preg_replace(array('/\[!/','/!\]/'),array('[[',']]'),$parse_me); // Main parser handles, TVs, snippets, chunks, etc. $parse_me = $modx->parseDocumentSource($parse_me); // Merge placeholders $parse_me = $modx->mergePlaceholderContent($parse_me); // remove all unused placeholders if(strpos($parse_me, '[+')>-1) { $matches= array(); preg_match_all('~\[\+(.*?)\+\]~', $parse_me, $matches); if($matches[0]) $parse_me = str_replace($matches[0],'',$parse_me); } // Rewrite [~~] style urls $parse_me = $modx->rewriteUrls($parse_me); return $parse_me; } } if(!function_exists('send_confirmation')) { function send_confirmation($to, $from, $subject, $chunk) { global $modx; $headers = ''; // Get and prep the body $body = $modx->getChunk($chunk); $body = parse_string($body); // If stripping HTML tags changes anything then it's HTML $is_html = (strip_tags($body) != $body); if($is_html) { $headers = "MIME-Version: 1.0\n". "Content-type: text/html; charset=iso-8859-1\r\n"; } $headers .= "From: {$from}\n"; mail($to, $subject, $body, $headers); } } $html = ''; $form_sent = false; $form = isset($_POST) ? $_POST : array(); // If we are sending a form if(isset($form['send_to']) && $form['send_to'] == 'FormProcessor') { register_values($form); if(check_requirements($form_required,$form)) { if($data_email_address) { email_data($data_email_address, $data_email_subject, $form, $data_email_chunk); } if($write_database) { write_database($form_chunk, $form); } if($confirmation_email_chunk) { if($emails = find_fields($form, '/.*email.*/i', '/^[A-Z0-9._-]+@[A-Z0-9][A-Z0-9.-]{0,61}[A-Z0-9]\.[A-Z.]{2,6}$/i')) { send_confirmation(current($emails), $confirmation_email_from, $confirmation_email_subject, $confirmation_email_chunk); } } $html .= render_confirmation($confirmation_page_chunk); $form_sent = true; } } if($form_sent == false) { $html .= render_form($form_chunk, $form); } return $html;
{$name}: {$value}