--- loncom/interface/lonmsgdisplay.pm 2006/05/11 19:04:31 1.23 +++ loncom/interface/lonmsgdisplay.pm 2006/06/29 13:52:19 1.35 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging display # -# $Id: lonmsgdisplay.pm,v 1.23 2006/05/11 19:04:31 www Exp $ +# $Id: lonmsgdisplay.pm,v 1.35 2006/06/29 13:52:19 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -125,6 +125,9 @@ use Apache::lonlocal; use Apache::loncommunicate; use Apache::lonfeedback; use Apache::lonrss(); +use Apache::lonselstudent(); +use lib '/home/httpd/lib/perl/'; +use LONCAPA; # Querystring component with sorting type my $sqs; @@ -214,7 +217,7 @@ sub movemsg { # Copy message my %message=&Apache::lonnet::get('nohist_email'.$srcsuffix,[$msgid]); if (!exists($message{$msgid}) || $message{$msgid} eq '') { - if (&Apache::slotrequest::network_error(%message)) { + if (&Apache::lonnet::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.')); @@ -223,7 +226,7 @@ sub movemsg { my $result =&Apache::lonnet::put('nohist_email'.$trgsuffix, {$msgid => $message{$msgid}}); - if (&Apache::slotrequest::network_error($result)) { + if (&Apache::lonnet::error($result)) { return (0,&mt('Message not moved, A network error occurred.')); } @@ -231,12 +234,12 @@ sub movemsg { unless ($trgfolder eq 'trash') { 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)) { + if (&Apache::lonnet::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)) { + if (&Apache::lonnet::error($result)) { return (0,&mt('Message copied to new folder but status was not, A network error occurred.')); } } @@ -246,10 +249,10 @@ sub movemsg { &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)) { + if (&Apache::lonnet::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)) { + if (&Apache::lonnet::error($result_del_stat)) { return (0,&mt('Message copied, but unable to delete the original status from the source folder.')); } @@ -259,133 +262,32 @@ sub movemsg { # ======================================================= Display a course list sub discourse { - my $r=shift; - my $classlist = &Apache::loncoursedata::get_classlist(); - my ($classgroups,$studentgroups) = - &Apache::loncoursedata::get_group_memberships($classlist); - my %lt=&Apache::lonlocal::texthash('cfa' => 'Check All', - 'cfs' => 'Check Section/Group', - 'cfn' => 'Uncheck All'); - if (defined($env{'form.group'})) { - $r->print(''."\n"); - } - $r->print(< - -  - -  - -

-ENDDISHEADER - my %coursepersonnel=&Apache::lonnet::get_course_adv_roles(); - $r->print(&Apache::loncommon::start_data_table()); - if (keys(%coursepersonnel) > 0) { - $r->print('

Non-students

'); - $r->print(&Apache::loncommon::start_data_table()); - $r->print('NameUsername:DomainRole'); - foreach my $role (sort(keys(%coursepersonnel))) { - foreach my $user (split(/\,/,$coursepersonnel{$role})) { - my ($puname,$pudom)=split(/\:/,$user); - $r->print(&Apache::loncommon::start_data_table_row()); - $r->print(''. - '('.$user.'),'.$role.''); - $r->print(&Apache::loncommon::end_data_table_row()); - } - } - $r->print(&Apache::loncommon::end_data_table()); - } - if (keys(%{$classlist}) > 0) { - $r->print('

Students

'); - $r->print(&Apache::loncommon::start_data_table()); - $r->print('NameUsername:DomainSectionGroups'); - 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 @studentsgroups = - &Apache::loncoursedata::get_students_groups($student,$status, - $classgroups); - my $grouplist = join(', ',@studentsgroups); - my $key = 'send_to_&&&'.$section.'&&&_'.$student; - if (! defined($fullname) || $fullname eq '') {$fullname = $sname;} - my $checked = ''; - my $groupcount = 0; - my $groupitems; - $r->print(&Apache::loncommon::start_data_table_row()); - $r->print(''.$groupitems. - ''.$sname.':'.$sdom.''.$section. - ''.$grouplist.''); - $r->print(&Apache::loncommon::end_data_table_row()); - } - $r->print(&Apache::loncommon::end_data_table()); - } + my $result; + my ($course_personnel, + $current_members, + $expired_members, + $future_members) = + &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'}); + unshift @$current_members, (@$course_personnel); + my %defaultUsers; + + $result = &Apache::lonselstudent::render_student_list($current_members, + "compemail", + "current", + \%defaultUsers, + 1,"selectedusers",1); + + $result .= &Apache::lonselstudent::render_student_list($expired_members, + "compemail", + "expired", + \%defaultUsers, + 1, "selectedusers",0); + $result .= &Apache::lonselstudent::render_student_list($future_members, + "compemail", + "future", + \%defaultUsers, + 1, "selectedusers", 0); + return $result; } # ==================================================== Display Critical Message @@ -418,7 +320,7 @@ $content{'sendername'}.':'. # Check to see if there were any messages. if ($result eq '') { $result = "

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

