[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / SendMail.pm Repository:
ViewVC logotype

Diff of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm

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

Revision 1372 Revision 1373
9 9
10use strict; 10use strict;
11use warnings; 11use warnings;
12use CGI qw(); 12use CGI qw();
13use HTML::Entities; 13use HTML::Entities;
14use Mail::Sender;
14 15
15sub initialize { 16sub initialize {
16 my ($self) = @_; 17 my ($self) = @_;
17 my $r = $self->{r}; 18 my $r = $self->{r};
18 my $db = $self->{db}; 19 my $db = $self->{db};
271# warn "FIXME saving to ${emailDirectory}/$output_file"; 272# warn "FIXME saving to ${emailDirectory}/$output_file";
272 } elsif ($action eq 'Preview') { 273 } elsif ($action eq 'Preview') {
273 $self->{response} = 'preview'; 274 $self->{response} = 'preview';
274 275
275 } elsif ($action eq 'Send Email') { 276 } elsif ($action eq 'Send Email') {
276 277 $self->{response} = 'send_email';
277 278
279 my @recipients = @{$self->{ra_send_to}};
280 warn "No recipients selected " unless @recipients;
281 # get merge file
282 my $merge_file = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None';
283 my $delimiter = ',';
284 my $rh_merge_data = $self->read_merge_file("$merge_file", "$delimiter");
285 warn "No data for merge file $merge_file" unless ref($rh_merge_data);
286
287 foreach my $recipient (@recipients) {
288 #warn "FIXME sending email to $recipient";
289 my $ur = $self->{db}->getUser($recipient);
290 my ($msg, $preview_header);
291 eval{ ($msg,$preview_header) = $self->process_message($ur,$rh_merge_data); };
292 warn "There were errors in processing user $ur, merge file $merge_file. $@" if $@;
293 my $mailer = Mail::Sender->new({
294 from => $from,
295 to => $ur->email_address,
296 smtp => $ce->{mail}->{smtpServer},
297 subject => $subject,
298 headers => "X-Remote-Host: ".$r->get_remote_host(),
299 });
300 unless (ref $mailer) {
301 warn "Failed to create a mailer: $Mail::Sender::Error";
302 next;
303 }
304 unless (ref $mailer->Open()) {
305 warn "Failed to open the mailer: $Mail::Sender::Error";
306 next;
307 }
308 my $MAIL = $mailer->GetHandle() or warn "Couldn't get handle";
309 $msg = 'Hi ' . $msg;
310 print $MAIL $msg || warn "Couldn't print to $MAIL";
311 close $MAIL || warn "Couldn't close $MAIL";
312 #warn "FIXME mailed to ", $ur->email_address, "from $from subject $subject";
313
314 }
315
316
317#&success;
278 318
279 319
280 } else { 320 } else {
281 warn "Don't recognize button $action"; 321 warn "Didn't recognize button $action";
282 }
283
284 #if Save button was clicked
285 if (( $r->param('action') eq 'Save') && defined($r->param('body')) && defined($r->param('savefilename'))) {
286
287
288 #if Save As button was clicked
289 } elsif (( $r->param('action') eq 'Save as:') && defined($r->param('body')) && defined($r->param('savefilename'))) {
290
291
292 } elsif (( $r->param('action') eq 'save_as_default') && defined($r->param('body'))) {
293
294
295 } elsif ( $r->param('action') eq 'Send Email' ) {
296
297 my @studentID = ();
298
299 if ($r->param('To') eq 'classList' && defined($r->param('classList')) && $r->param('classList') ne 'None') {
300# my $classlist = $r->param('classList');
301# my $classListFile = "$templateDirectory$classlist";
302# my @classList = ();
303# #FIXME checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile);
304# open(FILE, "$classListFile") || die "can't open $classListFile";
305# @classList=<FILE>;
306# close(FILE);
307#
308# foreach (@classList) { ## read through classlist and send e-mail
309# ## message to all active students
310# unless ($_ =~ /\S/) {next;} ## skip blank lines
311# chomp;
312# my @classListRecord=&getRecord($_);
313# my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name)
314# = @classListRecord;
315# unless (&dropStatus($status)) {
316# push (@studentID, $studentID);
317# $fn{$studentID} = $firstName;
318# $ln{$studentID} = $lastName;
319# $section{$studentID} = $section;
320# $recitation{$studentID} = $recitation;
321# $status{$studentID} = $status;
322# $email{$studentID} = $email_address;
323# $login{$studentID} = $login_name;
324# }
325# }
326 } elsif ($r->param('To') eq 'studentID' && defined($r->param('studentID'))) {
327 @studentID = $r->param('studentID');
328 my ($studentID, $login_name);
329#
330# foreach $studentID (@studentID) {
331# $login_name = $studentID_LoginName_Hash{$studentID};
332# &attachCLRecord($login_name);
333# $fn{$studentID} = CL_getStudentFirstName($login_name);
334# $ln{$studentID} = CL_getStudentLastName($login_name);
335# $section{$studentID} = CL_getClassSection($login_name);
336# $recitation{$studentID} = CL_getClassRecitation($login_name);
337# $status{$studentID} = CL_getStudentStatus($login_name);
338# $email{$studentID} = CL_getStudentEmailAddress($login_name);
339# $login{$studentID} = $login_name;
340# }
341
342 } elsif ($r->param('To') eq 'all_students') {
343 @studentID = ();
344 my ($studentID, $login_name, $status);
345
346# foreach $login_name (@availableStudents) {
347# &attachCLRecord($login_name);
348# $status = CL_getStudentStatus($login_name);
349# next if &dropStatus($status);
350# $studentID = CL_getStudentID($login_name);
351# push(@studentID,$studentID);
352#
353# $fn{$studentID} = CL_getStudentFirstName($login_name);
354# $ln{$studentID} = CL_getStudentLastName($login_name);
355# $section{$studentID} = CL_getClassSection($login_name);
356# $recitation{$studentID} = CL_getClassRecitation($login_name);
357# $status{$studentID} = CL_getStudentStatus($login_name);
358# $email{$studentID} = CL_getStudentEmailAddress($login_name);
359# $login{$studentID} = $login_name;
360# }
361 } else {
362 $self->submission_error('You didn\'t select any recipients. Make sure you select either all student in the course, individual students or a whole classlist.');
363 } 322 }
364
365# my $mergeFile = '';
366#
367# #the radio button named 'merge' determines whether to take the selected mergefile
368# #or one that was typed in. A error message is given if select one and use the other
369# $mergeFile = $scoringDirectory . $r->param('mergeFiles')
370# if ($r->param('merge') eq 'mergeFiles' && defined($r->param('mergeFiles')) && $r->param('mergeFiles') ne 'None');
371#
372# $mergeFile = $templateDirectory . $r->param('mergeFile')
373# if ($r->param('merge') eq 'mergeFile' && defined($r->param('mergeFile')) && $r->param('mergeFile') !~ m|/$|); #does not end in a /
374#
375# if ($mergeFile =~ /^[~.]/ || $mergeFile =~ /\.\./) {
376# $self->submission_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");
377# }
378# if ($r->param('body') =~ /(\$COL\[.*?\])/ && !(-e $mergeFile)) {
379# $self->submission_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.");
380# }
381#
382
383 my %mergeAArray = ();
384# unless ($mergeFile eq '') {%mergeAArray = &delim2aa($mergeFile);}
385#
386
387#
388# foreach my $studentID (@studentID) {
389# @COL =();
390# $SID = $studentID;
391# $LN = defined $ln{$studentID} ? $ln{$studentID} :'';
392# $FN = defined $fn{$studentID} ? $fn{$studentID} :'';
393# $SECTION = defined $section{$studentID} ? $section{$studentID} :'';
394# $RECITATION = defined $recitation{$studentID} ? $recitation{$studentID} :'';
395# $EMAIL = defined $email{$studentID} ? $email{$studentID} :'';
396# $STATUS =defined $status{$studentID} ? $status{$studentID} :'';
397# $LOGIN = $login{$studentID};
398#
399# next if ($LOGIN =~ /^$practiceUser/); ## skip practice users
400#
401# if ($timeout_attempts >= $max_timeout_attempts) { ## have attemped to connect to smtp server
402# ## the max allowed times. Now just collect
403# ## data on emails not sent and exit
404# ++$emails_not_sent;
405# &log_error(\@exceeded_max_timeout,$FN,$LN,$EMAIL);
406# next;
407# }
408#
409# unless ((defined $mergeAArray{$studentID}) or ($mergeFile eq '')) {
410# if ($cgi->param('no_record')) {
411# ++$emails_not_sent;
412# &log_error(\@no_record,$FN,$LN,$EMAIL);
413# next;
414# }
415# }
416
417# my ($dbString, @dbArray);
418# if (defined $mergeAArray{$SID}) {
419# $dbString = $mergeAArray{$SID}; ## get sid record from merge file
420# @dbArray = &getRecord($dbString);
421# unshift(@dbArray,$SID);
422# unshift(@dbArray,""); ## note COL[1] is the first column
423# @COL= @dbArray; ## put merge fields in COL array
424# $endCol = @COL; ## \endCol-1 gives last field, etc
425# }
426# my $smtp;
427# if ($smtp = Net::SMTP->new($Global::smtpServer, Timeout => $timeout_sec)) {} else {
428# # &internal_error("Couldn't contact SMTP server.");
429# ++$emails_not_sent;
430# &log_error(\@timeout_problem,$FN,$LN,$EMAIL);
431# ++$timeout_attempts;
432# next;
433# }
434#
435# $smtp->mail($smtpSender);
436#
437# if ( $smtp->recipient($EMAIL)) { # this one's okay, keep going
438# if ( $smtp->data("To: $EMAIL\n" . output() ) ) {
439# ++$emails_sent;
440# } else {
441# ++$emails_not_sent;
442# &log_error(\@unknown_problem,$FN,$LN,$EMAIL);
443# next;
444# }
445# # &internal_error("Unknown problem sending message data to SMTP server.");
446# } else { # we have a problem with this address
447# $smtp->reset;
448# #&internal_error("SMTP server doesn't like this address: <$EMAIL>.");
449# ++$emails_not_sent;
450# &log_error(\@bad_email_addresses,$FN,$LN,$EMAIL);
451# }
452# $smtp->quit;
453# }
454# &success;
455 }
456
457 323
458 324
459 325
460} #end initialize 326} #end initialize
461 327
462# sub fieldEditHTML {
463# my ($self, $fieldName, $value, $properties) = @_;
464# my $size = $properties->{size};
465# my $type = $properties->{type};
466# my $access = $properties->{access};
467# my $items = $properties->{items};
468# my $synonyms = $properties->{synonyms};
469#
470#
471# if ($access eq "readonly") {
472# return $value;
473# }
474# if ($type eq "number" or $type eq "text") {
475# return CGI::input({type=>"text", name=>$fieldName, value=>$value, size=>$size});
476# }
477# if ($type eq "enumerable") {
478# my $matched = undef; # Whether a synonym match has occurred
479#
480# # Process synonyms for enumerable objects
481# foreach my $synonym (keys %$synonyms) {
482# if ($synonym ne "*" and $value =~ m/$synonym/) {
483# $value = $synonyms->{$synonym};
484# $matched = 1;
485# }
486# }
487# if (!$matched and exists $synonyms->{"*"}) {
488# $value = $synonyms->{"*"};
489# }
490# return CGI::popup_menu({
491# name => $fieldName,
492# values => [keys %$items],
493# default => $value,
494# labels => $items,
495# });
496# }
497# }
498 328
499sub title { 329sub title {
500 my $self = shift; 330 my $self = shift;
501 return 'Send mail to ' .$self->{ce}->{courseName}; 331 return 'Send mail to ' .$self->{ce}->{courseName};
502} 332}
519sub body { 349sub body {
520 my ($self, $setID) = @_; 350 my ($self, $setID) = @_;
521 my $response = (defined($self->{response}))? $self->{response} : ''; 351 my $response = (defined($self->{response}))? $self->{response} : '';
522 if ($response eq 'preview') { 352 if ($response eq 'preview') {
523 $self->print_preview($setID); 353 $self->print_preview($setID);
524 } else { 354 } elsif (($response eq 'send_email')){
355 $self->{message} .= CGI::h3("Email sent to "). join(" ", @{$self->{ra_send_to}});
525 $self->print_form($setID); 356 $self->print_form($setID);
526 } 357 }
527 358
528} 359}
529sub print_preview { 360sub print_preview {
537 my $rh_merge_data = $self->read_merge_file("$merge_file", "$delimiter"); 368 my $rh_merge_data = $self->read_merge_file("$merge_file", "$delimiter");
538 369
539 my ($msg, $preview_header) = $self->process_message($ur,$rh_merge_data); 370 my ($msg, $preview_header) = $self->process_message($ur,$rh_merge_data);
540 371
541 my $recipients = join(" ",@{$self->{ra_send_to} }); 372 my $recipients = join(" ",@{$self->{ra_send_to} });
373 my $errorMessage = defined($self->{submitError}) ? CGI::h3($self->{submitError} ) : '' ;
374 $msg = join("",
375 $errorMessage,
376 $preview_header,
377 "To: " , $ur->email_address,"\n",
378 "From: " , $self->{from} , "\n" ,
379 "Reply-To: " , $self->{replyTo} , "\n" ,
380 "Subject: " , $self->{subject} , "\n" ,"\n" ,
381 $msg , "\n"
382 );
542 383
543 return join("", '<pre>',$preview_header,$msg,"\n","\n", 384 return join("", '<pre>',$msg,"\n","\n",
544 '</pre>', 385 '</pre>',
545 CGI::p('Use browser back button to return from preview mode'), 386 CGI::p('Use browser back button to return from preview mode'),
546 CGI::h3('Emails to be sent to the following:'), 387 CGI::h3('Emails to be sent to the following:'),
547 $recipients, "\n", 388 $recipients, "\n",
548 389
696# ), "\n",CGI::br(); 537# ), "\n",CGI::br();
697# warn "merge keys ", join( " ",@merge_keys); 538# warn "merge keys ", join( " ",@merge_keys);
698############################################################################################# 539#############################################################################################
699# merge file fragment and message text area field 540# merge file fragment and message text area field
700############################################################################################# 541#############################################################################################
701 542 my @tmp2;
702 my @tmp2= @{$rh_merge_data->{ $db->getUser($preview_user)->student_id } }; 543 eval{ @tmp2= @{$rh_merge_data->{ $db->getUser($preview_user)->student_id } };};
544 if ($@) {
545 print CGI::p( "Couldn't get merge data for $preview_user", CGI::br(), $@) ;
546 } else {
703 print CGI::pre("",data_format(0..($#tmp2)),"\n", data_format(@tmp2)); 547 print CGI::pre("",data_format(0..($#tmp2)),"\n", data_format(@tmp2));
548 }
704#create a textbox with the subject and a textarea with the message 549#create a textbox with the subject and a textarea with the message
705#print actual body of message 550#print actual body of message
706 551
707 print "\n", CGI::p( $self->{message}) if defined($self->{message}); 552 print "\n", CGI::p( $self->{message}) if defined($self->{message});
708 print "\n", CGI::p( CGI::textarea(-name=>'body', -default=>$text, -rows=>$rows, -columns=>$columns, -override=>1)); 553 print "\n", CGI::p( CGI::textarea(-name=>'body', -default=>$text, -rows=>$rows, -columns=>$columns, -override=>1));
875 my $STATUS = $ur->status; 720 my $STATUS = $ur->status;
876 my $EMAIL = $ur->email_address; 721 my $EMAIL = $ur->email_address;
877 my $LOGIN = $ur->user_id; 722 my $LOGIN = $ur->user_id;
878 # get record from merge file 723 # get record from merge file
879 # FIXME this is inefficient. The info should be cached 724 # FIXME this is inefficient. The info should be cached
880 my @COL = @{$rh_merge_data->{$SID} }; 725 my @COL = defined($rh_merge_data->{$SID}) ? @{$rh_merge_data->{$SID} } : ();
726 $self->submission_error( "No merge data for $SID $FN $LN $LOGIN") unless defined($rh_merge_data->{$SID});
881 727
882 my $endCol = @COL; 728 my $endCol = @COL;
883 # for safety, only evaluate special variables 729 # for safety, only evaluate special variables
884 my $tmp = $text; 730 my $msg = $text;
885 $tmp =~ s/(\$SID)/eval($1)/ge; 731 $msg =~ s/(\$SID)/eval($1)/ge;
886 $tmp =~ s/(\$LN)/eval($1)/ge; 732 $msg =~ s/(\$LN)/eval($1)/ge;
887 $tmp =~ s/(\$FN)/eval($1)/ge; 733 $msg =~ s/(\$FN)/eval($1)/ge;
888 $tmp =~ s/(\$STATUS)/eval($1)/ge; 734 $msg =~ s/(\$STATUS)/eval($1)/ge;
889 $tmp =~ s/(\$SECTION)/eval($1)/ge; 735 $msg =~ s/(\$SECTION)/eval($1)/ge;
890 $tmp =~ s/(\$RECITATION)/eval($1)/ge; 736 $msg =~ s/(\$RECITATION)/eval($1)/ge;
891 $tmp =~ s/(\$EMAIL)/eval($1)/ge; 737 $msg =~ s/(\$EMAIL)/eval($1)/ge;
892 $tmp =~ s/(\$LOGIN)/eval($1)/ge; 738 $msg =~ s/(\$LOGIN)/eval($1)/ge;
893 $tmp =~ s/\$COL\[ *-/\$COL\[$endCol-/g; 739 $msg =~ s/\$COL\[ *-/\$COL\[$endCol-/g;
894 $tmp =~ s/(\$COL\[.*?\])/eval($1)/ge; 740 $msg =~ s/(\$COL\[.*?\])/eval($1)/ge;
741
742 $msg =~ s/\r//g;
895 743
896 my $preview_header = CGI::pre("",data_format(0..($#COL)),"\n", data_format(@COL)). 744 my $preview_header = CGI::pre("",data_format(0..($#COL)),"\n", data_format(@COL)).
897 CGI::h3( "This sample mail would be sent to $EMAIL"); 745 CGI::h3( "This sample mail would be sent to $EMAIL");
898 746
899 747
900 my $msg = join("",
901 "To: " , $ur->email_address,"\n",
902 "From: " , $self->{from} , "\n" ,
903 "Reply-To: " , $self->{replyTo} , "\n" ,
904 "Subject: " , $self->{subject} , "\n" ,"\n" ,
905 $tmp , "\n"
906 );
907
908 $msg =~ s/\r//g;
909 return $msg, $preview_header; 748 return $msg, $preview_header;
910} 749}
911 sub data_format { 750 sub data_format {
912 map {$_ =~s/\s/\./g;$_} map {sprintf('%-8.8s',$_);} @_; 751 map {$_ =~s/\s/\./g;$_} map {sprintf('%-8.8s',$_);} @_;
913 } 752 }

Legend:
Removed from v.1372  
changed lines
  Added in v.1373

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9