--- loncom/interface/lonmsg.pm 2005/11/01 15:59:18 1.153
+++ loncom/interface/lonmsg.pm 2006/04/23 05:47:33 1.173.2.1
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines for messaging
#
-# $Id: lonmsg.pm,v 1.153 2005/11/01 15:59:18 www Exp $
+# $Id: lonmsg.pm,v 1.173.2.1 2006/04/23 05:47:33 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -97,6 +97,17 @@ Right now, this document will cover just
it is likely you will not need to programmatically read messages,
since lonmsg already implements that functionality.
+The routines used to package messages and unpackage messages are not
+only used by lonmsg when creating/extracting messages for LON-CAPA's
+internal messaging system, but also by lonnotify.pm which is available
+for use by Domain Coordinators to broadcast standard e-mail to specified
+users in their domain. The XML packaging used in the two cases is very
+similar. The differences are the use of $uname and
+$udom in stored internal messages, compared
+with $email in stored
+Domain Coordinator e-mail for the storage of information about
+recipients of the message/e-mail.
+
=head1 FUNCTIONS
=over 4
@@ -115,6 +126,7 @@ use Mail::Send;
use Apache::lonlocal;
use Apache::loncommunicate;
use Apache::lonfeedback;
+use Apache::lonrss();
# Querystring component with sorting type
my $sqs;
@@ -125,7 +137,7 @@ my $interdis;
sub packagemsg {
my ($subject,$message,$citation,$baseurl,$attachmenturl,
- $recuser,$recdomain)=@_;
+ $recuser,$recdomain,$msgid,$type)=@_;
$message =&HTML::Entities::encode($message,'<>&"');
$citation=&HTML::Entities::encode($citation,'<>&"');
$subject =&HTML::Entities::encode($subject,'<>&"');
@@ -135,15 +147,29 @@ sub packagemsg {
#remove machine specification
$attachmenturl =~ s|^http://[^/]+/|/|;
$attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
-
+ my $course_context;
+ if (defined($env{'form.replyid'})) {
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
+ split(/\:/,&Apache::lonnet::unescape($env{'form.replyid'}));
+ $course_context = $origcid;
+ }
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.(rep)?rec\_(.*)$/) {
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) =
+ split(/\:/,&Apache::lonnet::unescape($2));
+ $course_context = $origcid;
+ last;
+ }
+ }
+ unless(defined($course_context)) {
+ $course_context = $env{'request.course.id'};
+ }
my $now=time;
$msgcount++;
- my $partsubj=$subject;
- $partsubj=&Apache::lonnet::escape($partsubj);
- my $msgid=&Apache::lonnet::escape(
- $now.':'.$partsubj.':'.$env{'user.name'}.':'.
- $env{'user.domain'}.':'.$msgcount.':'.
- $env{'request.course.id'}.':'.$$);
+ unless(defined($msgid)) {
+ $msgid = &buildmsgid($now,$subject,$env{'user.name'},$env{'user.domain'},
+ $msgcount,$course_context,$$);
+ }
my $result=''.$env{'user.name'}.''.
''.$env{'user.domain'}.''.
''.$subject.''.
@@ -156,14 +182,31 @@ sub packagemsg {
''.$env{'browser.version'}.''.
''.$env{'browser.mathml'}.''.
''.$ENV{'HTTP_USER_AGENT'}.''.
- ''.$env{'request.course.id'}.''.
+ ''.$course_context.''.
''.$env{'request.course.sec'}.''.
''.$env{'request.role'}.''.
''.$env{'request.filename'}.''.
- ''.$msgid.''.
- ''.$recuser.''.
- ''.$recdomain.''.
- ''.$message.'';
+ ''.$msgid.'';
+ if (ref($recuser) eq 'ARRAY') {
+ for (my $i=0; $i<@{$recuser}; $i++) {
+ if ($type eq 'dcmail') {
+ my ($username,$email) = split(/:/,$$recuser[$i]);
+ $username = &Apache::lonnet::unescape($username);
+ $email = &Apache::lonnet::unescape($email);
+ $username = &HTML::Entities::encode($username,'<>&"');
+ $email = &HTML::Entities::encode($email,'<>&"');
+ $result .= ''.
+ $email.'';
+ } else {
+ $result .= ''.$$recuser[$i].''.
+ ''.$$recdomain[$i].'';
+ }
+ }
+ } else {
+ $result .= ''.$recuser.''.
+ ''.$recdomain.'';
+ }
+ $result .= ''.$message.'';
if (defined($citation)) {
$result.=''.$citation.'';
}
@@ -187,9 +230,18 @@ sub unpackagemsg {
if ($token->[0] eq 'S') {
my $entry=$token->[1];
my $value=$parser->get_text('/'.$entry);
- $content{$entry}=$value;
+ if (($entry eq 'recuser') || ($entry eq 'recdomain')) {
+ push(@{$content{$entry}},$value);
+ } elsif ($entry eq 'recipient') {
+ my $username = $token->[2]{'username'};
+ $username = &HTML::Entities::decode($username,'<>&"');
+ $content{$entry}{$username} = $value;
+ } else {
+ $content{$entry}=$value;
+ }
}
}
+ if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
if ($content{'attachmenturl'}) {
my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
if ($notoken) {
@@ -207,15 +259,30 @@ sub unpackagemsg {
# ======================================================= Get info out of msgid
+sub buildmsgid {
+ my ($now,$subject,$uname,$udom,$msgcount,$course_context,$pid) = @_;
+ $subject=&Apache::lonnet::escape($subject);
+ return(&Apache::lonnet::escape($now.':'.$subject.':'.$uname.':'.
+ $udom.':'.$msgcount.':'.$course_context.':'.$pid));
+}
+
sub unpackmsgid {
- my ($msgid,$folder)=@_;
+ my ($msgid,$folder,$skipstatus,$status_cache)=@_;
$msgid=&Apache::lonnet::unescape($msgid);
- my $suffix=&foldersuffix($folder);
- my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid)=split(/\:/,
- &Apache::lonnet::unescape($msgid));
- my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
- if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
- unless ($status{$msgid}) { $status{$msgid}='new'; }
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid,
+ $processid)=split(/\:/,&Apache::lonnet::unescape($msgid));
+ if (!defined($processid)) { $fromcid = ''; }
+ my %status=();
+ unless ($skipstatus) {
+ if (ref($status_cache)) {
+ $status{$msgid} = $status_cache->{$msgid};
+ } else {
+ my $suffix=&foldersuffix($folder);
+ %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
+ }
+ if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
+ unless ($status{$msgid}) { $status{$msgid}='new'; }
+ }
return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid);
}
@@ -367,7 +434,7 @@ sub all_url_author_res_msg {
# ================================================== Critical message to a user
sub user_crit_msg_raw {
- my ($user,$domain,$subject,$message,$sendback,$toperm)=@_;
+ my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;
# Check if allowed missing
my $status='';
my $msgid='undefined';
@@ -381,13 +448,9 @@ sub user_crit_msg_raw {
'put:'.$domain.':'.$user.':critical:'.
&Apache::lonnet::escape($msgid).'='.
&Apache::lonnet::escape($message),$homeserver);
- if ($env{'request.course.id'}) {
- &user_normal_msg_raw(
- $env{'course.'.$env{'request.course.id'}.'.num'},
- $env{'course.'.$env{'request.course.id'}.'.domain'},
- 'Critical ['.$user.':'.$domain.']',
- $message);
- }
+ if (defined($sentmessage)) {
+ $$sentmessage = $message;
+ }
} else {
$status='no_host';
}
@@ -425,7 +488,7 @@ sub user_crit_msg_raw {
=cut
sub user_crit_msg {
- my ($user,$domain,$subject,$message,$sendback,$toperm)=@_;
+ my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_;
my $status='';
my %userenv = &Apache::lonnet::get('environment',['msgforward'],
$domain,$user);
@@ -435,10 +498,10 @@ sub user_crit_msg {
my ($forwuser,$forwdomain)=split(/\:/,$_);
$status.=
&user_crit_msg_raw($forwuser,$forwdomain,$subject,$message,
- $sendback,$toperm).' ';
+ $sendback,$toperm,$sentmessage).' ';
}
} else {
- $status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback,$toperm);
+ $status=&user_crit_msg_raw($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage);
}
return $status;
}
@@ -473,33 +536,47 @@ sub user_crit_received {
sub user_normal_msg_raw {
my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
- $toperm)=@_;
+ $toperm,$currid,$newid,$sentmessage)=@_;
# Check if allowed missing
- my $status='';
+ my ($status,$packed_message);
my $msgid='undefined';
my $text=$message;
unless (($message)&&($user)&&($domain)) { $status='empty'; };
my $homeserver=&Apache::lonnet::homeserver($user,$domain);
if ($homeserver ne 'no_host') {
- ($msgid,$message)=&packagemsg($subject,$message,$citation,$baseurl,
- $attachmenturl,$user,$domain);
+ ($msgid,$packed_message)=
+ &packagemsg($subject,$message,$citation,$baseurl,
+ $attachmenturl,$user,$domain,$currid);
+ (undef, my $packed_message_no_citation)=
+ &packagemsg($subject,$message,undef ,$baseurl,
+ $attachmenturl,$user,$domain,$currid);
# Store in user folder
$status=&Apache::lonnet::critical(
'put:'.$domain.':'.$user.':nohist_email:'.
&Apache::lonnet::escape($msgid).'='.
- &Apache::lonnet::escape($message),$homeserver);
+ &Apache::lonnet::escape($packed_message),$homeserver);
# Save new message received time
&Apache::lonnet::put
('email_status',{'recnewemail'=>time},$domain,$user);
-# Into sent-mail folder
- $status.=' '.&Apache::lonnet::critical(
- 'put:'.$env{'user.domain'}.':'.$env{'user.name'}.
- ':nohist_email_sent:'.
- &Apache::lonnet::escape($msgid).'='.
- &Apache::lonnet::escape($message),$env{'user.home'});
+# Into sent-mail folder unless a broadcast message or critical message
+ unless (($env{'request.course.id'}) &&
+ (($env{'form.sendmode'} eq 'group') ||
+ (($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
+ (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})))) {
+ $status .= &store_sent_mail($msgid,$packed_message_no_citation);
+ }
} else {
$status='no_host';
}
+ if (defined($newid)) {
+ $$newid = $msgid;
+ }
+ if (defined($sentmessage)) {
+ $$sentmessage = $packed_message;
+ }
+
# Notifications
my %userenv = &Apache::lonnet::get('environment',['notification',
'permanentemail'],
@@ -530,25 +607,36 @@ sub user_normal_msg_raw {
sub user_normal_msg {
my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl,
- $toperm)=@_;
+ $toperm,$sentmessage)=@_;
my $status='';
my %userenv = &Apache::lonnet::get('environment',['msgforward'],
$domain,$user);
my $msgforward=$userenv{'msgforward'};
if ($msgforward) {
- foreach (split(/\,/,$msgforward)) {
- my ($forwuser,$forwdomain)=split(/\:/,$_);
- $status.=
- &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
- $citation,$baseurl,$attachmenturl,$toperm).' ';
- }
+ foreach (split(/\,/,$msgforward)) {
+ my ($forwuser,$forwdomain)=split(/\:/,$_);
+ $status.=
+ &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message,
+ $citation,$baseurl,$attachmenturl,$toperm,
+ undef,undef,$sentmessage).' ';
+ }
} else {
$status=&user_normal_msg_raw($user,$domain,$subject,$message,
- $citation,$baseurl,$attachmenturl,$toperm);
+ $citation,$baseurl,$attachmenturl,$toperm,
+ undef,undef,$sentmessage);
}
return $status;
}
+sub store_sent_mail {
+ my ($msgid,$message) = @_;
+ my $status =' '.&Apache::lonnet::critical(
+ 'put:'.$env{'user.domain'}.':'.$env{'user.name'}.
+ ':nohist_email_sent:'.
+ &Apache::lonnet::escape($msgid).'='.
+ &Apache::lonnet::escape($message),$env{'user.home'});
+ return $status;
+}
# ============================================================ List all folders
@@ -612,8 +700,9 @@ sub statuschange {
&Apache::lonnet::put('email_status'.$suffix,{$msgid => $newstatus});
}
if ($newstatus eq 'deleted') {
- &movemsg(&Apache::lonnet::unescape($msgid),$folder,'trash');
- }
+ return &movemsg($msgid,$folder,'trash');
+ }
+ return ;
}
# ============================================================= Make new folder
@@ -634,19 +723,53 @@ sub movemsg {
if ($srcfolder eq 'new') { $srcfolder=''; }
my $srcsuffix=&foldersuffix($srcfolder);
my $trgsuffix=&foldersuffix($trgfolder);
+ if ($srcsuffix eq $trgsuffix) {
+ return (0,&mt('Message not moved, Attempted to move message to the same folder as it already is in.'));
+ }
# Copy message
my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]);
- &Apache::lonnet::put('nohist_email'.$trgsuffix,{$msgid => $message{$msgid}});
+ if (!exists($message{$msgid}) || $message{$msgid} eq '') {
+ if (&Apache::slotrequest::network_error(%message)) {
+ return (0,&mt('Message not moved, A network error occurred.'));
+ } else {
+ return (0,&mt('Message not moved as the message is no longer in the source folder.'));
+ }
+ }
+
+ my $result =&Apache::lonnet::put('nohist_email'.$trgsuffix,
+ {$msgid => $message{$msgid}});
+ if (&Apache::slotrequest::network_error($result)) {
+ return (0,&mt('Message not moved, A network error occurred.'));
+ }
# Copy status
unless ($trgfolder eq 'trash') {
- my %status=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);
- &Apache::lonnet::put('email_status'.$trgsuffix,{$msgid => $status{$msgid}});
+ my %status=&Apache::lonnet::get('email_status'.$srcsuffix,[$msgid]);
+ # a non-existant status is the mark of an unread msg
+ if (&Apache::slotrequest::network_error(%status)) {
+ return (0,&mt('Message copied to new folder but status was not, A network error occurred.'));
+ }
+ my $result=&Apache::lonnet::put('email_status'.$trgsuffix,
+ {$msgid => $status{$msgid}});
+ if (&Apache::slotrequest::network_error($result)) {
+ return (0,&mt('Message copied to new folder but status was not, A network error occurred.'));
+ }
}
+
# Delete orginals
- &Apache::lonnet::del('nohist_email'.$srcsuffix,[$msgid]);
- &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
+ my $result_del_msg =
+ &Apache::lonnet::del('nohist_email'.$srcsuffix,[$msgid]);
+ my $result_del_stat =
+ &Apache::lonnet::del('email_status'.$srcsuffix,[$msgid]);
+ if (&Apache::slotrequest::network_error($result_del_msg)) {
+ return (0,&mt('Message copied, but unable to delete the original from the source folder.'));
+ }
+ if (&Apache::slotrequest::network_error($result_del_stat)) {
+ return (0,&mt('Message copied, but unable to delete the original status from the source folder.'));
+ }
+
+ return (1);
}
# ======================================================= Display a course list
@@ -782,12 +905,17 @@ sub sortedmessages {
my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
#unpack the varibles and repack into temp for sorting
my @temp;
+ my %descriptions;
+ my %status_cache =
+ &Apache::lonnet::get('email_status'.&foldersuffix($folder),\@messages);
foreach (@messages) {
my $msgid=&Apache::lonnet::escape($_);
my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)=
- &Apache::lonmsg::unpackmsgid($msgid,$folder);
+ &Apache::lonmsg::unpackmsgid($msgid,$folder,undef,
+ \%status_cache);
+ my $description = &get_course_desc($fromcid,\%descriptions);
my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
- $msgid);
+ $msgid,$description);
# Check whether message was sent during blocking period.
if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) {
my $escid = &Apache::lonnet::unescape($msgid);
@@ -823,6 +951,12 @@ sub sortedmessages {
if ($env{'form.sortedby'} eq "revsubject"){
@temp = sort {lc($b->[1]) cmp lc($a->[1])} @temp;
}
+ if ($env{'form.sortedby'} eq "course"){
+ @temp = sort {lc($a->[6]) cmp lc($b->[6])} @temp;
+ }
+ if ($env{'form.sortedby'} eq "revcourse"){
+ @temp = sort {lc($b->[6]) cmp lc($a->[6])} @temp;
+ }
if ($env{'form.sortedby'} eq "status"){
@temp = sort {$a->[4] cmp $b->[4]} @temp;
}
@@ -832,6 +966,27 @@ sub sortedmessages {
return @temp;
}
+sub get_course_desc {
+ my ($fromcid,$descriptions) = @_;
+ my $description;
+ if (!$fromcid) {
+ return $description;
+ } else {
+ if (defined($$descriptions{$fromcid})) {
+ $description = $$descriptions{$fromcid};
+ } else {
+ if (defined($env{'course.'.$fromcid.'.description'})) {
+ $description = $env{'course.'.$fromcid.'.description'};
+ } else {
+ my %courseinfo=&Apache::lonnet::coursedescription($fromcid); $description = $courseinfo{'description'};
+ $description = $courseinfo{'description'};
+ }
+ $$descriptions{$fromcid} = $description;
+ }
+ return $description;
+ }
+}
+
# ======================================================== Display new messages
@@ -840,15 +995,13 @@ sub disnew {
my %lt=&Apache::lonlocal::texthash(
'nm' => 'New Messages',
'su' => 'Subject',
+ 'co' => 'Course',
'da' => 'Date',
'us' => 'Username',
'op' => 'Open',
'do' => 'Domain'
);
- my @msgids = sort split(/\&/,&Apache::lonnet::reply
- ('keys:'.$env{'user.domain'}.':'.
- $env{'user.name'}.':nohist_email',
- $env{'user.home'}));
+ my @msgids = sort(&Apache::lonnet::getkeys('nohist_email'));
my @newmsgs;
my %setters = ();
my $startblock = 0;
@@ -857,10 +1010,15 @@ sub disnew {
my $numblocked = 0;
# Check for blocking of display because of scheduled online exams.
&blockcheck(\%setters,\$startblock,\$endblock);
+ my %status_cache =
+ &Apache::lonnet::get('email_status',\@msgids);
+ my %descriptions;
foreach (@msgids) {
+ my $msgid=&Apache::lonnet::escape($_);
my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
- &Apache::lonmsg::unpackmsgid($_);
+ &Apache::lonmsg::unpackmsgid($msgid,undef,undef,\%status_cache);
if (defined($sendtime) && $sendtime!~/error/) {
+ my $description = &get_course_desc($fromcid,\%descriptions);
my $numsendtime = $sendtime;
$sendtime = &Apache::lonlocal::locallocaltime($sendtime);
if ($status eq 'new') {
@@ -869,11 +1027,12 @@ sub disnew {
$numblocked ++;
} else {
push @newmsgs, {
- msgid => $_,
+ msgid => $msgid,
sendtime => $sendtime,
shortsub => &Apache::lonnet::unescape($shortsubj),
from => $fromname,
- fromdom => $fromdom
+ fromdom => $fromdom,
+ course => $description
}
}
}
@@ -883,7 +1042,7 @@ sub disnew {
$r->print(<$lt{'nm'}
  |
-$lt{'da'} | $lt{'us'} | $lt{'do'} | $lt{'su'} |
+$lt{'da'} | $lt{'us'} | $lt{'do'} | $lt{'su'} | $lt{'co'} |
TABLEHEAD
foreach my $msg (@newmsgs) {
$r->print(<<"ENDLINK");
@@ -891,7 +1050,7 @@ TABLEHEAD
onMouseOut="javascript:style.backgroundColor='#FFBB77'">
$lt{'op'} |
ENDLINK
- foreach ('sendtime','from','fromdom','shortsub') {
+ foreach ('sendtime','from','fromdom','shortsub','course') {
$r->print("$msg->{$_} | ");
}
$r->print("");
@@ -1005,6 +1164,12 @@ ENDDISHEADER
$r->print(''.&mt('Subject').'');
}
$r->print('');
+ if ($env{'form.sortedby'} eq "revcourse") {
+ $r->print(''.&mt('Course').'');
+ } else {
+ $r->print(''.&mt('Course').'');
+ }
+ $r->print(' | ');
if ($env{'form.sortedby'} eq "revstatus") {
$r->print(''.&mt('Status').' | ');
} else {
@@ -1012,7 +1177,7 @@ ENDDISHEADER
}
$r->print("\n");
for (my $n=$firstdis;$n<=$lastdis;$n++) {
- my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID)= @{$temp[$n]};
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID,$description)= @{$temp[$n]};
if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) {
if ($status eq 'new') {
$r->print('');
@@ -1030,10 +1195,12 @@ ENDDISHEADER
''.&Apache::lonlocal::locallocaltime($sendtime).' | '.
$fromname.' | '.$fromdomain.' | '.
&Apache::lonnet::unescape($shortsubj).' | '.
- $status." |
\n");
+ $description.''.$status.' | '."\n");
} elsif ($status eq 'deleted') {
# purge
- &movemsg(&Apache::lonnet::unescape($origID),$folder,'trash');
+ my ($result,$msg) =
+ &movemsg(&Apache::lonnet::unescape($origID),$folder,'trash');
+
}
}
$r->print("
\n".
@@ -1106,7 +1273,9 @@ sub compout {
'ca' => 'Cancel',
'ma' => 'Mail');
- if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
+ if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
$dispcrit=
'
' . $crithelp .
@@ -1114,8 +1283,9 @@ sub compout {
'' . $crithelp .
'
';
- }
+&mt('Send copy to permanent email address (if known)').'
'.
+''; }
my %message;
my %content;
my $defdom=$env{'user.domain'};
@@ -1231,7 +1401,7 @@ $dispcrit
ENDUPLOAD
}
if ($broadcast eq 'group') {
- &discourse;
+ &discourse($r);
}
$r->print(''.
&Apache::lonfeedback::generate_preview_button('compemail','message').
@@ -1244,7 +1414,9 @@ sub retrieve_instructor_comments {
my ($user,$domain)=@_;
my $target=$env{'form.grade_target'};
if (! $env{'request.course.id'}) { return; }
- if (! &Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
+ if (! &Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
return;
}
my %records=&Apache::lonnet::dump('nohist_email',
@@ -1269,7 +1441,10 @@ sub disfacetoface {
my ($r,$user,$domain)=@_;
my $target=$env{'form.grade_target'};
unless ($env{'request.course.id'}) { return; }
- unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
+ if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
+ $r->print('Not allowed');
return;
}
my %records=&Apache::lonnet::dump('nohist_email',
@@ -1285,6 +1460,12 @@ sub disfacetoface {
$result.=''.&mt('Record').'
';
} elsif ($content{'subject'}=~/^Broadcast/) {
$result .=''.&mt('Broadcast Message').'
';
+ if ($content{'subject'}=~/^Broadcast\./) {
+ %content=&unpackagemsg($content{'message'});
+ $content{'message'}=
+ ''.&mt('Subject').': '.$content{'subject'}.'
'.
+ $content{'message'};
+ }
} else {
$result.=''.&mt('Critical Message').'
';
%content=&unpackagemsg($content{'message'});
@@ -1317,7 +1498,10 @@ $content{'sendername'}.'@'.
sub facetoface {
my ($r,$stage)=@_;
- unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) {
+ if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
+ $r->print('Not allowed');
return;
}
&printheader($r,
@@ -1360,12 +1544,13 @@ ENDTREC
($env{'form.recdomain'}) && ($env{'form.recuname'})) {
chomp($env{'form.newrecord'});
if ($env{'form.newrecord'}) {
+ my $recordtxt = $env{'form.newrecord'};
&user_normal_msg_raw(
$env{'course.'.$env{'request.course.id'}.'.num'},
$env{'course.'.$env{'request.course.id'}.'.domain'},
&mt('Record').
' ['.$env{'form.recuname'}.':'.$env{'form.recdomain'}.']',
- $env{'form.newrecord'});
+ $recordtxt);
}
$r->print(''.&Apache::loncommon::plainname($env{'form.recuname'},
$env{'form.recdomain'}).'
');
@@ -1391,7 +1576,12 @@ ENDBFORM
sub examblock {
my ($r,$action) = @_;
unless ($env{'request.course.id'}) { return;}
- unless (&Apache::lonnet::allowed('srm',$env{'request.course.id'})) { $r->print('Not allowed'); }
+ if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})) {
+ $r->print('Not allowed');
+ return;
+ }
my %lt=&Apache::lonlocal::texthash(
'comb' => 'Communication Blocking',
'cbds' => 'Communication blocking during scheduled exams',
@@ -1824,6 +2014,16 @@ sub displaymessage {
}
$r->print('');
}
+ my $tolist;
+ my @recipients = ();
+ for (my $i=0; $i<@{$content{'recuser'}}; $i++) {
+ $recipients[$i] = &Apache::loncommon::aboutmewrapper(
+ &Apache::loncommon::plainname($content{'recuser'}[$i],
+ $content{'recdomain'}[$i]),
+ $content{'recuser'}[$i],$content{'recdomain'}[$i]).
+ ' ('.$content{'recuser'}[$i].' at '.$content{'recdomain'}[$i].') ';
+ }
+ $tolist = join(', ',@recipients);
$r->print('
'.&mt('Subject').': '.$content{'subject'}.
($folder ne 'sent'?'
'.&mt('From').': '.
&Apache::loncommon::aboutmewrapper(
@@ -1831,11 +2031,7 @@ sub displaymessage {
$content{'sendername'},$content{'senderdomain'}).' ('.
$content{'sendername'}.' at '.
$content{'senderdomain'}.') ':'
'.&mt('To').': '.
- &Apache::loncommon::aboutmewrapper(
- &Apache::loncommon::plainname($content{'recuser'},$content{'recdomain'}),
- $content{'recuser'},$content{'recdomain'}).' ('.
- $content{'recuser'}.' at '.
- $content{'recdomain'}.') ').
+ $tolist).
($content{'courseid'}?'
'.&mt('Course').': '.$courseinfo{'description'}.
($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):'').
'
'.&mt('Time').': '.$content{'time'}.
@@ -1876,9 +2072,10 @@ sub displayresource {
$content{'sendername'},
$content{'senderdomain'},
$content{'courseid'});
- } else {
+ } elsif ($env{'user.adv'}) {
return $content{'citation'};
}
+ return '';
}
# ================================================================== The Header
@@ -1950,6 +2147,8 @@ sub sendoffmail {
my ($r,$folder)=@_;
my $suffix=&foldersuffix($folder);
my $sendstatus='';
+ my %specialmsg_status;
+ my $numspecial = 0;
if ($env{'form.send'}) {
&printheader($r,'','Messages being sent.');
$r->rflush();
@@ -1994,42 +2193,107 @@ sub sendoffmail {
$toaddr{$auname.':'.$audom}='';
}
}
+
+ my $savemsg;
+ my $msgtype;
+ my %sentmessage;
+ if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
+ (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'})
+ )) {
+ $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'},1);
+ $msgtype = 'critical';
+ } else {
+ $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'});
+ }
foreach (keys %toaddr) {
my ($recuname,$recdomain)=split(/\:/,$_);
- my $msgtxt;
- if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
- (&Apache::lonnet::allowed('srm',$env{'request.course.id'}))) {
- $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'},1);
- } else {
- $msgtxt=&Apache::lonfeedback::clear_out_html($env{'form.message'});
- }
+ my $msgtxt = $savemsg;
if ($toaddr{$_}) { $msgtxt.='
'.$toaddr{$_}; }
- my $thismsg;
+ my $thismsg;
if ((($env{'form.critmsg'}) || ($env{'form.sendbck'})) &&
- (&Apache::lonnet::allowed('srm',$env{'request.course.id'}))) {
+ (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
+ || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ '/'.$env{'request.course.sec'}))) {
$r->print(&mt('Sending critical message').' '.$recuname.'@'.$recdomain.': ');
$thismsg=&user_crit_msg($recuname,$recdomain,
&Apache::lonfeedback::clear_out_html($env{'form.subject'}),
$msgtxt,
- $env{'form.sendbck'},$env{'form.permanent'});
+ $env{'form.sendbck'},$env{'form.permanent'},\$sentmessage{$_});
} else {
$r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': ');
$thismsg=&user_normal_msg($recuname,$recdomain,
&Apache::lonfeedback::clear_out_html($env{'form.subject'}),
$msgtxt,
- $content{'citation'},undef,undef,$env{'form.permanent'});
- if (($env{'request.course.id'}) && ($env{'form.sendmode'} eq 'group')) {
- &user_normal_msg_raw(
- $env{'course.'.$env{'request.course.id'}.'.num'},
- $env{'course.'.$env{'request.course.id'}.'.domain'},
- 'Broadcast ['.$recuname.':'.$recdomain.']',
- $msgtxt);
- }
+ $content{'citation'},undef,undef,$env{'form.permanent'},\$sentmessage{$_});
+ }
+ if (($env{'request.course.id'}) && (($msgtype eq 'critical') ||
+ ($env{'form.sendmode'} eq 'group'))) {
+ $specialmsg_status{$recuname.':'.$recdomain} = $thismsg;
+ if ($thismsg eq 'ok') {
+ $numspecial ++;
+ }
}
$r->print($thismsg.'
');
$sendstatus.=' '.$thismsg;
}
+ if (($env{'request.course.id'}) && (($env{'form.sendmode'} eq 'group')
+ || ($msgtype eq 'critical'))) {
+ my $subj_prefix;
+ if ($msgtype eq 'critical') {
+ $subj_prefix = 'Critical.';
+ } else {
+ $subj_prefix = 'Broadcast.';
+ }
+ my ($specialmsgid,$specialresult);
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $course_str = &Apache::lonnet::escape('['.$cnum.':'.$cdom.']');
+
+ if ($numspecial) {
+ $specialresult = &user_normal_msg_raw($cnum,$cdom,$subj_prefix.
+ ' '.$course_str,$savemsg,undef,undef,undef,
+ undef,undef,\$specialmsgid);
+ $specialmsgid = &Apache::lonnet::unescape($specialmsgid);
+ }
+ if ($specialresult eq 'ok') {
+ my $record_sent;
+ my @recusers = ();
+ my @recudoms = ();
+ my ($stamp,$msgsubj,$msgname,$msgdom,$msgcount,$context,$pid) =
+ split(/\:/,&Apache::lonnet::unescape($specialmsgid));
+ foreach my $recipient (sort(keys(%toaddr))) {
+ if ($specialmsg_status{$recipient} eq 'ok') {
+ my $usersubj = $subj_prefix.'['.$recipient.']';
+ my $usermsgid = &buildmsgid($stamp,$usersubj,$msgname,
+ $msgdom,$msgcount,$context,$pid);
+ &user_normal_msg_raw($cnum,$cdom,$subj_prefix.
+ ' ['.$recipient.']',$sentmessage{$recipient},
+ undef,undef,undef,undef,$usermsgid);
+ my ($uname,$udom) = split/:/,$recipient;
+ push(@recusers,$uname);
+ push(@recudoms,$udom);
+ }
+ }
+ if (@recusers) {
+ my $specialmessage;
+ my $sentsubj = $subj_prefix.' ('.$numspecial.' sent) '.
+ &Apache::lonfeedback::clear_out_html($env{'form.subject'});
+ $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"');
+ my $sentmsgid = &buildmsgid($stamp,$sentsubj,$msgname,
+ $msgdom,$msgcount,$context,$pid);
+ ($specialmsgid,$specialmessage) =
+ &packagemsg(&Apache::lonfeedback::clear_out_html(
+ $env{'form.subject'}),$savemsg,undef,undef,undef,
+ \@recusers,\@recudoms,$sentmsgid);
+ $record_sent = &store_sent_mail($specialmsgid,$specialmessage);
+ }
+ } else {
+ &Apache::lonnet::logthis('Failed to create record of critical message or broadcast in '.$env{'course.'.$env{'request.course.id'}.'.num'}.' at '.$env{'course.'.$env{'request.course.id'}.'.domain'}.' - no msgid generated');
+ }
+ }
} else {
&printheader($r,'','No messages sent.');
}
@@ -2151,31 +2415,63 @@ sub handler {
&compout($r,$env{'form.forward'},undef,undef,undef,$folder);
} elsif ($env{'form.markdel'}) {
&printheader($r,'','Deleted Message');
- &statuschange($env{'form.markdel'},'deleted',$folder);
+ my ($result,$msg) =
+ &statuschange($env{'form.markdel'},'deleted',$folder);
+ if (!$result) {
+ $r->print('Failed to delete the message.
'.
+ ''.$msg."
\n");
+ }
&Apache::loncommunicate::menu($r);
&disall($r,($folder?$folder:$dismode));
} elsif ($env{'form.markedmove'}) {
- my $total=0;
- foreach (keys %env) {
- if ($_=~/^form\.delmark_(.*)$/) {
- &movemsg(&Apache::lonnet::unescape($1),$folder,
- $env{'form.movetofolder'});
- $total++;
+ my ($total,$failed,@failed_msg)=(0,0);
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.delmark_(.*)$/) {
+ my ($result,$msg) =
+ &movemsg(&Apache::lonnet::unescape($1),$folder,
+ $env{'form.movetofolder'});
+ if ($result) {
+ $total++;
+ } else {
+ $failed++;
+ push(@failed_msg,$msg);
+ }
}
}
&printheader($r,'','Moved Messages');
+ if ($failed) {
+ $r->print('
+ Failed to move '.$failed.' message(s)
');
+ $r->print(''.
+ join("
\n",@failed_msg).
+ "
\n");
+ }
$r->print('Moved '.$total.' message(s)');
&Apache::loncommunicate::menu($r);
&disall($r,($folder?$folder:$dismode));
} elsif ($env{'form.markeddel'}) {
- my $total=0;
- foreach (keys %env) {
- if ($_=~/^form\.delmark_(.*)$/) {
- &statuschange(&Apache::lonnet::unescape($1),'deleted',$folder);
- $total++;
+ my ($total,$failed,@failed_msg)=(0,0);
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.delmark_(.*)$/) {
+ my ($result,$msg) =
+ &statuschange(&Apache::lonnet::unescape($1),'deleted',
+ $folder);
+ if ($result) {
+ $total++;
+ } else {
+ $failed++;
+ push(@failed_msg,$msg);
+ }
}
}
&printheader($r,'','Deleted Messages');
+ if ($failed) {
+ $r->print('
+ Failed to delete '.$failed.' message(s)
');
+ $r->print(''.
+ join("
\n",@failed_msg).
+ "
\n");
+ }
$r->print('Deleted '.$total.' message(s)');
&Apache::loncommunicate::menu($r);
&disall($r,($folder?$folder:$dismode));
@@ -2195,6 +2491,13 @@ sub handler {
if ($env{'form.storebasecomment'}) {
&storecomment($r);
}
+ if (($env{'form.rsspost'}) && ($env{'request.course.id'})) {
+ &Apache::lonrss::addentry($env{'course.'.$env{'request.course.id'}.'.num'},
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ 'Course_Announcements',
+ $env{'form.subject'},
+ $env{'form.message'},'/adm/communicate','public');
+ }
&disall($r,($folder?$folder:$dismode));
} elsif ($env{'form.newfolder'}) {
&printheader($r,'','New Folder');