". - ''.&mt('Select a course').'
'. + ''.&mt('Select a course or group').'
'. ''.&mt('Communicate').''; } else { $r->print($header); @@ -444,7 +346,7 @@ sub sortedmessages { } foreach my $msgid (@messages) { - my $esc_msgid=&Apache::lonnet::escape($msgid); + my $esc_msgid=&escape($msgid); my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)= &Apache::lonmsg::unpackmsgid($esc_msgid,$folder,undef, \%status_cache); @@ -551,7 +453,7 @@ sub disnew { my %lt=&Apache::lonlocal::texthash( 'nm' => 'New Messages', 'su' => 'Subject', - 'co' => 'Course', + 'co' => 'Course/Group', 'da' => 'Date', 'us' => 'Username', 'op' => 'Open', @@ -570,7 +472,7 @@ sub disnew { &Apache::lonnet::get('email_status',\@msgids); my %descriptions; foreach (@msgids) { - my $msgid=&Apache::lonnet::escape($_); + my $msgid=&escape($_); my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)= &Apache::lonmsg::unpackmsgid($msgid,undef,undef,\%status_cache); if (defined($sendtime) && $sendtime!~/error/) { @@ -669,7 +571,7 @@ sub disfolder { function uncheckall() { for (i=0; iprint(''); if ($env{'form.sortedby'} eq "revcourse") { - $r->print(''.&mt('Course').''); + $r->print(''.&mt('Course/Group').''); } else { - $r->print(''.&mt('Course').''); + $r->print(''.&mt('Course/Group').''); } $r->print(''); if ($env{'form.sortedby'} eq "revstatus") { @@ -753,7 +655,7 @@ ENDDISHEADER $dis_name = join('
',@{$recv_name}); $dis_domain = join('
',@{$recv_domain}); } else { - my $msg_id = &Apache::lonnet::unescape($origID); + my $msg_id = &unescape($origID); my %message = &Apache::lonnet::get('nohist_email'.$suffix, [$msg_id]); my %content = &Apache::lonmsg::unpackagemsg($message{$msg_id}); @@ -772,7 +674,7 @@ ENDDISHEADER } elsif ($status eq 'deleted') { # purge my ($result,$msg) = - &movemsg(&Apache::lonnet::unescape($origID),$folder,'trash'); + &movemsg(&unescape($origID),$folder,'trash'); } } @@ -816,15 +718,15 @@ sub compout { 'Broadcast Message'); } elsif ($forwarding) { &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/email?display=".&Apache::lonnet::escape($forwarding), + ({href=>"/adm/email?display=".&escape($forwarding), text=>"Display Message"}); - &printheader($r,'/adm/email?forward='.&Apache::lonnet::escape($forwarding), + &printheader($r,'/adm/email?forward='.&escape($forwarding), 'Forwarding a Message'); } elsif ($replying) { &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/email?display=".&Apache::lonnet::escape($replying), + ({href=>"/adm/email?display=".&escape($replying), text=>"Display Message"}); - &printheader($r,'/adm/email?replyto='.&Apache::lonnet::escape($replying), + &printheader($r,'/adm/email?replyto='.&escape($replying), 'Replying to a Message'); } elsif ($replycrit) { $r->print('

'.&mt('Replying to a Critical Message').'

'); @@ -874,7 +776,7 @@ sub compout { $dismsg=&mt('Forwarded message from').' '. $content{'sendername'}.' '.&mt('at').' '.$content{'senderdomain'}; if ($content{'baseurl'}) { - $disbase=''; + $disbase=''; } } if ($replying) { @@ -890,11 +792,11 @@ sub compout { $dismsg=~s/\f/\n/g; $dismsg=~s/\n+/\n\> /g; if ($content{'baseurl'}) { - $disbase=''; + $disbase=''; if ($env{'user.adv'}) { $disbase.=' '. + &escape($content{'baseurl'}).'" target="comments">'. &mt('Show re-usable messages').'
'; } } @@ -978,6 +880,8 @@ ENDUPLOAD } if ($broadcast eq 'group') { &discourse($r); + my $studentsel = &discourse(); + $r->print($studentsel); } $r->print(''. &Apache::lonfeedback::generate_preview_button('compemail','message'). @@ -1038,7 +942,7 @@ sub disfacetoface { $result .='

'.&mt('Broadcast Message').'

'; if ($content{'subject'}=~/^Broadcast\./) { if (defined($content{'coursemsgid'})) { - my $crsmsgid = &Apache::lonnet::escape($content{'coursemsgid'}); + my $crsmsgid = &escape($content{'coursemsgid'}); my $broadcast_message = &general_message($crsmsgid); $content{'message'} = ''.&mt('Subject').': '.$content{'message'}.'
'.$broadcast_message; } else { @@ -1051,7 +955,7 @@ sub disfacetoface { } else { $result.='

