--- loncom/interface/lonmsgdisplay.pm 2006/04/23 04:04:38 1.8 +++ loncom/interface/lonmsgdisplay.pm 2006/05/17 09:51:26 1.26 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging display # -# $Id: lonmsgdisplay.pm,v 1.8 2006/04/23 04:04:38 albertel Exp $ +# $Id: lonmsgdisplay.pm,v 1.26 2006/05/17 09:51:26 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -28,6 +28,7 @@ package Apache::lonmsgdisplay; +use Apache::lonselstudent; =pod @@ -184,8 +185,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 @@ -206,107 +208,73 @@ sub movemsg { if ($srcfolder eq 'new') { $srcfolder=''; } my $srcsuffix=&Apache::lonmsg::foldersuffix($srcfolder); my $trgsuffix=&Apache::lonmsg::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 sub discourse { - my $r=shift; - my $classlist = &Apache::loncoursedata::get_classlist(); - my $now=time; - my %lt=&Apache::lonlocal::texthash('cfa' => 'Check All', - 'cfs' => 'Check Section/Group', - 'cfn' => 'Uncheck All'); - $r->print(<<ENDDISHEADER); -<input type="hidden" name="sendmode" value="group" /> -<script> - function checkall() { - for (i=0; i<document.forms.compemail.elements.length; i++) { - if - (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) { - document.forms.compemail.elements[i].checked=true; - } - } - } + my $result; + my ($course_personnel, + $current_members, + $expired_members, + $future_members) = &Apache::lonselstudent::get_people_in_class(); + unshift @$current_members, (@$course_personnel); + my %defaultUsers; + + $result = &Apache::lonselstudent::render_student_list($current_members, + "compemail", + "current", + \%defaultUsers, + 1,"selectedusers",1); - function checksec() { - for (i=0; i<document.forms.compemail.elements.length; i++) { - if - (document.forms.compemail.elements[i].name.indexOf - ('send_to_&&&'+document.forms.compemail.chksec.value+'&&&')==0) { - document.forms.compemail.elements[i].checked=true; - } - } - } - - function uncheckall() { - for (i=0; i<document.forms.compemail.elements.length; i++) { - if - (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) { - document.forms.compemail.elements[i].checked=false; - } - } - } -</script> -<input type="button" onClick="checkall()" value="$lt{'cfa'}" /> -<input type="button" onClick="checksec()" value="$lt{'cfs'}" /> -<input type="text" size="5" name="chksec" /> -<input type="button" onClick="uncheckall()" value="$lt{'cfn'}" /> -<p> -ENDDISHEADER - my %coursepersonnel=&Apache::lonnet::get_course_adv_roles(); - $r->print('<table>'); - foreach my $role (sort keys %coursepersonnel) { - foreach (split(/\,/,$coursepersonnel{$role})) { - my ($puname,$pudom)=split(/\:/,$_); - $r->print('<tr><td><label>'. - '<input type="checkbox" name="send_to_&&&&&&_'. - $puname.':'.$pudom.'" /> '. - &Apache::loncommon::plainname($puname,$pudom). - '</label></td>'. - '<td>('.$_.'),</td><td><i>'.$role.'</i></td></tr>'); - } - } - $r->print('</table><table>'); - my $sort = sub { - my $aname=lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]); - if (!$aname) { $aname=$a; } - my $bname=lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]); - if (!$bname) { $bname=$b; } - return $aname cmp $bname; - }; - foreach my $student (sort $sort (keys(%{$classlist}))) { - my $info=$classlist->{$student}; - my ($sname,$sdom,$status,$fullname,$section) = - (@{$info}[&Apache::loncoursedata::CL_SNAME(), - &Apache::loncoursedata::CL_SDOM(), - &Apache::loncoursedata::CL_STATUS(), - &Apache::loncoursedata::CL_FULLNAME(), - &Apache::loncoursedata::CL_SECTION()]); - next if ($status ne 'Active'); - next if ($env{'request.course.sec'} && - $section ne $env{'request.course.sec'}); - my $key = 'send_to_&&&'.$section.'&&&_'.$student; - if (! defined($fullname) || $fullname eq '') { $fullname = $sname; } - $r->print('<tr><td><label>'. - qq{<input type="checkbox" name="$key" />}.(' 'x2). - $fullname.'</label></td><td>'.$sname.'@'.$sdom.'</td><td>'.$section. - '</td></tr>'); - } - $r->print('</table>'); + return $result; } # ==================================================== Display Critical Message @@ -324,7 +292,7 @@ sub discrit { $result.='<hr />'.&mt('From').': <b>'. &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('. -$content{'sendername'}.'@'. +$content{'sendername'}.':'. $content{'senderdomain'}.') '.$content{'time'}. '<br />'.&mt('Subject').': '.$content{'subject'}. '<br /><pre>'. @@ -357,18 +325,30 @@ sub sortedmessages { my %descriptions; my %status_cache = &Apache::lonnet::get('email_status'.&Apache::lonmsg::foldersuffix($folder),\@messages); - foreach (@messages) { - my $msgid=&Apache::lonnet::escape($_); + + my $get_received; + if ($folder eq 'sent' + && ($env{'form.sortedby'} =~ m/^(rev)?(user|domain)$/)) { + $get_received = 1; + } + + foreach my $msgid (@messages) { + my $esc_msgid=&Apache::lonnet::escape($msgid); my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)= - &Apache::lonmsg::unpackmsgid($msgid,$folder,undef, + &Apache::lonmsg::unpackmsgid($esc_msgid,$folder,undef, \%status_cache); my $description = &get_course_desc($fromcid,\%descriptions); my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status, - $msgid,$description); + $esc_msgid,$description); + if ($get_received) { + my %message = &Apache::lonnet::get('nohist_email'.$suffix, + [$msgid]); + my %content = &Apache::lonmsg::unpackagemsg($message{$msgid}); + push(@temp1,$content{'recuser'},$content{'recdomain'}); + } # Check whether message was sent during blocking period. if ($sendtime >= $startblock && ($sendtime <= $endblock && $endblock > 0) ) { - my $escid = &Apache::lonnet::unescape($msgid); - $$blocked{$escid} = 'ON'; + $$blocked{$msgid} = 'ON'; $$numblocked ++; } else { push @temp ,\@temp1; @@ -383,16 +363,32 @@ sub sortedmessages { @temp = sort {$b->[0] <=> $a->[0]} @temp; } if ($env{'form.sortedby'} eq "user"){ - @temp = sort {lc($a->[2]) cmp lc($b->[2])} @temp; + if ($get_received) { + @temp = sort {lc($a->[7][0]) cmp lc($b->[7][0])} @temp; + } else { + @temp = sort {lc($a->[2]) cmp lc($b->[2])} @temp; + } } if ($env{'form.sortedby'} eq "revuser"){ - @temp = sort {lc($b->[2]) cmp lc($a->[2])} @temp; + if ($get_received) { + @temp = sort {lc($b->[7][0]) cmp lc($a->[7][0])} @temp; + } else { + @temp = sort {lc($b->[2]) cmp lc($a->[2])} @temp; + } } if ($env{'form.sortedby'} eq "domain"){ - @temp = sort {$a->[3] cmp $b->[3]} @temp; + if ($get_received) { + @temp = sort {$a->[8][0] cmp $b->[8][0]} @temp; + } else { + @temp = sort {$a->[3] cmp $b->[3]} @temp; + } } if ($env{'form.sortedby'} eq "revdomain"){ - @temp = sort {$b->[3] cmp $a->[3]} @temp; + if ($get_received) { + @temp = sort {$b->[8][0] cmp $a->[8][0]} @temp; + } else { + @temp = sort {$b->[3] cmp $a->[3]} @temp; + } } if ($env{'form.sortedby'} eq "subject"){ @temp = sort {lc($a->[1]) cmp lc($b->[1])} @temp; @@ -549,7 +545,7 @@ sub disfolder { my $numblocked = 0; &blockcheck(\%setters,\$startblock,\$endblock); $r->print(<<ENDDISHEADER); -<script> +<script type="text/javascript"> function checkall() { for (i=0; i<document.forms.disall.elements.length; i++) { if @@ -627,7 +623,9 @@ ENDDISHEADER my $suffix = &Apache::lonmsg::foldersuffix($folder); for (my $n=$firstdis;$n<=$lastdis;$n++) { - my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID,$description)= @{$temp[$n]}; + my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$origID, + $description,$recv_name,$recv_domain)= + @{$temp[$n]}; if (($status ne 'deleted') && defined($sendtime) && $sendtime!~/error/) { if ($status eq 'new') { $r->print('<tr class="LC_mail_new">'); @@ -640,12 +638,17 @@ ENDDISHEADER } my ($dis_name,$dis_domain) = ($fromname,$fromdomain); if ($folder eq 'sent') { - my $msg_id = &Apache::lonnet::unescape($origID); - my %message=&Apache::lonnet::get('nohist_email'.$suffix, - [$msg_id]); - my %content=&Apache::lonmsg::unpackagemsg($message{$msg_id}); - $dis_name = join('<br />',@{$content{'recuser'}}); - $dis_domain = join('<br />',@{$content{'recdomain'}}); + if (defined($recv_name) && !defined($recv_domain)) { + $dis_name = join('<br />',@{$recv_name}); + $dis_domain = join('<br />',@{$recv_domain}); + } else { + my $msg_id = &Apache::lonnet::unescape($origID); + my %message = &Apache::lonnet::get('nohist_email'.$suffix, + [$msg_id]); + my %content = &Apache::lonmsg::unpackagemsg($message{$msg_id}); + $dis_name = join('<br />',@{$content{'recuser'}}); + $dis_domain = join('<br />',@{$content{'recdomain'}}); + } } $r->print('<td><input type="checkbox" name="delmark_'.$origID.'" /></td><td><a href="/adm/email?display='.$origID.$sqs. '">'.&mt('Open').'</a></td><td>'. @@ -657,7 +660,9 @@ ENDDISHEADER $description.'</td><td>'.$status.'</td></tr>'."\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("</table>\n<p>". @@ -785,7 +790,9 @@ sub compout { } my $citation=&displayresource(%content); if ($env{'form.recdom'}) { $defdom=$env{'form.recdom'}; } - $r->print( + if ($env{'form.text'}) { $dismsg=$env{'form.text'}; } + if ($env{'form.subject'}) { $dissub=$env{'form.subject'}; } + $r->print( '<form action="/adm/email" name="compemail" method="post"'. ' enctype="multipart/form-data">'."\n". '<input type="hidden" name="sendmail" value="on" />'."\n". @@ -795,7 +802,7 @@ sub compout { $r->print('<tr><td colspan="2">'.&mt('Replying to').' '. &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).' ('. - $content{'sendername'}.'@'. + $content{'sendername'}.':'. $content{'senderdomain'}.')'. '<input type="hidden" name="recuname" value="'.$content{'sendername'}.'" />'. '<input type="hidden" name="recdomain" value="'.$content{'senderdomain'}.'" />'. @@ -860,6 +867,8 @@ ENDUPLOAD } if ($broadcast eq 'group') { &discourse($r); + my $studentsel = &discourse(); + $r->print($studentsel); } $r->print('</form>'. &Apache::lonfeedback::generate_preview_button('compemail','message'). @@ -888,7 +897,7 @@ sub retrieve_instructor_comments { next if ($content{'subject'} !~ /^Record/); # &Apache::lonfeedback::newline_to_br(\$content{'message'}); $result.='Recorded by '. - $content{'sendername'}.'@'.$content{'senderdomain'}."\n"; + $content{'sendername'}.':'.$content{'senderdomain'}."\n"; $result.= &Apache::lontexconvert::msgtexconverted($content{'message'})."\n"; } @@ -946,7 +955,7 @@ sub disfacetoface { $result.=&mt('By').': <b>'. &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($content{'sendername'},$content{'senderdomain'}),$content{'sendername'},$content{'senderdomain'}).'</b> ('. -$content{'sendername'}.'@'. +$content{'sendername'}.':'. $content{'senderdomain'}.') '.$content{'time'}. '<br /><pre>'. &Apache::lontexconvert::msgtexconverted($content{'message'}). @@ -1160,7 +1169,7 @@ sub blockstore { unless ( defined($cancels{$_}) ) { my ($newstart,$newend) = &get_dates_from_form($_); my $newkey = $newstart.'____'.$newend; - $blocking{$newkey} = $env{'user.name'}.'@'.$env{'user.domain'}.':'.$env{'form.title_'.$_}; + $blocking{$newkey} = $env{'user.name'}.':'.$env{'user.domain'}.':'.$env{'form.title_'.$_}; } } if ($addtotal + $modtotal > 0) { @@ -1203,70 +1212,54 @@ sub get_blockdates { $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'} ); - $$blockcount = keys %{$records}; - - foreach (keys %{$records}) { - if ($_ eq 'error: 2 tie(GDBM) Failed while attempting dump') { - $$blockcount = 0; - last; - } + $$blockcount = keys(%{$records}); + + if ((keys(%{$records}))[0] =~ /^error: 2 /) { + $records = {}; + $$blockcount = 0; } } sub display_blocker_status { my ($r,$records,$ltext) = @_; my $parmcount = 0; - my @bgcols = ("#eeeeee","#dddddd"); - my $function = &Apache::loncommon::get_users_function(); - my $color = &Apache::loncommon::designparm($function.'.tabbg', - $env{'user.domain'}); + my %lt = &Apache::lonlocal::texthash( 'modi' => 'Modify', 'canc' => 'Cancel', ); + $r->print(&Apache::loncommon::start_data_table()); $r->print(<<"END"); -<table border="0" cellpadding="0" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table width="100%" border="0" cellpadding="1" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF"> - <tr bgcolor="$color"> - <td><b>$$ltext{'dura'}</b></td> - <td><b>$$ltext{'setb'}</b></td> - <td><b>$$ltext{'even'}</b></td> - <td><b>$$ltext{'actn'}?</b></td> - </tr> + <tr> + <th>$$ltext{'dura'}</th> + <th>$$ltext{'setb'}</th> + <th>$$ltext{'even'}</th> + <th>$$ltext{'actn'}?</th> + </tr> END - foreach (sort keys %{$records}) { - my $iter = $parmcount%2; + foreach my $record (sort(keys(%{$records}))) { my $onchange = 'onFocus="javascript:window.document.forms['. "'blockform'].elements['modify_".$parmcount."'].". 'checked=true;"'; - my ($start,$end) = split/____/,$_; + my ($start,$end) = split(/____/,$record); my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); - my ($setter,$title) = split/:/,$$records{$_}; - my ($setuname,$setudom) = split/@/,$setter; + + my ($setuname,$setudom,$title) = + &parse_block_record($$records{$record}); + $title = &HTML::Entities::encode($title,'"<>&'); my $settername = &Apache::loncommon::plainname($setuname,$setudom); + $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); - <tr bgcolor="$bgcols[$iter]"> <td>$$ltext{'star'}: $startform<br/>$$ltext{'endd'}: $endform</td> <td>$settername</td> - <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$_" /></td> + <td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$record" /></td> <td><label>$lt{'modi'}? <input type="checkbox" name="modify_$parmcount" /></label><br /><label>$lt{'canc'}? <input type="checkbox" name="cancel_$parmcount" /></label> - </tr> END - $parmcount ++; + $r->print(&Apache::loncommon::end_data_table_row()); + $parmcount++; } $r->print(<<"END"); - </table> - </td> - </tr> - </table> - </td> - </tr> </table> <br /> <br /> @@ -1274,6 +1267,19 @@ 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; @@ -1283,9 +1289,6 @@ sub display_addblocker_table { 'checked=true;"'; my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); - my $function = &Apache::loncommon::get_users_function(); - my $color = &Apache::loncommon::designparm($function.'.tabbg', - $env{'user.domain'}); my %lt = &Apache::lonlocal::texthash( 'addb' => 'Add block', 'exam' => 'e.g., Exam 1', @@ -1293,133 +1296,106 @@ sub display_addblocker_table { ); $r->print(<<"END"); <h4>$lt{'addn'}</h4> -<table border="0" cellpadding="0" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table width="100%" border="0" cellpadding="1" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF"> - <tr bgcolor="#CCCCFF"> - <td><b>$$ltext{'dura'}</b></td> - <td><b>$$ltext{'even'} $lt{'exam'}</b></td> - <td><b>$$ltext{'actn'}?</b></td> - </tr> - <tr bgcolor="#eeeeee"> - <td>$$ltext{'star'}: $startform<br />$$ltext{'endd'}: $endform</td> - <td><input type="text" name="title_$parmcount" size="15" value="" /></td> - <td><label>$lt{'addb'}? <input type="checkbox" name="add_$parmcount" value="1" /></label></td> - </tr> - </table> - </td> - </tr> - </table> - </td> - </tr> -</table> END + $r->print(&Apache::loncommon::start_data_table()); + $r->print(<<"END"); + <tr> + <th>$$ltext{'dura'}</th> + <th>$$ltext{'even'} $lt{'exam'}</th> + <th>$$ltext{'actn'}?</th> + </tr> +END + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print(<<"END"); + <td>$$ltext{'star'}: $startform<br />$$ltext{'endd'}: $endform</td> + <td><input type="text" name="title_$parmcount" size="15" value="" /></td> + <td><label>$lt{'addb'}? <input type="checkbox" name="add_$parmcount" value="1" /></label></td> +END + $r->print(&Apache::loncommon::end_data_table_row()); + $r->print(&Apache::loncommon::end_data_table()); return; } sub blockcheck { my ($setters,$startblock,$endblock) = @_; # Retrieve active student roles and active course coordinator/instructor roles - my @livecses = (); - my @staffcses = (); - $$startblock = 0; - $$endblock = 0; - foreach (keys %env) { - if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) { - my $role = $1; - my $cse = $2; - $cse =~ s|/|_|; - if ($env{$_} =~ m/^(\d*)\.(\d*)$/) { - unless (($2 > 0 && $2 < time) || ($1 > time)) { - if ($role eq 'st') { - push @livecses, $cse; - } else { - unless (grep/^$cse$/,@staffcses) { - push @staffcses, $cse; - } - } - } - } - } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) { - my $rolepriv = $env{'user.role..rolesdef_'.$3}; - } - } - # Retrieve blocking times and identity of blocker for active courses for students. - if (@livecses > 0) { - foreach my $cse (@livecses) { - my ($cdom,$crs) = split/_/,$cse; - if ( (grep/^$cse$/,@staffcses) && ($env{'request.role'} !~ m-^st\./$cdom/$crs$-) ) { - next; - } else { - %{$$setters{$cse}} = (); - @{$$setters{$cse}{'staff'}} = (); - @{$$setters{$cse}{'times'}} = (); - my %records = &Apache::lonnet::dump('comm_block',$cdom,$crs); - foreach (keys %records) { - if ($_ =~ m/^(\d+)____(\d+)$/) { - if ($1 <= time && $2 >= time) { - my ($staff,$title) = split/:/,$records{$_}; - push @{$$setters{$cse}{'staff'}}, $staff; - push @{$$setters{$cse}{'times'}}, $_; - if ( ($$startblock == 0) || ($$startblock > $1) ) { - $$startblock = $1; - } - if ( ($$endblock == 0) || ($$endblock < $2) ) { - $$endblock = $2; - } - } - } - } - } - } + 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 $function = &Apache::loncommon::get_users_function(); - my $color = &Apache::loncommon::designparm($function.'.tabbg', - $env{'user.domain'}); my %lt = &Apache::lonlocal::texthash( 'cacb' => 'Currently active communication blocks', 'cour' => 'Course', 'dura' => 'Duration', 'blse' => 'Block set by' - ); + ); $r->print(<<"END"); -<br /<br />$lt{'cacb'}:<br /><br /> -<table border="0" cellpadding="0" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table width="100%" border="0" cellpadding="1" cellspacing="0"> - <tr> - <td width="100%" bgcolor="#000000"> - <table border="0" cellpadding="3" cellspacing="3" bgcolor="#FFFFFF"> - <tr bgcolor="$color"> - <td><b>$lt{'cour'}</b></td> - <td><b>$lt{'dura'}</b></td> - <td><b>$lt{'blse'}</b></td> - </tr> +<br /><br />$lt{'cacb'}:<br /><br /> +END + $r->print(&Apache::loncommon::start_data_table()); + $r->print(<<"END"); +<tr> + <th>$lt{'cour'}</th> + <th>$lt{'dura'}</th> + <th>$lt{'blse'}</th> +</tr> END - foreach (keys %{$setters}) { - my %courseinfo=&Apache::lonnet::coursedescription($_); - for (my $i=0; $i<@{$$setters{$_}{staff}}; $i++) { - my ($uname,$udom) = split/\@/,$$setters{$_}{staff}[$i]; + 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) = split/____/,$$setters{$_}{times}[$i]; + my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]}; $openblock = &Apache::lonlocal::locallocaltime($openblock); $closeblock= &Apache::lonlocal::locallocaltime($closeblock); - $r->print('<tr><td>'.$courseinfo{'description'}.'</td>'. + $r->print(&Apache::loncommon::start_data_table_row(). + '<td>'.$courseinfo{'description'}.'</td>'. '<td>'.$openblock.' to '.$closeblock.'</td>'. - '<td>'.$fullname.' ('.$uname.'@'.$udom. - ')</td></tr>'); + '<td>'.$fullname.' ('.$uname.':'.$udom. + ')</td>'. + &Apache::loncommon::end_data_table_row()); } } - $r->print('</table></td></tr></table></td></tr></table>'); + $r->print(&Apache::loncommon::end_data_table()); } # ----------------------------------------------------------- Display a message @@ -1571,7 +1547,7 @@ sub header { $r->print(&Apache::loncommon::start_page('Communication and Messages', $extra)); $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,($title?$title:'Communication and Messages'))); + (($title?$title:'Communication and Messages'))); } @@ -1647,29 +1623,46 @@ sub sendoffmail { %content=&Apache::lonmsg::unpackagemsg($message{$msgid},1); &statuschange($msgid,'replied',$folder); } - my %toaddr=(); - undef %toaddr; - if ($env{'form.sendmode'} eq 'group') { - foreach (keys %env) { - if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) { - $toaddr{$1}=''; + + my $to = $env{'form.selectedusers.forminput'}; + my $mode = $env{'form.sendmode'}; + + my %toaddr; + if ($to) { + foreach my $dest (@$to) { + my ($user,$domain) = split /:/, $dest; + if (($user ne '') && ($domain ne '')) { + my $address = $user.":".$domain; # How the code below expects it. + $toaddr{$address} = ''; } } + } + + if ($env{'form.sendmode'} eq 'group') { + foreach my $address (keys(%env)) { + if ($address=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) { + $toaddr{$1}=''; + } + } } elsif ($env{'form.sendmode'} eq 'upload') { - foreach (split(/[\n\r\f]+/,$env{'form.upfile'})) { - my ($rec,$txt)=split(/\s*\:\s*/,$_); + foreach my $line (split(/[\n\r\f]+/,$env{'form.upfile'})) { + my ($rec,$txt)=split(/\s*\:\s*/,$line); if ($txt) { $rec=~s/\@/\:/; $toaddr{$rec}.=$txt."\n"; } } } else { - $toaddr{$env{'form.recuname'}.':'.$env{'form.recdomain'}}=''; + if (($env{'form.recuname'} ne '') && ($env{'form.recdomain'} ne '')) { + $toaddr{$env{'form.recuname'}.':'.$env{'form.recdomain'}}=''; + } } if ($env{'form.additionalrec'}) { foreach (split(/\,/,$env{'form.additionalrec'})) { my ($auname,$audom)=split(/\@/,$_); - $toaddr{$auname.':'.$audom}=''; + if (($auname ne "") && ($audom ne "")) { + $toaddr{$auname.':'.$audom}=''; + } } } @@ -1689,33 +1682,43 @@ sub sendoffmail { $savemsg=&Apache::lonfeedback::clear_out_html($env{'form.message'}); } - foreach (keys %toaddr) { - my ($recuname,$recdomain)=split(/\:/,$_); + foreach my $address (sort(keys(%toaddr))) { + my ($recuname,$recdomain)=split(/\:/,$address); my $msgtxt = $savemsg; - if ($toaddr{$_}) { $msgtxt.='<hr />'.$toaddr{$_}; } - my $thismsg; + if ($toaddr{$address}) { $msgtxt.='<hr />'.$toaddr{$address}; } + 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'}. '/'.$env{'request.course.sec'}))) { - $r->print(&mt('Sending critical message').' '.$recuname.'@'.$recdomain.': '); - $thismsg=&Apache::lonmsg::user_crit_msg($recuname,$recdomain,$msgsubj,$msgtxt, - $env{'form.sendbck'},$env{'form.permanent'}, - \$sentmessage{$_}); + $r->print(&mt('Sending critical message').' '.$recuname.':'.$recdomain.': '); + @thismsg= + &Apache::lonmsg::user_crit_msg($recuname,$recdomain, + $msgsubj,$msgtxt, + $env{'form.sendbck'}, + $env{'form.permanent'}, + \$sentmessage{$address}); } else { - $r->print(&mt('Sending').' '.$recuname.'@'.$recdomain.': '); - $thismsg=&Apache::lonmsg::user_normal_msg($recuname,$recdomain,$msgsubj,$msgtxt, - $content{'citation'},undef,undef,$env{'form.permanent'},\$sentmessage{$_}); + $r->print(&mt('Sending').' '.$recuname.':'.$recdomain.': '); + @thismsg= + &Apache::lonmsg::user_normal_msg($recuname,$recdomain, + $msgsubj,$msgtxt, + $content{'citation'}, + undef,undef, + $env{'form.permanent'}, + \$sentmessage{$address}); } if (($env{'request.course.id'}) && (($msgtype eq 'critical') || ($env{'form.sendmode'} eq 'group'))) { - $specialmsg_status{$recuname.':'.$recdomain} = $thismsg; - if ($thismsg eq 'ok') { - $numspecial ++; - } + $specialmsg_status{$recuname.':'.$recdomain} = + join(' ',@thismsg); + foreach my $result (@thismsg) { + if ($result eq 'ok') { + $numspecial++; + } + } } - $r->print($thismsg.'<br />'); - $sendstatus.=' '.$thismsg; + $sendstatus.=' '.join(' ',@thismsg); } if (($env{'request.course.id'}) && (($env{'form.sendmode'} eq 'group') || ($msgtype eq 'critical'))) { @@ -1738,10 +1741,11 @@ sub sendoffmail { } if ($specialresult eq 'ok') { my $record_sent; - my @recusers = (); - my @recudoms = (); - my ($stamp,$crssubj,$msgname,$msgdom,$msgcount,$context,$pid) = - split(/\:/,&Apache::lonnet::unescape($specialmsgid)); + my @recusers; + my @recudoms; + my ($stamp,$crssubj,$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.']'; @@ -1753,15 +1757,15 @@ sub sendoffmail { &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,$subj_prefix. ' ['.$recipient.']',$msgsubj,undef, undef,undef,undef,$usermsgid,undef,undef,$specialmsgid); - my ($uname,$udom) = split/:/,$recipient; + my ($uname,$udom) = split(/:/,$recipient); push(@recusers,$uname); push(@recudoms,$udom); } } if (@recusers) { my $specialmessage; - my $sentsubj = $subj_prefix.' ('.$numspecial.' sent) '. - $msgsubj; + my $sentsubj = + $subj_prefix.' ('.$numspecial.' sent) '.$msgsubj; $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"'); my $sentmsgid = &Apache::lonmsg::buildmsgid($stamp,$sentsubj,$msgname, @@ -1787,7 +1791,7 @@ sub sendoffmail { } } else { $r->print('<p><span class="LC_error">'.&mt('Could not deliver message').'</span> '. - &mt('Please use the browser "Back" button and correct the recipient addresses').'</p>'); + &mt('Please use the browser "Back" button and correct the recipient addresses '."($sendstatus)").'</p>'); } } @@ -1808,7 +1812,7 @@ sub handler { ['display','replyto','forward','markread','markdel','markunread', 'sendreply','compose','sendmail','critical','recname','recdom', 'recordftf','sortedby','block','folder','startdis','interdis', - 'showcommentbaseurl','dismode']); + 'showcommentbaseurl','dismode','group','subject','text']); $sqs='&sortedby='.$env{'form.sortedby'}; # ------------------------------------------------------ They checked for email @@ -1894,32 +1898,67 @@ 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('<p class="LC_error">'. + &mt('Failed to delete the message.').'</p>'. + '<p class="LC_error">'.$msg."</p>\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'); - $r->print('Moved '.$total.' message(s)<p>'); + if ($failed) { + $r->print('<p class="LC_error"> + '.&mt('Failed to move [_1] message(s)',$failed). + '</p>'); + $r->print('<p class="LC_error">'. + join("</p>\n<p class=\"LC_error\">",@failed_msg). + "</p>\n"); + } + $r->print(&mt('Moved [_1] message(s)',$total).'<p>'); &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'); - $r->print('Deleted '.$total.' message(s)<p>'); + if ($failed) { + $r->print('<p class="LC_error"> + '.&mt('Failed to delete [_1] message(s)',$failed). + '</p>'); + $r->print('<p class="LC_error">'. + join("</p>\n<p class=\"LC_error\">",@failed_msg). + "</p>\n"); + } + $r->print(&mt('Deleted [_1] message(s)',$total).'<p>'); &Apache::loncommunicate::menu($r); &disall($r,($folder?$folder:$dismode)); } elsif ($env{'form.markunread'}) {