--- loncom/interface/lonmsgdisplay.pm 2006/06/30 02:06:15 1.35.2.2
+++ loncom/interface/lonmsgdisplay.pm 2007/01/04 16:54:07 1.62
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines for messaging display
#
-# $Id: lonmsgdisplay.pm,v 1.35.2.2 2006/06/30 02:06:15 albertel Exp $
+# $Id: lonmsgdisplay.pm,v 1.62 2007/01/04 16:54:07 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -74,8 +74,8 @@ email program, so they have full access
interface, or other features they may wish to use in response to the
student's query.
-=item * B: LON-CAPA can block display of e-mails that are
-sent to a student during an online exam. A course coordinator or
+=item * B: LON-CAPA can block selected communication
+features for students during an online exam. A course coordinator or
instructor can set an open and close date/time for scheduled online
exams in a course. If a user uses the LON-CAPA internal messaging
system to display e-mails during the scheduled blocking event,
@@ -132,44 +132,189 @@ use LONCAPA;
# Querystring component with sorting type
my $sqs;
my $startdis;
-my $interdis;
# ============================================================ List all folders
sub folderlist {
- my $folder=shift;
- my @allfolders=&Apache::lonnet::getkeys('email_folders');
- if ($allfolders[0]=~/^error:/) { @allfolders=(); }
- return '':'');
+ ''.
+ ($folder=~/^critical/?'':'');
+ return $output;
+}
+
+sub get_permanent_folders {
+ my %permfolders =
+ &Apache::lonlocal::texthash('' => 'INBOX',
+ 'trash' => 'TRASH',
+ 'critical' => 'Critical',
+ 'sent' => 'Sent Messages',
+ );
+ return %permfolders;
+}
+
+sub get_msgstatus_types {
+ my %statushash = &Apache::lonlocal::texthash(
+ '' => 'Any',
+ new => 'Unread',
+ read => 'Read',
+ replied => 'Replied to',
+ forwarded => 'Forwarded',
+ );
+ return %statushash;
}
sub scrollbuttons {
- my ($start,$maxdis,$first,$finish,$total)=@_;
+ my ($start,$maxdis,$first,$finish,$total,$msgstatus)=@_;
unless ($total>0) { return ''; }
$start++; $maxdis++;$first++;$finish++;
+
+ my %statushash = &get_msgstatus_types();
+ my $status;
+ if ($msgstatus eq '') {
+ $status = &mt('All');
+ } else {
+ $status = $statushash{$msgstatus};
+ }
return
- &mt('Page').': '.
+ ''.&mt('Page').': '.
''.
''.
' of '.$maxdis.
''.
' '.
- &mt('Showing messages [_1] through [_2] of [_3]',$first,$finish,$total).'';
+ &mt('[_1] messages: showing messages [_2] through [_3] of [_4].',$status,$first,$finish,$total).'';
}
# =============================================================== Status Change
@@ -195,14 +340,123 @@ sub statuschange {
# ============================================================= Make new folder
sub makefolder {
- my ($newfolder)=@_;
- if (($newfolder eq 'sent')
- || ($newfolder eq 'critical')
- || ($newfolder eq 'trash')
- || ($newfolder eq 'new')) { return; }
- &Apache::lonnet::put('email_folders',{$newfolder => time});
+ my ($newfolder) = @_;
+ my %permfolders = &get_permanent_folders();
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ my ($outcome,$warning);
+ if (defined($userfolders{$newfolder})) {
+ return &mt('The folder name: "[_1]" is already in use for an existing folder.',$newfolder);
+ }
+ foreach my $perm (keys(%permfolders)) {
+ if ($permfolders{$perm} eq $newfolder) {
+ return &mt('The folder name: "[_1]" is already used for one of the folders automatically generated by the system.',$newfolder);
+ }
+ }
+ if (&get_msgfolder_lock() eq 'ok') {
+ my %counter_hash = &Apache::lonnet::get('email_folders',["\0".'idcount']);
+ my $lastcount = $counter_hash{"\0".'idcount'};
+ my $folder_id = $lastcount + 1;
+ while (defined($userfolders{$folder_id})) {
+ $folder_id ++;
+ }
+ my %folderinfo = ( id => $folder_id,
+ created => time, );
+ $outcome =
+ &Apache::lonnet::put('email_folders',{$newfolder => \%folderinfo,
+ "\0".'idcount' => $folder_id});
+ my $releaseresult = &release_msgfolder_lock();
+ if ($releaseresult ne 'ok') {
+ $warning = $releaseresult;
+ }
+ } else {
+ $outcome =
+ &mt('Error - could not obtain lock on email folders record.');
+ }
+ return ($outcome,$warning);
}
+# ============================================================= Delete folder
+
+sub deletefolder {
+ my ($folder)=@_;
+ my %permfolders = &get_permanent_folders();
+ if (defined($permfolders{$folder})) {
+ return &mt('The folder "[_1]" may not be deleted',$folder);
+ }
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ if (!defined($userfolders{$folder})) {
+ return &mt('The folder "[_1]" does not exist so deletion is not required.',
+ $folder);
+ }
+ # check folder is empty;
+ my $suffix=&Apache::lonmsg::foldersuffix($folder);
+ my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
+ if (@messages > 0) {
+ return &mt('The folder "[_1]" contains messages so it may not be deleted.',$folder).
+ ' '.
+ &mt('Delete or move the messages to a different folder first.');
+ }
+ my $delresult = &Apache::lonnet::del('email_folders',[$folder]);
+ return $delresult;
+}
+
+sub renamefolder {
+ my ($folder) = @_;
+ my $newname = $env{'form.renamed'};
+ my %permfolders = &get_permanent_folders();
+ if ($env{'form.renamed'} eq '') {
+ return &mt('The folder "[_1]" may not be renamed to "[_2]" as the new name you requested is an invalid name.',$folder,$newname);
+ }
+ if (defined($permfolders{$newname})) {
+ return &mt('The folder "[_1]" may not be renamed to "[_2]" as the new name you requested is reserved for folders provided automatically by the system.',$folder,$newname);
+ }
+ my %userfolders = &Apache::lonmsg::get_user_folders();
+ if (defined($userfolders{$newname})) {
+ return &mt('The folder "[_1]" may not be renamed to "[_2]" because the new name you requested is already being used for an existing folder.',$folder,$newname);
+ }
+ if (!defined($userfolders{$folder})) {
+ return &mt('The folder "[_1]" could not be renamed to "[_2]" because the folder does not exist.',$folder,$newname);
+ }
+ my %folderinfo;
+ if (ref($userfolders{$folder}) eq 'HASH') {
+ %folderinfo = %{$userfolders{$folder}};
+ } else {
+ %folderinfo = ( id => $folder,
+ created => $userfolders{$folder},);
+ }
+ my $outcome =
+ &Apache::lonnet::put('email_folders',{$newname => \%folderinfo});
+ if ($outcome eq 'ok') {
+ $outcome = &Apache::lonnet::del('email_folders',[$folder]);
+ }
+ return $outcome;
+}
+
+sub get_msgfolder_lock {
+ # get lock for mail folder counter.
+ my $lockhash = { "\0".'lock_counter' => time, };
+ my $tries = 0;
+ my $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
+ while (($gotlock ne 'ok') && $tries <3) {
+ $tries ++;
+ sleep(1);
+ $gotlock = &Apache::lonnet::newput('email_folders',$lockhash);
+ }
+ return $gotlock;
+}
+
+sub release_msgfolder_lock {
+ # remove lock
+ my @del_lock = ("\0".'lock_counter');
+ my $dellockoutcome=&Apache::lonnet::del('email_folders',\@del_lock);
+ if ($dellockoutcome ne 'ok') {
+ return (' '.&mt('Warning: failed to release lock for counter').' ');
+ } else {
+ return 'ok';
+ }
+}
+
+
# ======================================================== Move between folders
sub movemsg {
@@ -270,12 +524,14 @@ sub discourse {
&Apache::lonselstudent::get_people_in_class($env{'request.course.sec'});
unshift @$current_members, (@$course_personnel);
my %defaultUsers;
+
+ $result .= ''."\n";
- $result = &Apache::lonselstudent::render_student_list($current_members,
- "compemail",
- "current",
- \%defaultUsers,
- 1,"selectedusers",1);
+ $result .= &Apache::lonselstudent::render_student_list($current_members,
+ "compemail",
+ "current",
+ \%defaultUsers,
+ 1,"selectedusers",1);
$result .= &Apache::lonselstudent::render_student_list($expired_members,
"compemail",
@@ -290,6 +546,191 @@ sub discourse {
return $result;
}
+sub disgroup {
+ my ($cdom,$cnum,$group,$viewgrps,$editgrps) = @_;
+ my $result;
+ # Needs to be in a course
+ if (!($env{'request.course.fn'})) {
+ $result = &mt('Error: you must have a course role selected to be able to send a broadcast message to a group in the course.');
+ return $result;
+ }
+ if ($cdom eq '' || $cnum eq '') {
+ $result = &mt('Error: could not determine domain or number of course');
+ return $result;
+ }
+ my ($memberinfo,$numitems) =
+ &Apache::longroup::group_memberlist($cdom,$cnum,$group,{},[]);
+ my @statustypes = ('active');
+ if ($viewgrps || $editgrps) {
+ push(@statustypes,('future','previous'));
+ }
+ if (keys(%{$memberinfo}) == 0) {
+ $result = &mt('As this group has no members, there are no '.
+ 'recipients to select.');
+ return $result;
+ } else {
+ $result = &mt('Select message recipients from the group members listed below. ');
+ my %Sortby = (
+ active => {},
+ previous => {},
+ future => {},
+ );
+ my %lt = &Apache::lonlocal::texthash(
+ 'name' => 'Name',
+ 'usnm' => 'Username',
+ 'doma' => 'Domain',
+ 'active' => 'Active Members',
+ 'previous' => 'Former Members',
+ 'future' => 'Future Members',
+ );
+ foreach my $user (sort(keys(%{$memberinfo}))) {
+ my $status = $$memberinfo{$user}{status};
+ if ($env{'form.'.$status.'.sortby'} eq 'fullname') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
+ } elsif ($env{'form.'.$status.'.sortby'} eq 'username') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{uname}}},$user);
+ } elsif ($env{'form.'.$status.'.sortby'} eq 'domain') {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{udom}}},$user);
+ } else {
+ push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user);
+ }
+ }
+ $result .= &group_check_uncheck();
+ $result .= '
'.
+ '
';
+ foreach my $status (@statustypes) {
+ if (ref($numitems) eq 'HASH') {
+ if ((defined($$numitems{$status})) && ($$numitems{$status})) {
+ $result.='
';
+ }
+ return $result;
+}
+
+sub group_check_uncheck {
+ my $output = qq|
+
+ |;
+}
+
+sub groupmail_header {
+ my ($action,$group,$cdom,$cnum) = @_;
+ my ($description,$refarg);
+ if (!$cdom || !$cnum) {
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ }
+ if (exists($env{'form.ref'})) {
+ $refarg = 'ref='.$env{'form.ref'};
+ }
+ if (!$group) {
+ $group = $env{'form.group'};
+ }
+ if ($group eq '') {
+ return '';
+ } else {
+ my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$group);
+ if (defined($curr_groups{$group})) {
+ my %groupinfo =
+ &Apache::longroup::get_group_settings($curr_groups{$group});
+ $description = &unescape($groupinfo{'description'});
+ }
+ }
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ if ($refarg) {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/coursegroups",
+ text=>"Groups",
+ title=>"View course groups"});
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg",
+ text=>"Group: $description",
+ title=>"Go to group's home page"},
+ {href=>"/adm/email?compose=group&group=".
+ "$env{'form.group'}&$refarg",
+ text=>"Send a Message in a Group",
+ title=>"Compose Group Email Message"},);
+ if ($action eq 'sending') {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({text=>"Messages being sent.",
+ title=>"Messages sent"},);
+ }
+ my $groupheader = &Apache::loncommon::start_page('Group Email');
+ $groupheader .= &Apache::lonhtmlcommon::breadcrumbs
+ ('Group - '.$env{'form.group'}.' Email');
+ return $groupheader;
+}
+
+sub groupmail_sent {
+ my ($group,$cdom,$cnum) = @_;
+ my $refarg;
+ if (exists($env{'form.ref'})) {
+ $refarg = 'ref='.$env{'form.ref'};
+ }
+ my $output .= '
'.
+ &mt('Send another group email').''.' '.
+ ''. &mt('Return to group page').'';
+ return $output;
+}
+
# ==================================================== Display Critical Message
sub discrit {
@@ -299,8 +740,8 @@ sub discrit {
'';
my %what=&Apache::lonnet::dump('critical');
my $result = '';
- foreach (sort keys %what) {
- my %content=&Apache::lonmsg::unpackagemsg($what{$_});
+ foreach my $key (sort(keys(%what))) {
+ my %content=&Apache::lonmsg::unpackagemsg($what{$key});
next if ($content{'senderdomain'} eq '');
$result.=''.&mt('From').': '.
&Apache::loncommon::aboutmewrapper(
@@ -313,14 +754,14 @@ $content{'sendername'}.':'.
''.
&mt('You have to confirm that you received this message. After confirmation, this message will be moved to your regular inbox').
' '.
- ''.
- ''.
+ '';
}
# Check to see if there were any messages.
if ($result eq '') {
$result = "
".&mt('You have no critical messages.')."
".
- ''.&mt('Select a course or group').' '.
+ ''.&mt('Select a course').' '.
''.&mt('Communicate').'';
} else {
$r->print($header);
@@ -330,7 +771,7 @@ $content{'sendername'}.':'.
}
sub sortedmessages {
- my ($blocked,$startblock,$endblock,$numblocked,$folder) = @_;
+ my ($blocked,$startblock,$endblock,$numblocked,$folder,$msgstatus) = @_;
my $suffix=&Apache::lonmsg::foldersuffix($folder);
my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
#unpack the varibles and repack into temp for sorting
@@ -347,9 +788,10 @@ sub sortedmessages {
foreach my $msgid (@messages) {
my $esc_msgid=&escape($msgid);
- my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)=
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid,$processid,$symb,$error) =
&Apache::lonmsg::unpackmsgid($esc_msgid,$folder,undef,
\%status_cache);
+ next if ($msgstatus ne '' && $msgstatus ne $status);
my $description = &get_course_desc($fromcid,\%descriptions);
my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
$esc_msgid,$description);
@@ -436,7 +878,7 @@ sub get_course_desc {
if (defined($env{'course.'.$fromcid.'.description'})) {
$description = $env{'course.'.$fromcid.'.description'};
} else {
- my %courseinfo=&Apache::lonnet::coursedescription($fromcid); $description = $courseinfo{'description'};
+ my %courseinfo=&Apache::lonnet::coursedescription($fromcid);
$description = $courseinfo{'description'};
}
$$descriptions{$fromcid} = $description;
@@ -445,158 +887,117 @@ sub get_course_desc {
}
}
-# ======================================================== Display new messages
-
-
-sub disnew {
- my $r=shift;
- my %lt=&Apache::lonlocal::texthash(
- 'nm' => 'New Messages',
- 'su' => 'Subject',
- 'co' => 'Course',
- 'da' => 'Date',
- 'us' => 'Username',
- 'op' => 'Open',
- 'do' => 'Domain'
- );
- my @msgids = sort(&Apache::lonnet::getkeys('nohist_email'));
- my @newmsgs;
- my %setters = ();
- my $startblock = 0;
- my $endblock = 0;
- my %blocked = ();
- 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=&escape($_);
- my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
- &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') {
- if ($numsendtime >= $startblock && ($numsendtime <= $endblock && $endblock > 0) ) {
- $blocked{$_} = 'ON';
- $numblocked ++;
- } else {
- push @newmsgs, {
- msgid => $msgid,
- sendtime => $sendtime,
- shortsub => $shortsubj,
- from => $fromname,
- fromdom => $fromdom,
- course => $description
- }
- }
- }
- }
- }
- if ($#newmsgs >= 0) {
- $r->print(<$lt{'nm'}
-
 
-
$lt{'da'}
$lt{'us'}
$lt{'do'}
$lt{'su'}
$lt{'co'}
-TABLEHEAD
- foreach my $msg (@newmsgs) {
- $r->print(<<"ENDLINK");
-
");
- $r->print(&mt('These').' '.$numblocked.' '.&mt('messages are not viewable because '));
- }
- $r->print(
-&mt('display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams').'.');
- &build_block_table($r,$startblock,$endblock,\%setters);
- }
-}
-
-
# ======================================================== Display all messages
sub disall {
- my ($r,$folder)=@_;
- $r->print(&folderlist($folder));
- if ($folder eq 'new') {
- &disnew($r);
- } elsif ($folder eq 'critical') {
+ my ($r,$folder,$msgstatus)=@_;
+ my %saveable = ('folder' => 'scalar',
+ 'msgstatus' => 'scalar',
+ 'sortedby' => 'scalar',
+ 'interdis' => 'scalar',
+ );
+ &Apache::loncommon::store_settings('user','mail',\%saveable);
+ &Apache::loncommon::restore_settings('user','mail',\%saveable);
+ $folder ||= $env{'form.folder'};
+ $msgstatus ||= $env{'form.msgstatus'};
+ $env{'form.interdis'} ||= 20;
+
+ $r->print(&folderlist($folder,$msgstatus));
+ if ($folder eq 'critical') {
&discrit($r);
} else {
- &disfolder($r,$folder);
+ &disfolder($r,$folder,$msgstatus);
}
}
# ============================================================ Display a folder
sub disfolder {
- my ($r,$folder)=@_;
+ my ($r,$folder,$msgstatus)=@_;
+ my %statushash = &get_msgstatus_types();
my %blocked = ();
my %setters = ();
- my $startblock;
- my $endblock;
my $numblocked = 0;
- &blockcheck(\%setters,\$startblock,\$endblock);
+ my ($startblock,$endblock) = &Apache::loncommon::blockcheck(\%setters,'com');
+ my %lt = &Apache::lonlocal::texthash(
+ sede => 'Select a destination folder to which the messages will be moved.',
+ nome => 'No messages have been selected to apply ths action to.',
+ chec => 'Check the checkbox for at least one message.',
+ );
$r->print(<
function checkall() {
- for (i=0; i
ENDDISHEADER
+
my $fsqs='&folder='.$folder;
- my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
+ my @temp=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder,$msgstatus);
my $totalnumber=$#temp+1;
- unless ($totalnumber>0) {
- $r->print('
'.&mt('Empty Folder').'
');
+ if ($totalnumber < 1) {
+ if ($msgstatus eq '') {
+ $r->print('
'.&mt('You have not replied to any messages in this folder.').'
');
+ } else {
+ $r->print('
'.&mt('There are no '.lc($statushash{$msgstatus}).' messages in this folder.').'
');
+ }
return;
}
- unless ($interdis) {
- $interdis=20;
- }
+ my $interdis = $env{'form.interdis'};
my $number=int($totalnumber/$interdis);
+ if ($totalnumber%$interdis == 0) {
+ $number--;
+ }
+
if (($startdis<0) || ($startdis>$number)) { $startdis=$number; }
my $firstdis=$interdis*$startdis;
if ($firstdis>$#temp) { $firstdis=$#temp-$interdis+1; }
my $lastdis=$firstdis+$interdis-1;
if ($lastdis>$#temp) { $lastdis=$#temp; }
- $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber));
+ $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber,$msgstatus));
$r->print('');
+ $r->print('');
if ($numblocked > 0) {
my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
$r->print('
'.
- $numblocked.' '.&mt('message(s) is/are not viewable because display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams.'));
- &build_block_table($r,$startblock,$endblock,\%setters);
+ &mt('[quant,_1,message is, messages are] not viewable because display of LON-CAPA messages sent to you by other students between [_2] and [_3] is currently being blocked because of online exams.',$numblocked,$beginblock,$finishblock));
+ $r->print(&Apache::loncommon::build_block_table($startblock,$endblock,
+ \%setters));
}
}
# ============================================================== Compose output
sub compout {
- my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_;
+ my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode,
+ $multiforward)=@_;
my $suffix=&Apache::lonmsg::foldersuffix($folder);
-
- if ($broadcast eq 'individual') {
+ my ($cdom,$cnum,$group,$refarg);
+ if (exists($env{'form.group'})) {
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ $group = $env{'form.group'};
+ my $action = 'composing';
+ $r->print(&groupmail_header($action,$group,$cdom,$cnum));
+ } elsif ($broadcast eq 'individual') {
&printheader($r,'/adm/email?compose=individual',
'Send a Message');
} elsif ($broadcast) {
@@ -731,6 +1181,13 @@ sub compout {
} elsif ($replycrit) {
$r->print('
'.&mt('Replying to a Critical Message').'
');
$replying=$replycrit;
+ } elsif ($multiforward) {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>"/adm/email?folder=".&escape($folder),
+ text=>"Display All Messages"});
+ &printheader($r,'/adm/email?compose=multiforward',
+ 'Forwarding Multiple Messages');
+ $r->print(&mt('Each of the [quant,_1,message] you checked will be forwarded to the recipient(s) you select below.',$multiforward).' ');
} else {
&printheader($r,'/adm/email?compose=upload',
'Distribute from Uploaded File');
@@ -741,13 +1198,18 @@ sub compout {
my $dismsg='';
my $disbase='';
my $func=&mt('Send New');
- my %lt=&Apache::lonlocal::texthash('us' => 'Username',
- 'do' => 'Domain',
- 'ad' => 'Additional Recipients',
- 'sb' => 'Subject',
- 'ca' => 'Cancel',
- 'ma' => 'Mail');
-
+ my %lt=&Apache::lonlocal::texthash('us' => 'Username',
+ 'do' => 'Domain',
+ 'ad' => 'Additional Recipients',
+ 'sb' => 'Subject',
+ 'ca' => 'Cancel',
+ 'ma' => 'Mail',
+ 'msg' => 'Messages',
+ 'gen' => 'Generate messages from a file',
+ 'gmt' => 'General message text',
+ 'tff' => 'The file format for the uploaded portion of the message is',
+ 'uas' => 'Upload and Send',
+ );
if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
|| &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
@@ -802,15 +1264,34 @@ sub compout {
}
}
my $citation=&displayresource(%content);
+ my ($can_grp_broadcast,$viewgrps,$editgrps);
if ($env{'form.recdom'}) { $defdom=$env{'form.recdom'}; }
if ($env{'form.text'}) { $dismsg=$env{'form.text'}; }
if ($env{'form.subject'}) { $dissub=$env{'form.subject'}; }
$r->print(
'
-The messages will be assembled from all lines with the respective
-username\@domain, and appended to the general message text.
+'.&mt('The messages will be assembled from all lines with the respective'."\n".'username:domain, and appended to the general message text.'));
+ $r->print(<
$dispcrit
-
+
ENDUPLOAD
}
if ($broadcast eq 'group') {
- &discourse($r);
- my $studentsel = &discourse();
- $r->print($studentsel);
+ if ($group eq '') {
+ my $studentsel = &discourse();
+ $r->print($studentsel);
+ }
}
if ($env{'form.displayedcrit'}) {
$r->print('');
@@ -893,12 +1404,55 @@ ENDUPLOAD
# ---------------------------------------------------- Display all face to face
+sub recipient_input_row {
+ my ($dom,%lt) = @_;
+ my $domform = &Apache::loncommon::select_dom_form($dom,'recdomain');
+ my $selectlink=
+ &Apache::loncommon::selectstudent_link('compemail','recuname',
+ 'recdomain');
+ my $output = <<"ENDREC";
+
$lt{'us'}:
$selectlink
+
$lt{'do'}:
+
$domform
+ENDREC
+ return $output;
+}
+
+sub additional_rec_row {
+ my ($lt) = @_;
+ my $output = <<"ENDADD";
+
';
+ return $output;
+}
+
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'})
- && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ if (! &Apache::lonnet::allowed('dff',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
return;
}
@@ -907,8 +1461,8 @@ sub retrieve_instructor_comments {
$env{'course.'.$env{'request.course.id'}.'.num'},
'%255b'.$user.'%253a'.$domain.'%255d');
my $result='';
- foreach (sort(keys(%records))) {
- my %content=&Apache::lonmsg::unpackagemsg($records{$_});
+ foreach my $key (sort(keys(%records))) {
+ my %content=&Apache::lonmsg::unpackagemsg($records{$key});
next if ($content{'senderdomain'} eq '');
next if ($content{'subject'} !~ /^Record/);
# &Apache::lonfeedback::newline_to_br(\$content{'message'});
@@ -924,10 +1478,10 @@ sub disfacetoface {
my ($r,$user,$domain)=@_;
my $target=$env{'form.grade_target'};
unless ($env{'request.course.id'}) { return; }
- if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
- && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ if (!&Apache::lonnet::allowed('dff',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
- $r->print('Not allowed');
+ $r->print(&mt('Not allowed'));
return;
}
my %records=&Apache::lonnet::dump('nohist_email',
@@ -935,8 +1489,8 @@ sub disfacetoface {
$env{'course.'.$env{'request.course.id'}.'.num'},
'%255b'.$user.'%253a'.$domain.'%255d');
my $result='';
- foreach (sort keys %records) {
- my %content=&Apache::lonmsg::unpackagemsg($records{$_});
+ foreach my $key (sort(keys(%records))) {
+ my %content=&Apache::lonmsg::unpackagemsg($records{$key});
next if ($content{'senderdomain'} eq '');
&Apache::lonfeedback::newline_to_br(\$content{'message'});
if ($content{'subject'}=~/^Record/) {
@@ -1006,10 +1560,10 @@ sub general_message {
sub facetoface {
my ($r,$stage)=@_;
- if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
- && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ if (!&Apache::lonnet::allowed('dff',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('dff',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
- $r->print('Not allowed');
+ $r->print(&mt('Not allowed'));
return;
}
my $crstype = &Apache::loncommon::course_type();
@@ -1083,8 +1637,8 @@ ENDBFORM
sub examblock {
my ($r,$action) = @_;
unless ($env{'request.course.id'}) { return;}
- if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
- && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
+ if (!&Apache::lonnet::allowed('dcm',$env{'request.course.id'})
+ && ! &Apache::lonnet::allowed('dcm',$env{'request.course.id'}.
'/'.$env{'request.course.sec'})) {
$r->print('Not allowed');
return;
@@ -1096,13 +1650,15 @@ sub examblock {
'cbds' => 'Communication blocking during scheduled exams',
'desc' => "You can use communication blocking to prevent $usertype enrolled in this course from displaying LON-CAPA messages sent by other $usertype during an online exam. As blocking of communication could potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA course, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.",
'mecb' => 'Modify existing communication blocking periods',
- 'ncbc' => 'No communication blocks currently stored'
+ 'ncbc' => 'No communication blocks currently stored',
+ 'stor' => 'Store',
);
my %ltext = &Apache::lonlocal::texthash(
'dura' => 'Duration',
'setb' => 'Set by',
'even' => 'Event',
+ 'blck' => 'Blocked?',
'actn' => 'Action',
'star' => 'Start',
'endd' => 'End'
@@ -1134,7 +1690,7 @@ sub examblock {
$r->print(<<"END");
-
+
$end_page
END
@@ -1145,10 +1701,6 @@ sub blockstore {
my $r = shift;
my %lt=&Apache::lonlocal::texthash(
'tfcm' => 'The following changes were made',
- 'cbps' => 'communication blocking period(s)',
- 'werm' => 'was/were removed',
- 'wemo' => 'was/were modified',
- 'wead' => 'was/were added',
'ncwm' => 'No changes were made.'
);
my %adds = ();
@@ -1159,35 +1711,40 @@ sub blockstore {
my $addtotal = 0;
my %blocking = ();
$r->print('
-END
- foreach my $course (keys(%{$setters})) {
- my %courseinfo=&Apache::lonnet::coursedescription($course);
- for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) {
- my ($uname,$udom) = @{$$setters{$course}{staff}[$i]};
- my $fullname = &Apache::loncommon::plainname($uname,$udom);
- my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]};
- $openblock = &Apache::lonlocal::locallocaltime($openblock);
- $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
- $r->print(&Apache::loncommon::start_data_table_row().
- '
'.$courseinfo{'description'}.'
'.
- '
'.$openblock.' to '.$closeblock.'
'.
- '
'.$fullname.' ('.$uname.':'.$udom.
- ')
'.
- &Apache::loncommon::end_data_table_row());
- }
- }
- $r->print(&Apache::loncommon::end_data_table());
+ my $typeorder = ['com','chat','boards','port','groups','blogs'];
+ return ($typeorder,\%types);
}
# ----------------------------------------------------------- Display a message
sub displaymessage {
- my ($r,$msgid,$folder)=@_;
+ my ($r,$msgid,$folder,$msgstatus)=@_;
my $suffix=&Apache::lonmsg::foldersuffix($folder);
my %blocked = ();
my %setters = ();
- my $startblock = 0;
- my $endblock = 0;
my $numblocked = 0;
my $crstype = &Apache::loncommon::course_type();
# info to generate "next" and "previous" buttons and check if message is blocked
- &blockcheck(\%setters,\$startblock,\$endblock);
- my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
+ my ($startblock,$endblock) = &Apache::loncommon::blockcheck(\%setters,'com');
+ my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder,$msgstatus);
if ( $blocked{$msgid} eq 'ON' ) {
&printheader($r,'/adm/email',&mt('Display a Message'));
$r->print(&mt('You attempted to display a message that is currently blocked because you are enrolled in one or more courses for which there is an ongoing online exam.'));
&build_block_table($r,$startblock,$endblock,\%setters);
return;
}
- &statuschange($msgid,'read',$folder);
+ if ($msgstatus eq '') {
+ &statuschange($msgid,'read',$folder);
+ }
my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
my %content=&Apache::lonmsg::unpackagemsg($message{$msgid});
@@ -1466,7 +1980,6 @@ sub displaymessage {
'
');
&Apache::loncommunicate::menu($r);
- &disall($r,($folder?$folder:$dismode));
+ &disall($r,($folder?$folder:$dismode),$msgstatus);
} elsif ($env{'form.markunread'}) {
&printheader($r,'','Marked Message as Unread');
&statuschange($env{'form.markunread'},'new');
&Apache::loncommunicate::menu($r);
- &disall($r,($folder?$folder:$dismode));
+ &disall($r,($folder?$folder:$dismode),$msgstatus);
} elsif ($env{'form.compose'}) {
&compout($r,'','',$env{'form.compose'});
} elsif ($env{'form.recordftf'}) {
@@ -1998,31 +2628,119 @@ sub handler {
} elsif ($env{'form.block'}) {
&examblock($r,$env{'form.block'});
} elsif ($env{'form.sendmail'}) {
- &sendoffmail($r,$folder);
+ if ($env{'form.multiforward'}) {
+ &printheader($r,'','Messages being sent.');
+ my $fixed_subj = $env{'form.subject'};
+ my $suffix=&Apache::lonmsg::foldersuffix($folder);
+ my (%sendresult,%forwardok,%forwardfail,$fwdcount);
+ my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark');
+ foreach my $item (@to_forward) {
+ my $msgid=&unescape($item);
+ my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
+ my %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1);
+ if ($env{'form.showorigsubj'}) {
+ $env{'form.subject'} = $fixed_subj.$content{'subject'};
+ } else {
+ $env{'form.subject'} = '';
+ }
+ my $uname = $content{'sendername'};
+ my $udom = $content{'senderdomain'};
+ &statuschange($msgid,'forwarded',$folder);
+ if ($env{'form.showorigsender'}) {
+ $env{'form.message'} = $env{'form.msgheader'}.' '.
+ &Apache::loncommon::plainname($uname,$udom).' ('.
+ $uname.':'.$udom.')';
+ }
+ $env{'form.message'} .= "\n\n-- Forwarded message --\n\n".
+ $content{'message'};
+ $fwdcount ++;
+ $r->print($fwdcount.': ');
+ $sendresult{$msgid} = &sendoffmail($r,$folder);
+ $r->print(' ');
+ }
+ foreach my $key (keys(%sendresult)) {
+ if ($sendresult{$key} =~/^(\s*(?:ok|con_delayed)\s*)*$/) {
+ $forwardok{$key} = $sendresult{$key};
+ } else {
+ $forwardfail{$key} = $sendresult{$key};
+ }
+ }
+ if (keys(%forwardok) > 0) {
+ my $count = keys(%forwardok);
+ $r->print(' '.
+ &mt('[quant,_1,message] forwarded.',$count).
+ '');
+ }
+ if (keys(%forwardfail) > 0) {
+ my $count = keys(%forwardfail);
+ $r->print('
'.
+ &mt('Could not forward [quant,_1,message].',$count).
+ ' ');
+ foreach my $key (keys(%forwardfail)) {
+ $r->print(&mt('Could not deliver forwarded message.').' '.
+ &mt('The recipient addresses may need to be corrected').' ('.$forwardfail{$key}.').