'.&mt('Critical Message').'

'; if (defined($content{'coursemsgid'})) { - my $crsmsgid=&Apache::lonnet::escape($content{'coursemsgid'}); + my $crsmsgid=&escape($content{'coursemsgid'}); my $critical_message = &general_message($crsmsgid); $content{'message'} = ''.&mt('Subject').': '.$content{'message'}.'
'.$critical_message; } else { @@ -1072,10 +976,11 @@ $content{'sendername'}.':'. } # Check to see if there were any messages. if ($result eq '') { + my $lctype = lc(&Apache::loncommon::course_type()); if ($target ne 'tex') { - $r->print("

".&mt("No notes, face-to-face discussion records, critical messages, or broadcast messages in this course.")."

"); + $r->print("

".&mt('No notes, face-to-face discussion records, critical messages, or broadcast messages in this [_1].',$lctype)."

"); } else { - $r->print('\textbf{'.&mt("No notes, face-to-face discussion records, critical messages or broadcast messages in this course.").'}\\\\'); + $r->print('\textbf{'.&mt('No notes, face-to-face discussion records, critical messages or broadcast messages in this [_1].',$lctype).'}\\\\'); } } else { $r->print($result); @@ -1104,6 +1009,9 @@ sub facetoface { $r->print('Not allowed'); return; } + my $crstype = &Apache::loncommon::course_type(); + my $leaders = ($crstype eq 'Group') ? 'coordinators and leaders' + : 'faculty and staff'; &printheader($r, '/adm/email?recordftf=query', "User Notes, Face-to-Face, Critical Messages, Broadcast Messages"); @@ -1121,9 +1029,9 @@ sub facetoface { ('stdselect','recuname','recdomain'); my %lt=&Apache::lonlocal::texthash('user' => 'Username', 'dom' => 'Domain', - 'head' => 'User Notes, Records of Face-To-Face Discussions, Critical Messages, and Broadcast Messages in Course', + 'head' => "User Notes, Records of Face-To-Face Discussions, Critical Messages, and Broadcast Messages in $crstype", 'subm' => 'Retrieve discussion and message records', - 'newr' => 'New Record (record is visible to course faculty and staff)', + 'newr' => 'New Record (record is visible to '.lc($crstype).' '.$leaders.')', 'post' => 'Post this Record'); $r->print(<<"ENDTREC");

$lt{'head'}

