--- loncom/interface/lonmsgdisplay.pm 2006/11/23 16:40:17 1.42 +++ loncom/interface/lonmsgdisplay.pm 2006/12/23 18:27:28 1.58 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging display # -# $Id: lonmsgdisplay.pm,v 1.42 2006/11/23 16:40:17 raeburn Exp $ +# $Id: lonmsgdisplay.pm,v 1.58 2006/12/23 18:27:28 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 '
'. - &mt('Folder').': '. - &Apache::loncommon::select_form($folder,'folder', - ('' => &mt('INBOX'),'trash' => &mt('TRASH'), - 'new' => &mt('New Messages Only'), - 'critical' => &mt('Critical'), - 'sent' => &mt('Sent Messages'), - map { $_ => $_ } @allfolders)). - ' '.&mt('Show'). - ''. - '
'. + my ($folder,$msgstatus) = @_; + my %lt = &Apache::lonlocal::texthash( + actn => 'Action', + fold => 'Folder', + show => 'Show', + status => 'Message Status', + go => 'Go', + nnff => 'New Name for Folder', + newn => 'New Name', + thfm => 'The folder may not be renamed', + fmnb => 'folder may not be renamed as it is a folder provided by the system.', + asth => 'as this name is already in use for a system-provided or user-defined folder.', + the => 'The', + tnfm => 'The new folder may not be named', + + ); + + my %actions = &Apache::lonlocal::texthash( + view => 'View Folder', + rename => 'Rename Folder', + delete => 'Delete Folder', + ); + $actions{'select_form_order'} = ['view','rename','delete']; + + my %statushash = &get_msgstatus_types(); + + $statushash{'select_form_order'} = ['','new','read','replied','forwarded']; + + my %permfolders = &get_permanent_folders(); + my $permlist = join("','",sort(keys(%permfolders))); + my ($permlistkeys,$permlistvals); + foreach my $key (sort(keys(%permfolders))) { + $permlistvals .= $permfolders{$key}."','"; + $permlistkeys .= $key."','"; + } + $permlistvals =~ s/','$//; + $permlistkeys =~ s/','$//; + my %gotfolders = &Apache::lonmsg::get_user_folders(); + my %userfolders; + + foreach my $key (keys(%gotfolders)) { + $key =~ s/(['"])/\$1/g; #' stupid emacs + $userfolders{$key} = $key; + } + my @userorder = sort(keys(%userfolders)); + my %formhash = (%permfolders,%userfolders); + my $folderlist = join("','",@userorder); + $folderlist .= "','".$permlistvals; + + $formhash{'select_form_order'} = ['','critical',@userorder,'sent','trash']; + my $output = qq||; + my %show = ('select_form_order' => [10,20,50,100,200], + map {$_=>$_} (10,20,50,100,200)); + + + $output .= ' + + + + + + +
+ + + + + + + +
'.$lt{'fold'}.'
'."\n". + &Apache::loncommon::select_form($folder,'folder',%formhash).' +
'.$lt{'show'}.'
'."\n". + &Apache::loncommon::select_form($env{'form.interdis'},'interdis', + %show).' +
'.$lt{'status'}.'
'."\n". + &Apache::loncommon::select_form($msgstatus,'msgstatus',%statushash).' +
'.$lt{'actn'}.'
'. + &Apache::loncommon::select_form('view','folderaction',%actions).' +

'. + ' +
+
     + '. + '

+
'.&mt('New Folder').'
'. + ' +
+
'."\n". ''. - ($folder=~/^(new|critical)/?'
':''); + ''. + ($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 { @@ -350,10 +604,10 @@ sub disgroup { $result.=''. '
'.$lt{$status}. ''. - ''. '  '. - ''. '

