[system] / trunk / webwork / system / cgi / cgi-scripts / profSendMail.pl Repository:
ViewVC logotype

Diff of /trunk/webwork/system/cgi/cgi-scripts/profSendMail.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5 Revision 6
1#!/usr/bin/perl 1#!/usr/local/bin/perl
2 2
3## This file is profSendMail.pl 3## This file is profSendMail.pl
4## It provides a utility for professors to send mail to one or more students 4## It provides a utility for professors to send mail to one or more students
5## using individualized emails or mass emails 5## using individualized emails or mass emails
6## Original by the WebWork Team at University of Rochester
7## Modifications for Invalid Address Checking and for CC's
8## by Jonathan Duncan and William Wheeler at Indiana University
6 9
7use lib '/ww/webwork/development/'; # mainWeBWorKDirectory; 10use lib '/ww/webwork/gage_system/webwork/system/lib/'; # mainWeBWorKDirectory
8 11
9use Global; 12use Global;
10use CGI qw(:standard); 13use CGI qw(:standard);
11use Auth; 14use Auth;
12use Net::SMTP; 15use Net::SMTP;
25my $course = $cgi->param('course'); 28my $course = $cgi->param('course');
26my $user = $cgi->param('user'); 29my $user = $cgi->param('user');
27my $session_key = $cgi->param('key'); 30my $session_key = $cgi->param('key');
28my $openfilename = $cgi->param('openfilename'); 31my $openfilename = $cgi->param('openfilename');
29 32
33#is this necessary?
34unless ($course && $user && $session_key)
35 {&wwerror("$0","The script did not receive the proper input data.","","", "");}
36
30&Global::getCourseEnvironment($course); 37&Global::getCourseEnvironment($course);
31 38
32my $scriptDirectory = $Global::scriptDirectory; 39my $scriptDirectory = $Global::scriptDirectory;
33my $databaseDirectory = $Global::databaseDirectory; 40my $databaseDirectory = $Global::databaseDirectory;
34my $htmlURL = $Global::htmlURL; 41my $htmlURL = $Global::htmlURL;
35my $cgiURL = $Global::cgiWebworkURL; 42my $cgiURL = $Global::cgiWebworkURL;
36my $courseScriptsDirectory = $Global::courseScriptsDirectory; 43my $courseScriptsDirectory = $Global::courseScriptsDirectory;
37my $templateDirectory = getCourseTemplateDirectory; 44my $templateDirectory = getCourseTemplateDirectory;
38my $emailDirectory = getCourseEmailDirectory; 45my $emailDirectory = getCourseEmailDirectory;
39my $scoringDirectory = getCourseScoringDirectory; 46my $scoringDirectory = getCourseScoringDirectory;
40my $feedbackAddress = $Global::feedbackAddress; 47my $feedbackAddress = $Global::feedbackAddress;
41my $defaultClasslistFile = getCourseClasslistFile($course); 48my $defaultClasslistFile = getCourseClasslistFile($course);
42my $default_msg = 'default.msg'; 49my $default_msg = 'default.msg';
43my $old_default_msg = 'default_old.msg'; 50my $old_default_msg = 'default_old.msg';
51
44require "${scriptDirectory}$Global::FILE_pl"; 52require "${scriptDirectory}$Global::FILE_pl";
45
46require "${scriptDirectory}$Global::classlist_DBglue_pl"; 53require "${scriptDirectory}$Global::classlist_DBglue_pl";
47require "${scriptDirectory}$Global::HTMLglue_pl"; 54require "${scriptDirectory}$Global::HTMLglue_pl";
48require "${scriptDirectory}$Global::FILE_pl"; 55require "${scriptDirectory}$Global::FILE_pl";
49 56
50# log access 57# log access
51&Global::log_info('', query_string); 58&Global::log_info('', query_string);
52 59
53my $permissionsFile = &Global::getCoursePermissionsFile($course); 60my $permissionsFile = &Global::getCoursePermissionsFile($course);
54my $permissions = &get_permissions($user, $permissionsFile); 61my $permissions = &get_permissions($user, $permissionsFile);
55my $keyFile = &Global::getCourseKeyFile($course); 62my $keyFile = &Global::getCourseKeyFile($course);
56 63
57 64
58#verify session key 65#verify session key
59&verify_key($user, $session_key, "$keyFile", $course); 66&verify_key($user, $session_key, "$keyFile", $course);
60 67
61#verify permissions are correct 68#verify permissions are correct
62if (($permissions != $Global::instructor_permissions) and ($permissions != $Global::TA_permissions) ) { 69if( ($permissions != $Global::instructor_permissions) and ($permissions != $Global::TA_permissions) ) {
63 print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n"; 70 print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n";
64 print &html_NO_PERMISSION; 71 print &html_NO_PERMISSION;
65 exit(0); 72 exit(0);
66 } 73}
67 74
68#user macros that can be used in the email message 75#user macros that can be used in the email message
69my $SID = ''; 76my $SID = '';
70my $FN = ''; 77my $FN = '';
71my $LN = ''; 78my $LN = '';
103 $availableStudents_ref = getAllLoginNamesSortedByName(); 110 $availableStudents_ref = getAllLoginNamesSortedByName();
104} 111}
105 112
106my @availableStudents = @$availableStudents_ref; 113my @availableStudents = @$availableStudents_ref;
107 114
108#my %loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()}; 115#my %loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()};
109my %studentID_LoginName_Hash = %{getStudentID_LoginName_Hash()}; 116my %studentID_LoginName_Hash = %{getStudentID_LoginName_Hash()};
110
111 117
112 118
113#make sure message file was submitted and exists 119#make sure message file was submitted and exists
114 my $messageFileName; 120my $messageFileName;
115 if (defined($openfilename) && -e "${emailDirectory}$openfilename") { 121if (defined($openfilename) && -e "${emailDirectory}$openfilename") {
116 if ( -R "${emailDirectory}$openfilename") { 122 if ( -R "${emailDirectory}$openfilename") {
117 $messageFileName = $openfilename; 123 $messageFileName = $openfilename;
124 }
118 } else { 125 else {
119 wwerror ('File is not readable', "The file 126 wwerror ('File is not readable', "The file
120${emailDirectory}$openfilename 127 ${emailDirectory}$openfilename
121is not readable by the webserver. Check that it's permissions are set correctly."); 128 is not readable by the webserver. Check that its permissions are set correctly.");
122 } 129 }
130}
123 } else { 131else {
124 $messageFileName = $default_msg; 132 $messageFileName = $default_msg;
125 } 133}
126 134
127 135
128#get row and column info if submitted 136#get row and column info if submitted
129 my $rows = (defined($cgi->param('rows'))) ? $cgi->param('rows') : $Global::editor_window_rows; 137my $rows = (defined($cgi->param('rows'))) ? $cgi->param('rows') : $Global::editor_window_rows;
130 my $columns = (defined($cgi->param('columns'))) ? $cgi->param('columns') : $Global::editor_window_columns; 138my $columns = (defined($cgi->param('columns'))) ? $cgi->param('columns') : $Global::editor_window_columns;
131 139
132#Deal with filled out forms and various actions resulting from different buttons 140#Deal with filled out forms and various actions resulting from different buttons
133 if ( defined($cgi->param('action')) ) { 141if ( defined( $cgi->param('action') ) ) {
134 if (defined($cgi->param('savefilename'))) { 142 if( defined( $cgi->param('savefilename') ) and ( $cgi->param('savefilename') =~ /^[~.]/ || $cgi->param('savefilename') =~ /\.\./ ) ) {
135 &user_error("For security reasons, you cannot save a message in any directory higher than the email directory. Please specify a file name to save under.") if ($cgi->param('savefilename') =~ /^[~.]/ || $cgi->param('savefilename') =~ /\.\./); 143 &user_error("For security reasons, you cannot save a message in any directory higher than the email directory. Please specify a file name to save under.");
136 } 144 }
137 145
146 #do nothing, but needed to prevent an infinite loop
147 if($cgi->param('action') eq 'Cancel' ) { }
138 #if Save button was clicked 148 #if Save button was clicked
139 if (( $cgi->param('action') eq 'Save') && defined($cgi->param('body')) && defined($cgi->param('savefilename'))) { 149 elsif( ( $cgi->param('action') eq 'Save') && defined( $cgi->param('body') ) && defined( $cgi->param('savefilename') ) ) {
140
141 my $temp_body = $cgi->param('body'); 150 my $temp_body = $cgi->param('body');
142 $temp_body =~ s/\r\n/\n/g; 151 $temp_body =~ s/\r\n/\n/g;
143 $temp_body = "From: " . $cgi->param('from') . "\n" . 152 $temp_body = "From: " . $cgi->param('from') . "\n" .
153 "Reply-To: " . $cgi->param('replyTo') . "\n" .
154 "Cc: " . $cgi->param('cc') . "\n" .
155 "Subject: " . $cgi->param('subject') . "\n" .
156 "Message: \n" . $temp_body;
157
158 saveProblem($temp_body, $cgi->param('savefilename'));
159 $messageFileName = $cgi->param('savefilename');
160 }
161 #if Save As button was clicked
162 elsif( ( $cgi->param('action') eq 'Save as' ) && defined( $cgi->param('body') ) && defined( $cgi->param('savefilename') ) ) {
163 $messageFileName = $cgi->param('savefilename');
164
165 if ($messageFileName =~ /^[~.]/ || $messageFileName =~ /\.\./) {
166 &user_error("For security reasons, you cannot specify a merge file from a directory higher than the email directory (you can't use ../blah/blah). Please specify a different file or move the needed file to the email directory");
167 }
168
169 my $temp_body = $cgi->param('body');
170 $temp_body =~ s/\r\n/\n/g;
171 $temp_body = "From: " . $cgi->param('from') . "\n" .
144 "Reply-To: " . $cgi->param('replyTo') . "\n" . 172 "Reply-To: " . $cgi->param('replyTo') . "\n" .
173 "Cc: " . $cgi->param('cc') . "\n" .
145 "Subject: " . $cgi->param('subject') . "\n" . 174 "Subject: " . $cgi->param('subject') . "\n" .
146 "Message: \n" . $temp_body; 175 "Message: \n" . $temp_body;
147 176
148 saveProblem($temp_body, $cgi->param('savefilename'));
149 $messageFileName = $cgi->param('savefilename');
150
151 #if Save As button was clicked
152 } elsif (( $cgi->param('action') eq 'Save as') && defined($cgi->param('body')) && defined($cgi->param('savefilename'))) {
153
154 $messageFileName = $cgi->param('savefilename');
155
156 if ($messageFileName =~ /^[~.]/ || $messageFileName =~ /\.\./) {
157 &user_error("For security reasons, you cannot specify a merge file from a directory higher than the email directory (you can't use ../blah/blah). Please specify a different file or move the needed file to the email directory");
158 }
159
160
161 my $temp_body = $cgi->param('body');
162 $temp_body =~ s/\r\n/\n/g;
163 $temp_body = "From: " . $cgi->param('from') . "\n" .
164 "Reply-To: " . $cgi->param('replyTo') . "\n" .
165 "Subject: " . $cgi->param('subject') . "\n" .
166 "Message: \n" . $temp_body;
167
168 saveNewProblem($temp_body, $messageFileName); 177 saveNewProblem($temp_body, $messageFileName);
169 178 }
170 #if Save As Default button was clicked 179 #if Save As Default button was clicked
171 } elsif (( $cgi->param('action') eq 'Save as Default') && defined($cgi->param('body'))) { 180 elsif( ( $cgi->param('action') eq 'Save as Default' ) && defined( $cgi->param('body') ) ) {
172
173 my $temp_body; 181 my $temp_body;
174 $temp_body = $cgi->param('body'); 182 $temp_body = $cgi->param('body');
175 $temp_body =~ s/\r\n/\n/g; 183 $temp_body =~ s/\r\n/\n/g;
176 184
177 #get default.msg and back it up in default.old.msg 185 #get default.msg and back it up in default.old.msg
178 open DEFAULT, "$emailDirectory$default_msg"; 186 open DEFAULT, "$emailDirectory$default_msg";
179 $temp_body = <DEFAULT>; 187 $temp_body = <DEFAULT>;
180 close DEFAULT; 188 close DEFAULT;
181 189
182 if ( -e "$emailDirectory$old_default_msg") { 190 if ( -e "$emailDirectory$old_default_msg") {
183 saveProblem($temp_body, $old_default_msg); 191 saveProblem($temp_body, $old_default_msg);
192 }
184 } else { 193 else {
185 saveNewProblem($temp_body, $old_default_msg); 194 saveNewProblem($temp_body, $old_default_msg);
186 } 195 }
187 196
188 #save new default message as default.msg 197 #save new default message as default.msg
189 $temp_body = $cgi->param('body'); 198 $temp_body = $cgi->param('body');
190 $temp_body =~ s/\r\n/\n/g; 199 $temp_body =~ s/\r\n/\n/g;
191 $temp_body = "From: " . $cgi->param('from') . "\n" . 200 $temp_body = "From: " . $cgi->param('from') . "\n" .
192 "Reply-To: " . $cgi->param('replyTo') . "\n" . 201 "Reply-To: " . $cgi->param('replyTo') . "\n" .
202 "Cc: " . $cgi->param('cc') . "\n" .
193 "Subject: " . $cgi->param('subject') . "\n" . 203 "Subject: " . $cgi->param('subject') . "\n" .
194 "Message: \n" . $temp_body; 204 "Message: \n" . $temp_body;
195 205
196 saveProblem($temp_body, $default_msg); 206 saveProblem($temp_body, $default_msg);
197 $messageFileName = $default_msg; 207 $messageFileName = $default_msg;
198 208 }
199 #if Send Email button was clicked 209 #if Send Email button was clicked, check addresses
210 elsif( ( $cgi->param('action') eq 'Send Email' ) || ( $cgi->param('action') eq 'Send to Good Addresses' ) ) {
211
212 my $cc;
213
200 } elsif ( $cgi->param('action') eq 'Send Email' ) { 214 if( ($cgi->param('action')) eq 'Send Email' ) {
215 # define our local procedure variables
216 my @Address = ();
217 my @Name = ();
218 my @BadAddress = ();
201 219
202 my @studentID = (); 220 # get list of addresses to verify from class list
203
204 if ($cgi->param('To') eq 'classList' && defined($cgi->param('classList')) && $cgi->param('classList') ne 'None') { 221 if( $cgi->param('To') eq 'classList' && defined( $cgi->param('classList') ) && $cgi->param('classList') ne 'None' ) {
222
205 my $classlist = $cgi->param('classList'); 223 my $classlist = $cgi->param('classList');
206 my $classListFile = "$templateDirectory$classlist"; 224 my $classListFile = "$templateDirectory$classlist";
207 my @classList = (); 225 my @classList = ();
208 checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile); 226 checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile);
209 open(FILE, "$classListFile") || die "can't open $classListFile"; 227 open(FILE, "$classListFile") || die "can't open $classListFile";
210 @classList=<FILE>; 228 @classList=<FILE>;
211 close(FILE); 229 close(FILE);
212 230
213 foreach (@classList) { ## read through classlist and send e-mail 231 foreach( @classList ) { # read through classlist, getting email and name of all active students
214 ## message to all active students
215 unless ($_ =~ /\S/) {next;} ## skip blank lines 232 next unless ($_ =~ /\S/); ## skip blank lines
216 chomp; 233 chomp;
234
217 my @classListRecord=&getRecord($_); 235 my @classListRecord = &getRecord($_);
218 my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name) 236 my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name)
219 = @classListRecord; 237 = @classListRecord;
220 unless (&dropStatus($status)) { 238 unless( &dropStatus($status) || $login_name =~ /^$Global::practiceUser/ ) {
221 push (@studentID, $studentID); 239 push(@Address,$email_address);
222 $fn{$studentID} = $firstName; 240 push(@Name,$firstName . ' ' . $lastName);
223 $ln{$studentID} = $lastName;
224 $section{$studentID} = $section;
225 $recitation{$studentID} = $recitation;
226 $status{$studentID} = $status;
227 $email{$studentID} = $email_address;
228 $login{$studentID} = $login_name;
229 }
230 } 241 }
242 } # end foreach
231 } 243 }
244 # get list of addresses to verify from selected list
232 elsif ($cgi->param('To') eq 'studentID' && defined($cgi->param('studentID'))) { 245 elsif( $cgi->param('To') eq 'studentID' && defined( $cgi->param('studentID') ) ) {
233 @studentID = $cgi->param('studentID'); 246 my(@studentID) = $cgi->param('studentID');
234 my ($studentID, $login_name); 247 my($studentID, $login_name);
235 248
236 foreach $studentID (@studentID) { 249 foreach $studentID (@studentID) {
237 $login_name = $studentID_LoginName_Hash{$studentID}; 250 $login_name = $studentID_LoginName_Hash{$studentID};
238 &attachCLRecord($login_name); 251 &attachCLRecord($login_name);
239 $fn{$studentID} = CL_getStudentFirstName($login_name); 252 push(@Address, CL_getStudentEmailAddress($login_name));
240 $ln{$studentID} = CL_getStudentLastName($login_name); 253 push(@Name, CL_getStudentFirstName($login_name) . ' ' . CL_getStudentLastName($login_name));
241 $section{$studentID} = CL_getClassSection($login_name);
242 $recitation{$studentID} = CL_getClassRecitation($login_name);
243 $status{$studentID} = CL_getStudentStatus($login_name);
244 $email{$studentID} = CL_getStudentEmailAddress($login_name);
245 $login{$studentID} = $login_name;
246 } 254 }
247
248 } 255 }
256 # get list of addresses to verify from all students
249 elsif ($cgi->param('To') eq 'all_students') { 257 elsif ($cgi->param('To') eq 'all_students') {
250 @studentID = (); 258 my(@studentID) = ();
251 my ($studentID, $login_name, $status); 259 my($studentID, $login_name, $status);
252 260
253 foreach $login_name (@availableStudents) { 261 foreach $login_name (@availableStudents) {
254 &attachCLRecord($login_name); 262 &attachCLRecord($login_name);
255 $status = CL_getStudentStatus($login_name); 263 $status = CL_getStudentStatus($login_name);
256 next if &dropStatus($status); 264 next if( &dropStatus($status) || $login_name =~ /^$Global::practiceUser/ );
257 $studentID = CL_getStudentID($login_name); 265
258 push(@studentID,$studentID); 266 push(@Address, CL_getStudentEmailAddress($login_name));
259 267 push(@Name, CL_getStudentFirstName($login_name) . ' ' . CL_getStudentLastName($login_name));
260 $fn{$studentID} = CL_getStudentFirstName($login_name);
261 $ln{$studentID} = CL_getStudentLastName($login_name);
262 $section{$studentID} = CL_getClassSection($login_name);
263 $recitation{$studentID} = CL_getClassRecitation($login_name);
264 $status{$studentID} = CL_getStudentStatus($login_name);
265 $email{$studentID} = CL_getStudentEmailAddress($login_name);
266 $login{$studentID} = $login_name;
267 } 268 }
268 } 269 }
270 # no list of addresses to verify!
269 else { 271 else {
270 &user_error('You didn\'t select any recipients. Make sure you select either all student in the course, individual students or a whole classlist.'); 272 &user_error('You didn\'t select any recipients. Make sure you select either all student in the course, individual students or a whole classlist.');
271 } 273 }
272 274
273 my $mergeFile = ''; 275 # now actually verify the addresses, storing bad name+addresses in @BadAddress
274 276
275 #the radio button named 'merge' determines whether to take the selected mergefile 277 $cc = $cgi->param('cc');
276 #or one that was typed in. A error message is given if select one and use the other 278 push( @Address, $cc ) if defined($cc) and $cc;
277 $mergeFile = $scoringDirectory . $cgi->param('mergeFiles')
278 if ($cgi->param('merge') eq 'mergeFiles' && defined($cgi->param('mergeFiles')) && $cgi->param('mergeFiles') ne 'None');
279
280 $mergeFile = $templateDirectory . $cgi->param('mergeFile')
281 if ($cgi->param('merge') eq 'mergeFile' && defined($cgi->param('mergeFile')) && $cgi->param('mergeFile') !~ m|/$|); #does not end in a /
282
283 if ($mergeFile =~ /^[~.]/ || $mergeFile =~ /\.\./) {
284 &user_error("For security reasons, you cannot specify a merge file from a directory higher than the email directory. Please specify a different file or move the needed file to the email directory");
285 } 279
286 if ($cgi->param('body') =~ /(\$COL\[.*?\])/ && !(-e $mergeFile)) { 280 my $i;
287 &user_error("In order to use the \$COL[] you must specify a merge file. The file you specified does not exist. Also, make sure you selected the right checkbox."); 281 my $smtp = Net::SMTP -> new( $Global::smtpServer, Timeout=>10 ) || &internal_error( "Couldn't contact SMTP server." );
282 $smtp -> mail($Global::webmaster);
288 } 283
289 284 for( $i = 0; $i < @Address; $i++ ) {
290 285 if( ! $smtp -> recipient( $Address[$i] ) ) { # this one is bad...put it in the list
291 my %mergeAArray = (); 286 $Address[$i] = 'none' if ( ! $Address[$i] );
292 unless ($mergeFile eq '') {%mergeAArray = &delim2aa($mergeFile);} 287 push( @BadAddress, $Name[$i] . ' (' . $Address[$i] . ')' );
293
294 foreach my $studentID (@studentID) {
295 unless ((defined $mergeAArray{$studentID}) or ($mergeFile eq '')) {
296 next if $cgi->param('no_record');
297 }
298 @COL =();
299 $SID = $studentID;
300 $LN = defined $ln{$studentID} ? $ln{$studentID} :'';
301 $FN = defined $fn{$studentID} ? $fn{$studentID} :'';
302 $SECTION = defined $section{$studentID} ? $section{$studentID} :'';
303 $RECITATION = defined $recitation{$studentID} ? $recitation{$studentID} :'';
304 $EMAIL = defined $email{$studentID} ? $email{$studentID} :'';
305 $STATUS =defined $status{$studentID} ? $status{$studentID} :'';
306 $LOGIN = $login{$studentID};
307
308 my ($dbString, @dbArray);
309 if (defined $mergeAArray{$SID}) {
310 $dbString = $mergeAArray{$SID}; ## get sid record from merge file
311 @dbArray = &getRecord($dbString);
312 unshift(@dbArray,$SID);
313 unshift(@dbArray,""); ## note COL[1] is the first column
314 @COL= @dbArray; ## put merge fields in COL array
315 $endCol = @COL; ## \endCol-1 gives last field, etc
316 } 288 }
289 }
290
291 $smtp -> reset();
292 $smtp -> quit();
293
294 # if we had any BadAddress entries, complain
295 if( @BadAddress > 0 ) {
296 # Begin Page with a header
297 print &htmlTOP( "Send Mail for " . $course ),
298 $cgi -> a( { -href=>"${cgiURL}profLogin.pl?user=$user&key=$session_key&course=$course" },
299 $cgi -> img( { -name=>'upImg', -src=>"${Global::upImgUrl}", -align=>'right', -border=>'1', -alt=>'[Up]'} ) ),
300 $cgi -> p;
317 301
302 # Page title
303 print "\n",$cgi->hr, $cgi->br,"\n\n",
304 $cgi -> h3( { -align=>'left' }, "Error Sending Mail for $course" ), "\n",
305 $cgi -> p;
306
307 # Print list of bad addresses
308 print "The following student email addresses had fatal errors:\n",
309 $cgi -> ul( li( {-type=>'disc'},\@BadAddress ) ),"\n\n",
310 "You may choose to cancel your message or send it to the Good Addresses on your email list.\n<p>",
311 "To avoid this message in the future, you should correct these bad email addresses (the ones listed above) in your email list \n",
312 "and/or delete the students from your email list. Please ask your course coordinator for help with this.\n";
313# "If you are sending to the entire class, you may avoid these messages in the future by changing\n",
314# "the status of the offending student(s) to 'Dropped'\n.";
315
316 # start form with hidden entries to pass info back to profSendMail.pl
317 print $cgi->startform( -action=>"${cgiURL}profSendMail.pl" ), "\n",
318 $cgi -> hidden(-name=>"user", -value=>$user), "\n",
319 $cgi -> hidden(-name=>"key", -value=>$session_key), "\n",
320 $cgi -> hidden(-name=>"course", -value=>$course), "\n",
321 $cgi -> hidden(-name=>"To"), "\n",
322 $cgi -> hidden(-name=>"classList"), "\n",
323 $cgi -> hidden(-name=>"studentID"), "\n",
324 $cgi -> hidden(-name=>"merge"), "\n",
325 $cgi -> hidden(-name=>"mergeFiles"), "\n",
326 $cgi -> hidden(-name=>"mergeFile"), "\n",
327 $cgi -> hidden(-name=>"body"), "\n",
328 $cgi -> hidden(-name=>"from"), "\n",
329 $cgi -> hidden(-name=>"replyTo"), "\n",
330 $cgi -> hidden(-name=>"cc"), "\n",
331 $cgi -> hidden(-name=>"subject"), "\n",
332 $cgi -> hidden(-name=>"columns"), "\n",
333 $cgi -> hidden(-name=>"dummyName"), "\n",
334 $cgi -> hidden(-name=>"format"), "\n",
335 $cgi -> hidden(-name=>"openfilename"), "\n",
336 $cgi -> hidden(-name=>"rows"), "\n",
337 $cgi -> hidden(-name=>"savefilename"), "\n",
338 $cgi -> hidden(-name=>"no_record"), "\n";
339
340
341 # create both necessary action buttons
342 print $cgi->submit(-name=>'action', -value=>'Send to Good Addresses'), "\n",
343 $cgi->submit(-name=>'action', -value=>'Cancel'),"\n",
344 $cgi->end_form,
345 &htmlBOTTOM("profSendMail", \%inputs, 'profSendMailHelp.html');
346
347 # End of HTML, and this part of the program
348 exit(0);
349 }
350 }
351
352
353 #if we want to send the e-mail anyway, or if there were no errors found
354 my @studentID = ();
355
356 if( $cgi->param('To') eq 'classList' && defined( $cgi->param('classList') ) && $cgi->param('classList') ne 'None' ) {
357 my $classlist = $cgi->param('classList');
358 my $classListFile = "$templateDirectory$classlist";
359 my @classList = ();
360 checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile);
361
362 open(FILE, "$classListFile") || die "can't open $classListFile";
363 @classList=<FILE>;
364 close(FILE);
365
366 foreach (@classList) { ## read through classlist and send e-mail
367 ## message to all active students
368 next unless($_ =~ /\S/); ## skip blank lines
369 chomp;
370
371 my @classListRecord = &getRecord($_);
372 my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name)
373 = @classListRecord;
374 unless( &dropStatus($status) || $login_name =~ /^$Global::practiceUser/ ) {
375 push (@studentID, $studentID);
376
377 $fn{$studentID} = $firstName;
378 $ln{$studentID} = $lastName;
379 $section{$studentID} = $section;
380 $recitation{$studentID} = $recitation;
381 $status{$studentID} = $status;
382 $email{$studentID} = $email_address;
383 $login{$studentID} = $login_name;
384 }
385 } # end foreach
386 }
387 elsif ($cgi->param('To') eq 'studentID' && defined($cgi->param('studentID'))) {
388 @studentID = $cgi->param('studentID');
389 my ($studentID, $login_name);
390
391 foreach $studentID (@studentID) {
392 $login_name = $studentID_LoginName_Hash{$studentID};
393 &attachCLRecord($login_name);
394 $fn{$studentID} = CL_getStudentFirstName($login_name);
395 $ln{$studentID} = CL_getStudentLastName($login_name);
396 $section{$studentID} = CL_getClassSection($login_name);
397 $recitation{$studentID} = CL_getClassRecitation($login_name);
398 $status{$studentID} = CL_getStudentStatus($login_name);
399 $email{$studentID} = CL_getStudentEmailAddress($login_name);
400 $login{$studentID} = $login_name;
401 }
402
403 }
404 elsif ($cgi->param('To') eq 'all_students') {
405 @studentID = ();
406 my ($studentID, $login_name, $status);
407
408 foreach $login_name (@availableStudents) {
409 &attachCLRecord($login_name);
410 $status = CL_getStudentStatus($login_name);
411 next if( &dropStatus($status) || $login_name =~ /^$Global::practiceUser/ );
412
413 $studentID = CL_getStudentID($login_name);
414 push(@studentID,$studentID);
415
416 $fn{$studentID} = CL_getStudentFirstName($login_name);
417 $ln{$studentID} = CL_getStudentLastName($login_name);
418 $section{$studentID} = CL_getClassSection($login_name);
419 $recitation{$studentID} = CL_getClassRecitation($login_name);
420 $status{$studentID} = CL_getStudentStatus($login_name);
421 $email{$studentID} = CL_getStudentEmailAddress($login_name);
422 $login{$studentID} = $login_name;
423 }
424 } # end elsif
425 else {
426 &user_error('You didn\'t select any recipients. Make sure you select either all student in the course, individual students or a whole classlist.');
427 }
428
429 my $mergeFile = '';
430
431 #the radio button named 'merge' determines whether to take the selected mergefile
432 #or one that was typed in. A error message is given if select one and use the other
433 $mergeFile = $scoringDirectory . $cgi->param('mergeFiles')
434 if ($cgi->param('merge') eq 'mergeFiles' && defined($cgi->param('mergeFiles')) && $cgi->param('mergeFiles') ne 'None');
435
436 $mergeFile = $templateDirectory . $cgi->param('mergeFile')
437 if ($cgi->param('merge') eq 'mergeFile' && defined($cgi->param('mergeFile')) && $cgi->param('mergeFile') !~ m|/$|); #does not end in a /
438
439 if( $mergeFile =~ /^[~.]/ || $mergeFile =~ /\.\./) {
440 &user_error( "For security reasons, you cannot specify a merge file from a directory higher than the email directory. Please specify a different file or move the needed file to the email directory" );
441 }
442 if( $cgi->param('body') =~ /(\$COL\[.*?\])/ && !(-e $mergeFile) ) {
443 &user_error( "In order to use the \$COL[] you must specify a merge file. The file you specified does not exist. Also, make sure you selected the right checkbox." );
444 }
445
446 my %mergeAArray = ();
447 %mergeAArray = &delim2aa($mergeFile) unless $mergeFile eq '';
448
449 foreach my $studentID (@studentID) {
450 unless( ( defined $mergeAArray{$studentID} ) or ( $mergeFile eq '' ) ) {
451 next if $cgi->param('no_record');
452 }
453
454 @COL = ();
455 $SID = $studentID;
456 $LN = defined $ln{$studentID} ? $ln{$studentID} :'';
457 $FN = defined $fn{$studentID} ? $fn{$studentID} :'';
458 $SECTION = defined $section{$studentID} ? $section{$studentID} :'';
459 $RECITATION = defined $recitation{$studentID} ? $recitation{$studentID} :'';
460 $EMAIL = defined $email{$studentID} ? $email{$studentID} :'';
461 $STATUS = defined $status{$studentID} ? $status{$studentID} :'';
462 $LOGIN = $login{$studentID};
463
464 my( $dbString, @dbArray );
465 if( defined $mergeAArray{$SID} ) {
466 $dbString = $mergeAArray{$SID}; ## get sid record from merge file
467 @dbArray = &getRecord($dbString);
468 unshift(@dbArray,$SID);
469 unshift(@dbArray,""); ## note COL[1] is the first column
470 @COL = @dbArray; ## put merge fields in COL array
471 $endCol = @COL; ## \endCol-1 gives last field, etc
472 }
473 $endCol = 0 unless defined $endCol;
474
318 &user_error('You didn\'t enter any message.') if ($cgi->param('body') eq ''); 475 &user_error( 'You didn\'t enter any message.' ) if ($cgi->param('body') eq '');
319 476
320 my $smtp = Net::SMTP->new($Global::smtpServer, Timeout=>10) || &internal_error("Couldn't contact SMTP server."); 477 my $smtp = Net::SMTP -> new( $Global::smtpServer, Timeout=>10 ) || &internal_error( "Couldn't contact SMTP server." );
321 $smtp->mail($Global::webmaster); 478 $smtp -> mail( $Global::webmaster );
322# $smtp->mail($Global::feedbackAddress); 479# $smtp->mail($Global::feedbackAddress);
323 480
324 if ( $smtp->recipient($EMAIL)) { # this one's okay, keep going 481 if( ( defined($cc) && $cc && $smtp->recipient($EMAIL,$cc) ) || ( $smtp -> recipient($EMAIL) ) ) { # this one's okay, keep going
325 $smtp->data(output() ) || 482 $smtp -> data( output() ) ||
326 &internal_error("Unknown problem sending message data to SMTP server."); 483 &internal_error( "Unknown problem sending message data to SMTP server." );
484 }
327 } else { # we have a problem a problem with this address 485 else { # we have a problem a problem with this address
328 $smtp->reset; 486 $smtp -> reset;
329 &internal_error("SMTP server doesn't like this address: <$EMAIL>."); 487# &internal_error( "SMTP server doesn't like this address: <$EMAIL> or <$cc>." );
488 #I'm not sure why the above line is commented out -- it might be a mistake (but it might not...)
330 } 489 }
331 $smtp->quit; 490 $smtp -> quit;
332 } 491 } # end foreach
492
333 &success; 493 &success;
334 } 494 }
335 } 495}
336 496
337 497
338 498
339#Begin Page 499#Begin Page
340 print &htmlTOP("Send Mail for " . $course), 500 print &htmlTOP("Send Mail for " . $course),
475 635
476print $cgi->hr, $cgi->p, $cgi->b('Enter Message: '), "\n", $cgi->br; 636print $cgi->hr, $cgi->p, $cgi->b('Enter Message: '), "\n", $cgi->br;
477#get message from given messageFileName 637#get message from given messageFileName
478 my ($text, @text); 638 my ($text, @text);
479 my $header = ''; 639 my $header = '';
480 my ($subject, $from, $replyTo); 640 my ($subject, $from, $replyTo, $cc);
481 if (-e "$emailDirectory$messageFileName") { 641 if (-e "$emailDirectory$messageFileName") {
482 open FILE, "$emailDirectory$messageFileName"; 642 open FILE, "$emailDirectory$messageFileName";
483 while ($header !~ s/Message:\s*$//m) { $header .= <FILE>; } 643 while ($header !~ s/Message:\s*$//m) { $header .= <FILE>; }
484 $text = join "", <FILE>; 644 $text = join "", <FILE>;
485 645
486 $header =~ /^From:\s*(.*)$/m; 646 $header =~ /^From:\s*(.*)$/m;
487 $from = $1 or $from = $feedbackAddress; #given email address or default feedback address 647 $from = $1 or $from = $feedbackAddress; #given email address or default feedback address
488 $header =~ /^Reply-To:\s*(.*)$/m; 648 $header =~ /^Reply-To:\s*(.*)$/m;
489 $replyTo = $1 or $replyTo = $feedbackAddress; 649 $replyTo = $1 or $replyTo = $feedbackAddress;
650 $header =~ /^Cc:\s*(.*)$/m;
651 $cc = $1;
490 $header =~ /^Subject:\s*(.*)$/m; 652 $header =~ /^Subject:\s*(.*)$/m;
491 $subject = $1; 653 $subject = $1;
492 654
493 655
494 } else { 656 } else {
495 # wwerror($0, "Message File $emailDirectory$messageFileName does not exist!"); 657 # wwerror($0, "Message File $emailDirectory$messageFileName does not exist!");
496 } 658 }
497 659
498# show professors's name and email address 660# show professors's name and email address
499 print "\n", $cgi->p, $cgi->b('From: '), $cgi->textfield(-name=>"from", -size=>40, -value=>$from, -override=>1), 661 print "\n", $cgi->p, $cgi->b('From: '), $cgi->textfield(-name=>"from", -size=>40, -value=>$from, -override=>1),
500 "\n", $cgi->p, $cgi->b('Reply-To: '), $cgi->textfield(-name=>"replyTo", -size=>40, -value=>$replyTo, -override=>1); 662 "\n", $cgi->p, $cgi->b('Reply-To: '), $cgi->textfield(-name=>"replyTo", -size=>40, -value=>$replyTo, -override=>1),
663 "\n", $cgi->p, $cgi->b('Cc: '), $cgi->textfield(-name=>"cc", -size=>40, -value=>$cc, -override=>1);
501 664
502#create a textbox with the subject and a textarea with the message 665#create a textbox with the subject and a textarea with the message
503 666
504 print "\n", $cgi->p, $cgi->b('Subject: '), $cgi->textfield(-name=>'subject', -default=>$subject, -size=>40, -override=>1), 667 print "\n", $cgi->p, $cgi->b('Subject: '), $cgi->textfield(-name=>'subject', -default=>$subject, -size=>40, -override=>1),
505 $cgi->p, 668 $cgi->p,
685 848
686 849
687 $msg = 850 $msg =
688 # message header 851 # message header
689 "From: " . $cgi->param('from') . "\n" . 852 "From: " . $cgi->param('from') . "\n" .
853 "To: " . $FN . ' ' . $LN . '<' . $EMAIL . '>' . "\n" .
690 "Reply-To: " . $cgi->param('replyTo') . "\n" . 854 "Reply-To: " . $cgi->param('replyTo') . "\n" .
855 "Cc: " . $cgi->param('cc') . "\n" .
691 "Subject: ". $cgi->param('subject') . "\n" . 856 "Subject: " . $cgi->param('subject') . "\n" .
692 "\n" . $tmp . "\n"; 857 "\n" . $tmp . "\n";
693 858
694 $msg =~ s/\r//g; 859 $msg =~ s/\r//g;
695 return $msg; 860 return $msg;
696} 861}
697 862
698sub success { 863sub success {
699 print $cgi->header, 864 # Begin Page with a header
700 $cgi->start_html( '-title'=>'Email Sent'), 865 print htmlTOP("Send Mail for " . $course),
866 $cgi->a( { -href=>"${cgiURL}profLogin.pl?user=$user&key=$session_key&course=$course" },
867 $cgi->img({ -name=>'upImg', -src=>"${Global::upImgUrl}", -align=>'right', -border=>'1', -alt=>'[Up]'})),
868 $cgi->p;
869
870 # Page title
871 print "\n",$cgi->hr, $cgi->br,"\n\n",
872 $cgi->h3({ -align=>'left' }, "Email Sent for $course"), "\n",
873 $cgi->p;
874
875 # Print list of bad addresses
701 $cgi->h1('Your message has been sent.'), 876 print $cgi->h1('Your message has been sent.'),"\n";
702 $cgi->end_html; 877
878
879 # start form with hidden entries to pass info back to profSendMail.pl
880 print $cgi->startform(-action=>"${cgiURL}profSendMail.pl"), "\n",
881 $cgi->hidden(-name=>"user", -value=>$user), "\n",
882 $cgi->hidden(-name=>"key", -value=>$session_key), "\n",
883 $cgi->hidden(-name=>"course", -value=>$course), "\n";
884
885 # create the action button
886 print $cgi->submit(-name=>'.submit', -value=>'Return to Send Email Page'),"\n",
887 $cgi->end_form,
888 htmlBOTTOM("profSendMail", \%inputs, 'profSendMailHelp.html');
889
890 # End of HTML, and this part of the program
703 exit(0); 891 exit(0);
704} 892}

Legend:
Removed from v.5  
changed lines
  Added in v.6

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9