@@ -1144,13 +1052,9 @@ ENDTREC ($env{'form.recdomain'}) && ($env{'form.recuname'})) { chomp($env{'form.newrecord'}); if ($env{'form.newrecord'}) { - my $recordtxt = $env{'form.newrecord'}; - &Apache::lonmsg::user_normal_msg_raw( - $env{'course.'.$env{'request.course.id'}.'.num'}, - $env{'course.'.$env{'request.course.id'}.'.domain'}, - &mt('Record'). - ' ['.$env{'form.recuname'}.':'.$env{'form.recdomain'}.']', - $recordtxt); + &Apache::lonmsg::store_instructor_comment($env{'form.newrecord'}, + $env{'form.recuname'}, + $env{'form.recdomain'}); } $r->print('

'.&Apache::loncommon::plainname($env{'form.recuname'}, $env{'form.recdomain'}).'

'); @@ -1182,10 +1086,12 @@ sub examblock { $r->print('Not allowed'); return; } + my $usertype = (&Apache::loncommon::course_type() eq 'Group') ? 'members' + : 'students'; my %lt=&Apache::lonlocal::texthash( 'comb' => 'Communication Blocking', 'cbds' => 'Communication blocking during scheduled exams', - 'desc' => 'You can use communication blocking to prevent students enrolled in this course from displaying LON-CAPA messages sent by other students during an online exam. As blocking of communication could potentially interrupt legitimate communication between students 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.', + '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' ); @@ -1473,7 +1379,7 @@ sub build_block_table { my ($r,$startblock,$endblock,$setters) = @_; my %lt = &Apache::lonlocal::texthash( 'cacb' => 'Currently active communication blocks', - 'cour' => 'Course', + 'cour' => 'Course/Group', 'dura' => 'Duration', 'blse' => 'Block set by' ); @@ -1517,6 +1423,8 @@ sub displaymessage { 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); @@ -1532,7 +1440,7 @@ sub displaymessage { my $counter=0; $r->print('
');
-    my $escmsgid=&Apache::lonnet::escape($msgid);
+    my $escmsgid=&escape($msgid);
     foreach (@messages) {
 	if ($_->[5] eq $escmsgid){
 	    last;
@@ -1542,17 +1450,17 @@ sub displaymessage {
     $r->print('
'); my $number_of_messages = scalar(@messages); #subtract 1 for last index # start output - &printheader($r,'/adm/email?display='.&Apache::lonnet::escape($msgid),'Display a Message','',$content{'baseurl'}); + &printheader($r,'/adm/email?display='.&escape($msgid),'Display a Message','',$content{'baseurl'}); my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'}); # Functions $r->print(''. - ''. - ''. - ''. - ''. '
'.&mt('Functions').':'.&mt('Reply').''.&mt('Forward').''.&mt('Mark Unread').''.&mt('Delete').''. $content{'baseurl'}.' ('.&Apache::lonnet::gettitle($content{'baseurl'}).')':''). @@ -1681,14 +1589,14 @@ sub storecomment { $cleanmsgtxt.=$_."\n"; } } - my $key=&Apache::lonnet::escape($env{'form.baseurl'}).'___'.time; + my $key=&escape($env{'form.baseurl'}).'___'.time; &Apache::lonnet::put('nohist_stored_comments',{ $key => $cleanmsgtxt }); } sub storedcommentlisting { my ($r)=@_; my %msgs=&Apache::lonnet::dump('nohist_stored_comments',undef,undef, - '^'.&Apache::lonnet::escape(&Apache::lonnet::escape($env{'form.showcommentbaseurl'}))); + '^'.&escape(&escape($env{'form.showcommentbaseurl'}))); $r->print(&Apache::loncommon::start_page('Stored Comment Listing',undef, {'onlybody' => 1})); if ((keys %msgs)[0]=~/^error\:/) { @@ -1733,13 +1641,27 @@ sub sendoffmail { &statuschange($msgid,'replied',$folder); } + my @to = + &Apache::loncommon::get_env_multiple('form.selectedusers.forminput'); + my $mode = $env{'form.sendmode'}; + my %toaddr; - if ($env{'form.sendmode'} eq 'group') { - foreach my $address (keys(%env)) { - if ($address=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) { - $toaddr{$1}=''; + 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 my $line (split(/[\n\r\f]+/,$env{'form.upfile'})) { my ($rec,$txt)=split(/\s*\:\s*/,$line); @@ -1749,12 +1671,16 @@ sub sendoffmail { } } } 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}=''; + } } } @@ -1823,20 +1749,20 @@ sub sendoffmail { my ($specialmsgid,$specialresult); my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $course_str = &Apache::lonnet::escape('['.$cnum.':'.$cdom.']'); + my $course_str = &escape('['.$cnum.':'.$cdom.']'); if ($numspecial) { $specialresult = &Apache::lonmsg::user_normal_msg_raw($cnum,$cdom,$subj_prefix. ' '.$course_str,$savemsg,undef,undef,undef, undef,undef,\$specialmsgid); - $specialmsgid = &Apache::lonnet::unescape($specialmsgid); + $specialmsgid = &unescape($specialmsgid); } if ($specialresult eq 'ok') { my $record_sent; my @recusers; my @recudoms; my ($stamp,$crssubj,$msgname,$msgdom,$msgcount,$context,$pid) = - split(/\:/,&Apache::lonnet::unescape($specialmsgid)); + split(/\:/,&unescape($specialmsgid)); foreach my $recipient (sort(keys(%toaddr))) { if ($specialmsg_status{$recipient} eq 'ok') { @@ -1883,7 +1809,7 @@ sub sendoffmail { } } else { $r->print('

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

'); + &mt('Please use the browser "Back" button and correct the recipient addresses '."($sendstatus)").'

'); } } @@ -1926,7 +1852,7 @@ sub handler { unless ($folder) { $folder=''; } else { - $sqs.='&folder='.&Apache::lonnet::escape($folder); + $sqs.='&folder='.&escape($folder); } # ------------------------------------------------------------ Get Display Mode @@ -1934,7 +1860,7 @@ sub handler { unless ($dismode) { $dismode=''; } else { - $sqs.='&dismode='.&Apache::lonnet::escape($dismode); + $sqs.='&dismode='.&escape($dismode); } # --------------------------------------------------------------------- Display @@ -2004,7 +1930,7 @@ sub handler { foreach my $key (keys(%env)) { if ($key=~/^form\.delmark_(.*)$/) { my ($result,$msg) = - &movemsg(&Apache::lonnet::unescape($1),$folder, + &movemsg(&unescape($1),$folder, $env{'form.movetofolder'}); if ($result) { $total++; @@ -2031,7 +1957,7 @@ sub handler { foreach my $key (keys(%env)) { if ($key=~/^form\.delmark_(.*)$/) { my ($result,$msg) = - &statuschange(&Apache::lonnet::unescape($1),'deleted', + &statuschange(&unescape($1),'deleted', $folder); if ($result) { $total++;