'. &Apache::loncommon::start_data_table(). @@ -517,9 +771,10 @@ $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 my @temp; my %descriptions; @@ -537,6 +792,7 @@ sub sortedmessages { my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)= &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); @@ -623,7 +879,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; @@ -632,158 +888,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/Group', - '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 my $id (@msgids) { - my $msgid=&escape($id); - 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{$id} = 'ON'; - $numblocked ++; - } else { - push @newmsgs, { - msgid => $msgid, - sendtime => $sendtime, - shortsub => $shortsubj, - from => $fromname, - fromdom => $fromdom, - course => $description - } - } - } - } - } - if ($#newmsgs >= 0) { - $r->print(<$lt{'nm'} - - -TABLEHEAD - foreach my $msg (@newmsgs) { - $r->print(<<"ENDLINK"); - - -ENDLINK - foreach my $item ('sendtime','from','fromdom','shortsub','course') { - $r->print(""); - } - $r->print(""); - } - $r->print('
 $lt{'da'}$lt{'us'}$lt{'do'}$lt{'su'}$lt{'co'}
$lt{'op'}$msg->{$item}
'); - } elsif ($numblocked == 0) { - $r->print("

".&mt('You have no unread messages')."

"); - } - if ($numblocked > 0) { - my $beginblock = &Apache::lonlocal::locallocaltime($startblock); - my $finishblock = &Apache::lonlocal::locallocaltime($endblock); - if ($numblocked == 1) { - $r->print("

".&mt('You have').' '.$numblocked.' '.&mt('blocked unread message').".

"); - $r->print(&mt('This message is not viewable because').' '); - } else { - $r->print("

".&mt('You have').' '.$numblocked.' '.&mt('blocked unread messages').".

"); - $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('Empty Folder').'

'); + } elsif ($msgstatus eq 'replied') { + $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('
'. - '
 '); + ''); } else { @@ -809,9 +1024,9 @@ ENDDISHEADER } $r->print(''. - ''."\n"); + my $localsenttime = &Apache::lonlocal::locallocaltime($sendtime); + my $count = $n +1; + $r->print(''); + foreach my $item ($localsenttime,$dis_name,$dis_domain,$shortsubj) { + $r->print(''); + } + my $showstatus; + my %statushash = &get_msgstatus_types(); + if ($status eq '') { + $showstatus = ''; + } else { + $showstatus = $statushash{$status}; + } + $r->print(''."\n"); } elsif ($status eq 'deleted') { # purge my ($result,$msg) = @@ -865,36 +1094,65 @@ ENDDISHEADER } } - $r->print("
 '); if ($env{'form.sortedby'} eq "revdate") { $r->print(''.&mt('Date').''); if ($env{'form.sortedby'} eq "revcourse") { - $r->print(''.&mt('Course/Group').''); + $r->print(''.&mt('Course').''); } else { - $r->print(''.&mt('Course/Group').''); + $r->print(''.&mt('Course').''); } $r->print(''); if ($env{'form.sortedby'} eq "revstatus") { @@ -850,14 +1065,28 @@ ENDDISHEADER $dis_domain = join('
',@{$content{'recdomain'}}); } } - $r->print('
'.&mt('Open').''. - ($folder ne 'trash'?''.&mt('Delete'):' ').''.&Apache::lonlocal::locallocaltime($sendtime).''. - $dis_name.''.$dis_domain.''. - $shortsubj.''. - $description.''.$status.'
'.(($status eq 'new')?'':''). + $count.'.'.(($status eq 'new')?'':'').' '. + ''.(($status eq 'new')?'':''). + ''. + $item.(($status eq 'new')?'':'').''.(($status eq 'new')?'':'').$description. + (($status eq 'new')?'':'').''. + (($status eq 'new')?'':'').$showstatus. + (($status eq 'new')?'':'').'
\n

". - ''.&mt('Check All').' '. - ''.&mt('Uncheck All').'

'. - ''); + $r->print("
\n"); + $r->print(' + + '."\n". + ''."\n"); + + if (keys(%gotfolders) > 0) { + $r->print(''); + } + $r->print(''."\n". + '
'. + '
'."\n". + ''."\n". + '
 '.&mt('Action').'
