Ticket #432: pappalardoform.php

File pappalardoform.php, 16.1 KB (added by kheatley, 6 years ago)
Line 
1<?php error_reporting(E_ALL ^ E_NOTICE);
2/**
3* physicsMITformMail script - sending mail via form
4*
5*     Author: Kimeee Heatley
6*      Email: kheatley@mit.edu
7*        Web: http://web.mit.edu/physics/
8*    Details: Php code to send form data to us and submitter and also to .csv file.
9*
10* Please direct bug reports,suggestions or feedback to our webmaster.
11* Kimeee Heatley at kheatley@mit.edu
12*                                                                         
13* MITformMail is free for both commercial and non-commercial use.
14* Re-distribution of this script without prior consent is strictly prohibited.
15*                                                                                 
16*/
17
18/*****************************************************************************
19 *                                                                           *
20 *                C  O  N  F  I  G  U  R  A  T  I  O  N                      *
21 *                                                                           *
22 *****************************************************************************/
23
24// email for send submitted forms //////////////////////////////////////////
25// if empty, use value from form ('send_to' field)
26$send_to = 'Carol Breen <breen@mit.edu>';
27//$send_to = 'Kimeee Heatley <kheatley@mit.edu>';
28
29// set $send_cc address if you need copy of mail to other addresses
30// for example: $send_cc = array('friend1@ccc.cc', 'friend2@ccc.cc');
31//
32$send_cc = array('kheatley@mit.edu'); 
33
34// Subject. if empty, use value from form ('subject' field)
35$subject = 'MIT Pappalardo Fellowship Competition 2019-2022 Nomination Submission ';
36
37// Allowed Referres. Should be empty or list of domains
38$referrers = array(); 
39
40// Attachments
41$attachment_enabled = 0;
42
43////// Database - write CSV file with data of submitted forms //////////////
44$database_enabled = 1;
45$database_file = 'pappalardo2019-2022.csv';
46
47// Fields to collect
48// $database_fields = '*' - mean all fields, as in form
49// $database_fields = array('from', 'subject') - only 'from', 'subject' fields
50       
51$database_fields = array('nomineeGender_req','nomineeFName_req', 'nomineeLName_req','nomineeInstitution_req', 'nomineeDept_req', 'nomineeField_req', 'nomineePhd_req', 'nomineeAddy_req', 'nomineePhone_req', 'nomineeEmail_req', 'nominatorTitle_req', 'nominatorFName_req', 'nominatorLName_req','nominatorInstitution_req', 'nominatorDept_req', 'nominatorAddy_req', 'nominatorPhone_req', 'nominatorEmail_req'); 
52       
53//$verify = "http://scripts.mit.edu/~physics/verify_nomination.php?var1='%nominatorName_req%'&var2='%nominatorEmail_req%'&var3='%nomineeName_req%'";
54
55$verify = 'https://physics.scripts.mit.edu/verify_nomination.php?var1=%nominatorEmail_req%&var2=%nominatorFName_req%&var3=%nominatorLName_req%&var4=%nomineeFName_req%&var5=%nomineeLName_req%';
56
57$nominatorFullName = '%nominatorFName_req%' . ' ' . '%nominatorLName_req%';
58$nomineeFullName = '%nomineeFName_req%' . ' ' . '%nomineeLName_req%';
59
60//$verify = 'http://scripts.mit.edu/~physics/verify_nomination.php?var1=%nominatorName_req%&var2=%nominatorEmail_req%&var3=%nomineeName_req%';
61
62////// Redirect user after submitting form
63$redirect_url = 'http://web.mit.edu/physics/research/pappalardo/confirmation_1of2.html';
64
65/* Now we are ready to send the email so we call phps mail() function
66with the appropriate variables from above included in the brackets */
67
68////// Auto-Responder
69////// You can substitute any of form fields in response by using
70////// %field_name% in response text.
71//////
72$date_time = date('Y-m-d H:i:s');
73$autoresponder_enabled = 1;
74$autoresponder_from = $send_to;
75$autoresponder_subject = $subject;
76$autoresponder_message = <<<MSG
77Dear %nominatorFName_req% %nominatorLName_req%,\n
78Thank you for your nomination for the 2019-2022 MIT Pappalardo Fellowships competition. \n
79Please review your submitted information below.  If the information is correct, please click the link at the bottom of this email to verify.\n
80Sincerely,\n
81Carol Breen
82Communications and Pappalardo Fellowships Program Administrator
83MIT Department of Physics\n
84----------Nominee Information------------\n
85Nominee Gender:  %nomineeGender_req%\n
86Nominee First Name:  %nomineeFName_req%\n
87Nominee Last Name:  %nomineeLName_req%\n
88Nominee Institution:  %nomineeInstitution_req%\n
89Nominee Department:  %nomineeDept_req%\n
90Nominee Field of Study:  %nomineeField_req%\n
91Nominee Date of PhD:  %nomineePhd_req%\n
92Nominee Address:  %nomineeAddy_req%\n
93Nominee Phone:  %nomineePhone_req%\n
94Nominee Email:  %nomineeEmail_req%\n
95----------Nominator Information----------\n
96Nominator Title:  %nominatorTitle_req%\n
97Nominator First Name:  %nominatorFName_req%\n
98Nominator Last Name:  %nominatorLName_req%\n
99Nominator Institution:  %nominatorInstitution_req%\n
100Nominator Department:  %nominatorDept_req%\n
101Nominator Address:  %nominatorAddy_req%\n
102Nominator Phone:  %nominatorPhone_req%\n
103Nominator Email:  %nominatorEmail_req%\n
104Please click this link to verify your nomination.  This will complete the nomination process. $verify\n
105MSG;
106/***************************************************************************/
107
108function do_formmail(){
109    global $autoresponder_enabled, $database_enabled;
110    $form      = get_form_data();
111    $errors    = check_form($form);
112    if ($errors) {
113        display_errors($errors);
114        return;
115    }
116    send_mail($form);
117    if ($autoresponder_enabled) 
118        auto_respond($form);
119    if ($database_enabled)
120        save_form($form);
121    redirect();
122}
123
124function redirect(){
125    global $redirect_url;
126    header("Location: $redirect_url");
127    exit();
128}
129
130
131
132function save_form($vars){
133    global $database_file, $database_fields;
134    $f = fopen($database_file, 'a');
135    if (!$f){
136        die("Cannot open db file for save");
137    }
138    foreach ($vars as $k=>$v) {
139        $vars[$k] = str_replace(array("|", ",", "\r","\n"), array(',', ' ',' ',' '), $v);
140    }
141    if (is_array($database_fields)) {
142        $vars_orig = $vars; 
143        $vars = array();
144        foreach ($database_fields as $k)
145            $vars[$k] = $vars_orig[$k];
146    }
147    $str = join(',', $vars);
148    fwrite($f, $str."\n");
149    fclose($f);
150}
151
152function auto_respond($vars){
153    global $autoresponder_from, $autoresponder_message, $autoresponder_subject;
154        global $nomineeFName, $nomineeLName, $nominatorFName, $nominatorLName, $nominatorEmail, $nominatorFullName, $nomineeFullName, $date_time; 
155    /// replace all vars in message
156    $msg = $autoresponder_message;
157    preg_match_all('/%(.+?)%/', $msg, $out);
158    $s_vars = $out[1]; //field list to substitute
159    foreach ($s_vars as $k)
160        $msg = str_replace("%$k%", $vars[$k], $msg);
161    /// replace all vars in subject
162    $subj = $autoresponder_subject;
163    preg_match_all('/%(.+?)%/', $subj, $out);
164    $s_vars = $out[1]; //field list to substitute
165    foreach ($s_vars as $k)
166        $subj = str_replace("%$k%", $vars[$k], $subj);
167    //
168    $_send_to = "$vars[nominatorFullName] <".$vars[nominatorEmail_req].">";
169    $_send_from = $autoresponder_from;
170    mail($_send_to, $subj, $msg, 'From: '.$_send_from);
171}
172
173function _build_fields($vars){
174    $skip_fields = array(
175        'subject');
176    // order by numeric begin, if it exists
177    $is_ordered = 0;
178    foreach ($vars as $k=>$v) 
179        if (in_array($k, $skip_fields)) unset($vars[$k]);
180
181    $new_vars = array();
182    foreach ($vars as $k=>$v){
183        // remove _num, _reqnum, _req from end of field names
184        $k = preg_replace('/_(req|num|reqnum)$/', '', $k);
185        // check if the fields is ordered
186        if (preg_match('/^\d+[ \:_-]/', $k)) $is_ordered++;
187        $new_vars[$k] = $v;
188    }
189    $vars = $new_vars;
190
191    $max_length = 10; // max length of key field
192    foreach ($vars as $k=>$v) {
193        $klen = strlen($k);
194        if (($klen > $max_length) && ($klen < 40))
195            $max_length = $klen;
196    }
197
198    if ($is_ordered){
199        ksort($vars);
200        $new_vars = array();
201        foreach ($vars as $k=>$v){
202            //remove number from begin of fields
203            $k = preg_replace('/^\d+[ \:_-]/', '', $k);
204            $new_vars[$k] = $v;
205        }
206        $vars = $new_vars;
207    }
208
209    // make output text
210    $out = "";
211    foreach ($vars as $k=>$v){
212        $k = str_replace('_', ' ', $k);
213        $k = ucfirst($k);
214        $len_diff = $max_length - strlen($k);
215        if ($len_diff > 0) 
216            $fill = str_repeat('.', $len_diff);
217        else 
218            $fill = '';
219        $out .= $k."$fill...: $v\n\n";
220    }
221    return $out;
222}
223
224
225function send_mail($vars){
226    global $send_to, $send_cc;
227    global $subject;
228    global $attachment_enabled;
229
230//    $files = array(); //files (field names) to attach in mail
231//    if (count($_FILES) && $attachment_enabled){
232//        $files = array_keys($_FILES);
233//    }
234
235    // build mail
236    $date_time = date('Y-m-d H:i:s');
237    $mime_delimiter = "----=_NextPart_000_0001_".md5(time());
238    $fields = _build_fields($vars);
239    $mail = 
240"This is a multi-part message in MIME format.
241   
242--$mime_delimiter
243Content-type: text/plain
244Content-Transfer-Encoding: 8bit
245Content-Disposition: inline
246
247MIT Pappalardo Nomination Form submitted:
248$fields
249--------------------
250REMOTE IP : $_SERVER[REMOTE_ADDR]
251DATE/TIME : $date_time
252";
253
254    if (count($files)){
255        foreach ($files as $file){
256            $file_name     = $_FILES[$file]['name'];
257            $file_type     = $_FILES[$file]['type'];
258            $file_tmp_name = $_FILES[$file]['tmp_name'];
259            $file_cnt = "";
260            $f=@fopen($file_tmp_name, "rb");
261            if (!$f) 
262                continue;
263            while($f && !feof($f))
264                $file_cnt .= fread($f, 4096);
265            fclose($f);
266            if (!strlen($file_type)) $file_type="applicaton/octet-stream";
267            if ($file_type == 'application/x-msdownload')
268                $file_type = "applicaton/octet-stream";
269
270            $mail .= "\n--$mime_delimiter\n";
271            $mail .= "Content-Type: $file_type;\n       name=\"$file_name\"\n";
272            $mail .= "Content-Transfer-Encoding: base64\n";
273            $mail .= "Content-Disposition: attachment;\n       filename=\"$file_name\"\n\n";
274            $mail .= chunk_split(base64_encode($file_cnt));
275        }
276    }
277    $mail .= "\n--$mime_delimiter--";
278
279
280    //send to
281    $_send_to = $send_to ? $send_to : "$vars[name_to] <".$vars[email_to].">";
282    $_send_from = "$vars[nominatorFullName] <".$vars[nominatorEmail_req].">";
283//    $_subject = $subject ? $subject : $vars['subject'];
284        $_subject = "Pappalardo Nomination form $nomineeFName_req $nomineeLName_req :: $date_time";
285
286    mail($_send_to, $_subject, $mail, 
287    "MIME-Version: 1.0\nFrom: $_send_from\nContent-Type: multipart/mixed;\n    boundary=\"$mime_delimiter\"\n");
288
289    foreach ($send_cc as $v){
290      mail($v, $_subject, $mail, 
291    "MIME-Version: 1.0\nFrom: $_send_from\nContent-Type: multipart/mixed;\n    boundary=\"$mime_delimiter\"\n");
292    }
293}
294
295function get_form_data(){
296    $vars = ($_SERVER['REQUEST_METHOD'] == 'GET') ? $_GET : $_POST;
297    //strip spaces from all fields
298    foreach ($vars as $k=>$v) $vars[$k] = trim($v);
299    if (get_magic_quotes_gpc())
300        foreach ($vars as $k=>$v) $vars[$k] = stripslashes($v);
301       
302    if (isset($vars['nominatorFName_req']))
303        $vars['nominatorFName_req'] = preg_replace("/[^\w\d\t\., _-]/", "", $vars['nominatorFName_req']);
304    if (isset($vars['nominatorLName_req']))
305        $vars['nominatorLName_req'] = preg_replace("/[^\w\d\t\., _-]/", "", $vars['nominatorLName_req']);       
306    if (isset($vars['nomineeFName_req']))
307        $vars['nomineeFName_req'] = preg_replace("/[^\w\d\t\., _-]/", "", $vars['nomineeFName_req']);
308    if (isset($vars['nomineeLName_req']))
309        $vars['nomineeLName_req'] = preg_replace("/[^\w\d\t\., _-]/", "", $vars['nomineeLName_req']);   
310    if (isset($vars['nominatorEmail_req']))
311        $vars['nominatorEmail_req'] = preg_replace("/[^@\w\.\d_-]/", "", $vars['nominatorEmail_req']);
312    if (isset($vars['subject']))
313        $vars['subject'] = preg_replace("/[^\w\d\t \".,;:#\$%^&\*()+=`~\|_-]/", "", $vars['subject']);
314    return $vars;
315}
316
317function check_form($vars){
318    global $referrers;
319    global $send_to;
320    global $subject;
321
322    $errors = array();
323
324    // check from email set
325    if (!strlen($vars['nominatorEmail_req'])){
326        $errors[] = "Required field <b>Nominator Email address</b> empty";
327    } else if (!check_email($vars['nominatorEmail_req'])){
328        $errors[] = "Required field <b>Nominator Email address</b> incorrect";       
329    }                 
330    if (!strlen($send_to) && !strlen($vars['email_to'])){
331        $errors[] = "<b>To Email</b> address empty (possible configuration error)";
332    } else if (!strlen($send_to) && !check_email($vars['email_to'])){
333        //if to email specified in form, check it and display error
334        $errors[] = "<b>To Email address</b> incorrect";       
335    }
336    if (!strlen($vars['subject']) && !strlen($subject)){
337        $errors[] = "<b>Subject</b> empty (possible configuration error)";
338    }
339    foreach ($vars as $k=>$v){
340        // check for required fields (end with _req)
341        if (preg_match('/^(.+?)_req$/i', $k, $m) && !strlen($v)){
342            $field_name = ucfirst($m[1]);
343            $errors[] = "Required field <b>$field_name</b> empty";
344        }
345        // check for number fields (end with _num)
346        if (preg_match('/^(.+?)_num$/i', $k, $m) && strlen($v) && !is_numeric($v)){
347            $field_name = ucfirst($m[1]);
348            $errors[] = "Field <b>$field_name</b> must contain only digits or be empty";
349        }
350        // check for number & required fields (end with _reqnum)
351        if (preg_match('/^(.+?)_reqnum$/i', $k, $m) && !is_numeric($v)){
352            $field_name = ucfirst($m[1]);
353            $errors[] = "Field <b>$field_name</b> must contain digits and only digits";
354        }
355    }
356
357    //check referrer
358    if (is_array($referrers) && count($referrers)){
359        $ref = parse_url($_SERVER['HTTP_REFERER']);
360        $host = $ref['host'];
361        $host_found = 0;
362        foreach ($referrers as $r){
363            if (strstr($host, $r)) 
364                $host_found++;
365        }
366        if (!$host_found){
367            $errors[] = "Unknown Referrer: <b>$host</b>";
368        }
369    }
370    return $errors;
371}
372
373function display_errors($errors){
374$errors = '<li>' . join('<li>', $errors);
375print <<<EOF
376<html>
377    <head><title>ERROR -- MIT PAPPALARDO FELLOWSHIP NOMINATION -- ERROR</title>
378        <link href="http://web.mit.edu/physics/css/form.css" rel="stylesheet" type="text/css">
379        </head>
380        <div align="center"><br>
381 
382  <form name="error">
383 
384  <a href="http://web.mit.edu/">
385<img src="http://web.mit.edu/graphicidentity/interface/mit-blackred-header1.gif"
386alt="MIT" width="357" height="46" border="0" style="border:0px white;background-color:#fff;">
387</a>
388
389<p class="header_large">2019-2022 Pappalardo Fellowship Competition Nomination Form</p>
390
391<p class="header_red">*AN ERROR OCCURED*</p>
392<span class="errors" style="text-align:left;">$errors</span><br />
393</div>
394</form>
395<p align=center>&nbsp;</p>
396<div class="footer">
397<span class="left">&nbsp;&copy; Copyright 2018
398<a href="http://web.mit.edu/physics/" target="_blank">MIT Department of Physics</a></span>
399<span class="right">
400Webmaster: <a href="mailto:kheatley@mit.edu" target="_blank">kheatley@mit.edu</a>&nbsp;
401</span>
402
403<br />
404</div>
405
406</html>
407EOF;
408}
409
410
411/**
412* Check email using regexes
413* @param string email
414* @return bool true if email valid, false if not
415*/
416function check_email($email) {
417    #characters allowed on name: 0-9a-Z-._ on host: 0-9a-Z-. on between: @
418    if (!preg_match('/^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/', $email))
419        return false;
420
421    #must start or end with alpha or num
422    if ( preg_match('/^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/', $email))
423        return false;
424
425    #name must end with alpha or num
426    if (!preg_match('/([0-9a-zA-Z_]{1})\@./',$email) )                   
427        return false;
428
429    #host must start with alpha or num
430    if (!preg_match('/.\@([0-9a-zA-Z_]{1})/',$email) )                   
431        return false;
432
433    #pair .- or -. or -- or .. not allowed
434    if ( preg_match('/.\.\-.|.\-\..|.\.\..|.\-\-./',$email) )
435        return false;
436
437    #pair ._ or -_ or _. or _- or __ not allowed
438    if ( preg_match('/.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./',$email) )
439        return false;
440
441    #host must end with '.' plus 2-5 alpha for TopLevelDomain
442    if (!preg_match('/\.([a-zA-Z]{2,5})$/',$email) )
443        return false;
444
445    return true;
446}
447
448do_formmail();
449?>