'."\n". + '

'); + $r->print(' '."\n"); } - $r->print('

'); - my @allfolders=&Apache::lonnet::getkeys('email_folders'); - if ($allfolders[0]=~/^error:/) { @allfolders=(); } - $r->print( - &Apache::loncommon::select_form('','movetofolder', - ( map { $_ => $_ } @allfolders)) - ); + if ($msgstatus ne 'read') { + $r->print(' ."\n"'); + } + if ($msgstatus ne 'unread') { + $r->print(' '."\n"); + } + $r->print(' '."\n"); + + my %gotfolders = &Apache::lonmsg::get_user_folders(); + if (keys(%gotfolders) > 0) { + $r->print(' '); + } + $r->print("\n".'

'.&mt('Destination folder').'
'); + my %userfolders; + foreach my $key (keys(%gotfolders)) { + $userfolders{$key} = $key; + } + $userfolders{''} = ""; + $r->print(&Apache::loncommon::select_form('','movetofolder',%userfolders). + '
   '. + '
'); my $postedstartdis=$startdis+1; - $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); my ($cdom,$cnum,$group,$refarg); if (exists($env{'form.group'})) { @@ -924,6 +1182,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'); @@ -934,13 +1199,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'})) { @@ -1037,24 +1307,49 @@ sub compout { } } my $latexHelp = Apache::loncommon::helpLatexCheatsheet(); - if ($broadcast ne 'upload') { - $r->print(<<"ENDCOMP"); -$lt{'ad'}
username\@domain,username\@domain, ... - - -$lt{'sb'}: - + my $subj_size; + if ($multiforward) { + $r->print(&additional_rec_row(\%lt)); + $r->print(''. + &mt('Unless you choose otherwise:').'
  • '. + &mt("The subject in each forwarded message will be 'Forwarding:' followed by the original subject.").'
  • '. + &mt("The message itself will begin with a first line: 'Forwarded message from' followed by the original sender's name.").'
'); + $func=&mt('Forward'); + $dissub = &mt('Forwarding').': '; + $subj_size = '10'; + my $extra = '<'.&mt('original subject').'>   '. + ''.&mt('Yes').' '.&mt('No'); + $dismsg = &mt('Forwarded message from ').' '; + my $sender = &mt("sender's name"); + $r->print(&msg_subject_row($dissub,\%lt,$subj_size,$extra)); + $r->print(''.&mt('Message begins with:').' '.$sender.'   '.&mt('Yes').' '.&mt('No').' + +
'. +$latexHelp. +&mt("Any new text to display before the text of the original messages:").'
+


'); + my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msg (@to_forward) { + $r->print(''); + } + $r->print(&submit_button_row($folder,$dismode,$func.' '.$lt{'msg'}, + \%lt)); + } elsif ($broadcast ne 'upload') { + $subj_size = '50'; + $r->print(&additional_rec_row(\%lt)); + $r->print(&msg_subject_row($dissub,\%lt,$subj_size)); + $r->print(<<"ENDCOMP"); + $latexHelp


$dispcrit $disbase - - - -
-$citation ENDCOMP + $r->print(&submit_button_row($folder,$dismode,$func.' '.$lt{'ma'}, + \%lt)); + $r->print($citation); if (exists($env{'form.ref'})) { $r->print(''); @@ -1064,31 +1359,34 @@ ENDCOMP $env{'form.group'}.'" />'); } } else { # $broadcast is 'upload' - $r->print(<print(< -

Generate messages from a file

+

$lt{'gen'}

Subject:

-

General message text
+

$lt{'gmt'}:

-The file format for the uploaded portion of the message is: -

-username1\@domain1: text
-username2\@domain2: text
-username3\@domain1: text
-
+$lt{'tff'}: +ENDBLOCK + $r->print(' +
'."\n".
+&mt('username1:domain1: text')."\n".
+&mt('username2:domain2: text')."\n".
+&mt('username3:domain1: text')."\n".
+'

-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') { @@ -1121,12 +1419,41 @@ ENDREC return $output; } +sub additional_rec_row { + my ($lt) = @_; + my $output = <<"ENDADD"; +$lt->{'ad'}:
username:domain,username:domain, ... + + +ENDADD + return $output; +} + +sub submit_button_row { + my ($folder,$dismode,$sendtext,$lt) = @_; + my $output = qq| + + + +
+|; + return $output; +} + +sub msg_subject_row { + my ($dissub,$lt,$subj_size,$extra) = @_; + my $output = ''.$lt->{'sb'}.':'.$extra. + ''; + 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; } @@ -1152,10 +1479,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', @@ -1234,10 +1561,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(); @@ -1311,8 +1638,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; @@ -1324,13 +1651,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' @@ -1362,7 +1691,7 @@ sub examblock { $r->print(<<"END");
- + $end_page END @@ -1373,10 +1702,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 = (); @@ -1388,7 +1713,7 @@ sub blockstore { my %blocking = (); $r->print('

'.$lt{'head'}.'

'); foreach my $envkey (keys(%env)) { - if ($envkey =~ m/^form\.modify_(\w+)$/) { + if ($envkey =~ m/^form\.modify_(\d+)$/) { $adds{$1} = $1; $removals{$1} = $1; $modtotal ++; @@ -1401,7 +1726,7 @@ sub blockstore { } elsif ($envkey =~ m/^form\.add_(\d+)$/) { $adds{$1} = $1; $addtotal ++; - } + } } foreach my $key (keys(%removals)) { @@ -1415,7 +1740,12 @@ sub blockstore { unless ( defined($cancels{$key}) ) { my ($newstart,$newend) = &get_dates_from_form($key); my $newkey = $newstart.'____'.$newend; - $blocking{$newkey} = $env{'user.name'}.':'.$env{'user.domain'}.':'.$env{'form.title_'.$key}; + my $blocktypes = &get_block_choices($key); + $blocking{$newkey} = { + setter => $env{'user.name'}.':'.$env{'user.domain'}, + event => &escape($env{'form.title_'.$key}), + blocks => $blocktypes, + }; } } if ($addtotal + $modtotal > 0) { @@ -1428,13 +1758,13 @@ sub blockstore { if ($chgestotal > 0) { $r->print($lt{'tfcm'}.'
    '); if ($canceltotal > 0) { - $r->print('
  • '.$canceltotal.' '.$lt{'cbps'},' '.$lt{'werm'}.'
  • '); + $r->print('
  • '.&mt('[quant,_1,communication blocking period was,communication blocking periods were] removed.',$canceltotal).'
  • '); } if ($modtotal > 0) { - $r->print('
  • '.$modtotal.' '.$lt{'cbps'},' '.$lt{'wemo'}.'
  • '); + $r->print('
  • '.&mt('[quant,_1,communication blocking period was,communication blocking periods were] modified.',$modtotal).'
  • '); } if ($addtotal > 0) { - $r->print('
  • '.$addtotal.' '.$lt{'cbps'},' '.$lt{'wead'}.'
  • '); + $r->print('
  • '.&mt('[quant,_1,communication blocking period was,communication blocking periods were] added.',$addtotal).'
  • '); } $r->print('
'); } else { @@ -1466,6 +1796,20 @@ sub get_blockdates { } } +sub get_block_choices { + my $item = shift; + my $blocklist; + my ($typeorder,$types) = &blocktype_text(); + foreach my $type (@{$typeorder}) { + if ($env{'form.'.$type.'_'.$item}) { + $blocklist->{$type} = 'on'; + } else { + $blocklist->{$type} = 'off'; + } + } + return $blocklist; +} + sub display_blocker_status { my ($r,$records,$ltext) = @_; my $parmcount = 0; @@ -1474,13 +1818,15 @@ sub display_blocker_status { 'modi' => 'Modify', 'canc' => 'Cancel', ); + my ($typeorder,$types) = &blocktype_text(); $r->print(&Apache::loncommon::start_data_table()); $r->print(<<"END"); - $$ltext{'dura'} - $$ltext{'setb'} - $$ltext{'even'} - $$ltext{'actn'}? + $ltext->{'dura'} + $ltext->{'setb'} + $ltext->{'even'} + $ltext->{'blck'} + $ltext->{'actn'}? END foreach my $record (sort(keys(%{$records}))) { @@ -1491,15 +1837,29 @@ END my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); - my ($setuname,$setudom,$title) = - &parse_block_record($$records{$record}); + my ($setuname,$setudom,$title,$blocks) = + &Apache::loncommon::parse_block_record($$records{$record}); $title = &HTML::Entities::encode($title,'"<>&'); - my $settername = &Apache::loncommon::plainname($setuname,$setudom); + my $settername = + &Apache::loncommon::aboutmewrapper( + &Apache::loncommon::plainname($setuname,$setudom), + $setuname,$setudom); $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); - $$ltext{'star'}: $startform
$$ltext{'endd'}:  $endform + $ltext->{'star'}: $startform
$ltext->{'endd'}:  $endform $settername + +END + foreach my $block (@{$typeorder}) { + my $blockstatus = ''; + if ($blocks->{$block} eq 'on') { + $blockstatus = 'checked="true"'; + } + $r->print('
'); + } + $r->print(<<"END"); +
END $r->print(&Apache::loncommon::end_data_table_row()); @@ -1513,19 +1873,6 @@ END return $parmcount; } -sub parse_block_record { - my ($record) = @_; - my ($setuname,$setudom,$title); - my @data = split(/:/,$record,3); - if (scalar(@data) eq 2) { - $title = $data[1]; - ($setuname,$setudom) = split(/@/,$data[0]); - } else { - ($setuname,$setudom,$title) = @data; - } - return ($setuname,$setudom,$title); -} - sub display_addblocker_table { my ($r,$parmcount,$ltext) = @_; my $start = time; @@ -1540,21 +1887,30 @@ sub display_addblocker_table { 'exam' => 'e.g., Exam 1', 'addn' => 'Add new communication blocking periods' ); + my ($typeorder,$types) = &blocktype_text(); $r->print(<<"END");

$lt{'addn'}

END $r->print(&Apache::loncommon::start_data_table()); $r->print(<<"END"); - $$ltext{'dura'} - $$ltext{'even'} $lt{'exam'} - $$ltext{'actn'}? + $ltext->{'dura'} + $ltext->{'even'} $lt{'exam'} + $ltext->{'blck'} + $ltext->{'actn'}? END - $r->print(&Apache::loncommon::start_data_table_row()); + $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); - $$ltext{'star'}: $startform
$$ltext{'endd'}:  $endform + $ltext->{'star'}: $startform
$ltext->{'endd'}:  $endform + +END + foreach my $block (@{$typeorder}) { + $r->print('
'); + } + $r->print(<<"END"); + END $r->print(&Apache::loncommon::end_data_table_row()); @@ -1562,103 +1918,32 @@ END return; } -sub blockcheck { - my ($setters,$startblock,$endblock) = @_; - # Retrieve active student roles and active course coordinator/instructor roles - my %live_courses = - map { $_ => 1} &Apache::loncommon::findallcourses(); - # FIXME should really probe for apriv, but ::allowed can only probe the - # currently active role - my %staff_of = - map { $_ => 1} &Apache::loncommon::findallcourses(['cc','in']); - - # Retrieve blocking times and identity of blocker for active courses - # for students. - return if (!%live_courses); - - foreach my $course (keys(%live_courses)) { - my $cdom = $env{'course.'.$course.'.domain'}; - my $cnum = $env{'course.'.$course.'.num'}; - - # if they are a staff member and are currently not playing student - next if ( $staff_of{$course} - && ($env{'request.role'} !~ m{^st\./$cdom/$cnum})); - - $setters->{$course} = {}; - $setters->{$course}{'staff'} = []; - $setters->{$course}{'times'} = []; - my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum); - foreach my $record (keys(%records)) { - my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/); - if ($start <= time && $end >= time) { - my ($staff_name,$staff_dom,$title) = - &parse_block_record($records{$record}); - push(@{$$setters{$course}{'staff'}}, [$staff_name,$staff_dom]); - push(@{$$setters{$course}{'times'}}, [$start,$end]); - if ( ($$startblock == 0) || ($$startblock > $1) ) { - $$startblock = $1; - } - if ( ($$endblock == 0) || ($$endblock < $2) ) { - $$endblock = $2; - } - } - } - } -} - -sub build_block_table { - my ($r,$startblock,$endblock,$setters) = @_; - my %lt = &Apache::lonlocal::texthash( - 'cacb' => 'Currently active communication blocks', - 'cour' => 'Course/Group', - 'dura' => 'Duration', - 'blse' => 'Block set by' +sub blocktype_text { + my %types = &Apache::lonlocal::texthash( + 'com' => 'Messaging', + 'chat' => 'Chat', + 'boards' => 'Discussion', + 'port' => 'Portfolio', + 'groups' => 'Groups', + 'blogs' => 'Blogs', ); - $r->print(<<"END"); -

$lt{'cacb'}:

-END - $r->print(&Apache::loncommon::start_data_table()); - $r->print(<<"END"); - - $lt{'cour'} - $lt{'dura'} - $lt{'blse'} - -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.')); @@ -1694,7 +1979,6 @@ sub displaymessage { ''.&mt('Delete').''. ''.&mt('Back to Folder Display').''); if ($counter > 0){ $r->print('print('
'.&mt('Completed.').''); - if ($env{'form.displayedcrit'}) { - &discrit($r); - } - if ($group ne '') { - $r->print(&groupmail_sent($group,$cdom,$cnum)); - } else { - &Apache::loncommunicate::menu($r); - } - } else { - $r->print('

'.&mt('Could not deliver message').' '. + if (!$env{'form.multiforward'}) { + if ($sendstatus=~/^(\s*(?:ok|con_delayed)\s*)*$/) { + $r->print('
'.&mt('Completed.'). + ''); + if ($env{'form.displayedcrit'}) { + &discrit($r); + } + if ($group ne '') { + $r->print(&groupmail_sent($group,$cdom,$cnum)); + } else { + &Apache::loncommunicate::menu($r); + } + } else { + $r->print('

'.&mt('Could not deliver message').' '. &mt('Please use the browser "Back" button and correct the recipient addresses '."($sendstatus)").'

'); + } } + return $sendstatus; } # ===================================================================== Handler @@ -2073,7 +2364,8 @@ sub handler { ['display','replyto','forward','markread','markdel','markunread', 'sendreply','compose','sendmail','critical','recname','recdom', 'recordftf','sortedby','block','folder','startdis','interdis', - 'showcommentbaseurl','dismode','group','subject','text','ref']); + 'showcommentbaseurl','dismode','group','subject','text','ref', + 'msgstatus']); $sqs='&sortedby='.$env{'form.sortedby'}; # ------------------------------------------------------ They checked for email @@ -2103,19 +2395,17 @@ sub handler { unless ($dismode) { $dismode=''; } else { - $sqs.='&dismode='.&escape($dismode); + $sqs.='&dismode='.&escape($dismode); } # --------------------------------------------------------------------- Display - + my $msgstatus = $env{'form.msgstatus'}; $startdis=$env{'form.startdis'}; - $startdis--; + if ($startdis ne '') { + $startdis--; + } unless ($startdis) { $startdis=0; } - $interdis=$env{'form.interdis'}; - unless ($interdis) { $interdis=20; } - $sqs.='&interdis='.$interdis; - if ($env{'form.firstview'}) { $startdis=0; } @@ -2134,7 +2424,7 @@ sub handler { # --------------------------------------------------------------- Render Output if ($env{'form.display'}) { - &displaymessage($r,$env{'form.display'},$folder); + &displaymessage($r,$env{'form.display'},$folder,$msgstatus); } elsif ($env{'form.replyto'}) { &compout($r,'',$env{'form.replyto'},undef,undef,$folder,$dismode); } elsif ($env{'form.confirm'}) { @@ -2171,47 +2461,82 @@ sub handler { '

'.$msg."

\n"); } &Apache::loncommunicate::menu($r); - &disall($r,($folder?$folder:$dismode)); - } elsif ($env{'form.markedmove'}) { - my ($total,$failed,@failed_msg)=(0,0); - foreach my $key (keys(%env)) { - if ($key=~/^form\.delmark_(.*)$/) { - my ($result,$msg) = - &movemsg(&unescape($1),$folder, - $env{'form.movetofolder'}); - if ($result) { + &disall($r,($folder?$folder:$dismode),$msgstatus); + } elsif ($env{'form.markedaction'} eq 'markedforward') { + my $total = 0; + my @to_forward = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msgid (@to_forward) { + &statuschange(&unescape($msgid),'forwarded',$folder); + $total ++; + } + if ($total > 0) { + &compout($r,undef,undef,undef,undef,$folder,$dismode,$total); + } + } elsif ($env{'form.markedaction'} eq 'markedread') { + my $total = 0; + my @to_markread = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msgid (@to_markread) { + &statuschange(&unescape($msgid),'read',$folder); + $total ++; + } + &printheader($r,'','Marked Messages Read'); + $r->print(&mt('Marked [_1] message(s) read',$total).'

'); + &Apache::loncommunicate::menu($r); + &disall($r,($folder?$folder:$dismode),$msgstatus); + } elsif ($env{'form.markedaction'} eq 'markedunread') { + my $total = 0; + my @to_markunread = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msgid (@to_markunread) { + &statuschange(&unescape($msgid),'new',$folder); + $total ++; + } + &printheader($r,'','Marked Messages Unread'); + $r->print(&mt('Marked [_1] message(s) unread',$total).'

'); + &Apache::loncommunicate::menu($r); + &disall($r,($folder?$folder:$dismode),$msgstatus); + } elsif ($env{'form.markedaction'} eq 'markedmove') { + my $destfolder = $env{'form.movetofolder'}; + my %gotfolders = &Apache::lonmsg::get_user_folders(); + &printheader($r,'','Moved Messages'); + if (!defined($gotfolders{$destfolder})) { + $r->print(&mt('Destination folder [_1] is not a valid folder', + $destfolder)); + } else { + my ($total,$failed,@failed_msg)=(0,0); + my @to_move = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msgid (@to_move) { + my ($result,$msg) = &movemsg(&unescape($msgid),$folder, + $env{'form.movetofolder'}); + if ($result) { $total++; - } else { + } else { $failed++; push(@failed_msg,$msg); - } + } } - } - &printheader($r,'','Moved Messages'); - if ($failed) { - $r->print('

+ if ($failed) { + $r->print('

'.&mt('Failed to move [_1] message(s)',$failed). '

'); - $r->print('

'. - join("

\n

",@failed_msg). - "

\n"); - } - $r->print(&mt('Moved [_1] message(s)',$total).'

'); + $r->print('

'. + join("

\n

",@failed_msg). + "

\n"); + } + $r->print(&mt('Moved [_1] message(s)',$total).'

'); + } &Apache::loncommunicate::menu($r); - &disall($r,($folder?$folder:$dismode)); - } elsif ($env{'form.markeddel'}) { + &disall($r,($folder?$folder:$dismode),$msgstatus); + } elsif ($env{'form.markedaction'} eq 'markeddel') { my ($total,$failed,@failed_msg)=(0,0); - foreach my $key (keys(%env)) { - if ($key=~/^form\.delmark_(.*)$/) { - my ($result,$msg) = - &statuschange(&unescape($1),'deleted', - $folder); - if ($result) { - $total++; - } else { - $failed++; - push(@failed_msg,$msg); - } + my @to_delete = &Apache::loncommon::get_env_multiple('form.delmark'); + foreach my $msgid (@to_delete) { + my ($result,$msg) = &statuschange(&unescape($msgid),'deleted', + $folder); + if ($result) { + $total++; + } else { + $failed++; + push(@failed_msg,$msg); } } &printheader($r,'','Deleted Messages'); @@ -2225,12 +2550,12 @@ sub handler { } $r->print(&mt('Deleted [_1] message(s)',$total).'

'); &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'}) { @@ -2238,7 +2563,63 @@ 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}.').

'); + } + } + &Apache::loncommunicate::menu($r); + } else { + &sendoffmail($r,$folder); + } if ($env{'form.storebasecomment'}) { &storecomment($r); } @@ -2250,19 +2631,51 @@ sub handler { $env{'form.message'},'/adm/communicate','public'); } if ((!exists($env{'form.group'})) && (!$env{'form.displayedcrit'})) { - &disall($r,($folder?$folder:$dismode)); + &disall($r,($folder?$folder:$dismode),$msgstatus); } } elsif ($env{'form.newfolder'}) { &printheader($r,'','New Folder'); - &makefolder($env{'form.newfolder'}); - &Apache::loncommunicate::menu($r); - &disall($r,$env{'form.newfolder'}); + my $showfolder = $env{'form.newfolder'}; + my ($makeresult,$warning) = &makefolder($env{'form.newfolder'}); + if ($makeresult eq 'ok') { + $r->print(&mt('Mail folder "[_1]" created.',$showfolder).'
'); + } else { + $r->print(&mt('Creation failed.').' '.$makeresult.'
'. + $warning); + $showfolder = $folder; + } + &Apache::loncommunicate::menu($r); + &disall($r,$showfolder,$msgstatus); } elsif ($env{'form.showcommentbaseurl'}) { &storedcommentlisting($r); + } elsif ($env{'form.folderaction'} eq 'delete') { + &printheader($r,'','Deleted Folder'); + my $showfolder = ''; + my $delresult = &deletefolder($folder); + if ($delresult eq 'ok') { + $r->print(&mt('Mail folder "[_1]" deleted.',$folder).'
'); + } else { + $r->print(&mt('Deletion failed.').' '.$delresult.'
'); + $showfolder = $folder; + } + &Apache::loncommunicate::menu($r); + &disall($r,$showfolder,$msgstatus); + } elsif ($env{'form.folderaction'} eq 'rename') { + &printheader($r,'','Renamed Folder'); + my $showfolder = $env{'form.renamed'}; + my $renresult = &renamefolder($folder); + if ($renresult eq 'ok') { + $r->print(&mt('Mail folder "[_1]" renamed "[_2]".',$folder,$showfolder).'
'); + } else { + $r->print(&mt('Renaming failed.').' '.$renresult.'
'); + $showfolder = $folder; + } + &Apache::loncommunicate::menu($r); + &disall($r,$showfolder,$msgstatus); } else { &printheader($r,'','Display All Messages'); - &Apache::loncommunicate::menu($r); - &disall($r,($folder?$folder:$dismode)); + &Apache::loncommunicate::menu($r); + &disall($r,($folder?$folder:$dismode),$msgstatus); } $r->print(&Apache::loncommon::end_page()); return OK;