--- loncom/interface/lonmsgdisplay.pm 2006/05/30 12:46:09 1.29 +++ loncom/interface/lonmsgdisplay.pm 2006/10/04 20:26:48 1.41 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging display # -# $Id: lonmsgdisplay.pm,v 1.29 2006/05/30 12:46:09 www Exp $ +# $Id: lonmsgdisplay.pm,v 1.41 2006/10/04 20:26:48 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -217,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.')); @@ -226,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.')); } @@ -234,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.')); } } @@ -249,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.')); } @@ -270,12 +270,14 @@ sub discourse { &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'}); unshift @$current_members, (@$course_personnel); my %defaultUsers; + + $result .= ''."\n"; - $result = &Apache::lonselstudent::render_student_list($current_members, - "compemail", - "current", - \%defaultUsers, - 1,"selectedusers",1); + $result .= &Apache::lonselstudent::render_student_list($current_members, + "compemail", + "current", + \%defaultUsers, + 1,"selectedusers",1); $result .= &Apache::lonselstudent::render_student_list($expired_members, "compemail", @@ -290,6 +292,191 @@ sub discourse { return $result; } +sub disgroup { + my ($cdom,$cnum,$group,$viewgrps,$editgrps) = @_; + my $result; + # Needs to be in a course + if (!($env{'request.course.fn'})) { + $result = &mt('Error: you must have a course role selected to be able to send a broadcast message to a group in the course.'); + return $result; + } + if ($cdom eq '' || $cnum eq '') { + $result = &mt('Error: could not determine domain or number of course'); + return $result; + } + my ($memberinfo,$numitems) = + &Apache::longroup::group_memberlist($cdom,$cnum,$group,{},[]); + my @statustypes = ('active'); + if ($viewgrps || $editgrps) { + push(@statustypes,('future','previous')); + } + if (keys(%{$memberinfo}) == 0) { + $result = &mt('As this group has no members, there are no '. + 'recipients to select.'); + return $result; + } else { + $result = &mt('Select message recipients from the group members listed below.
'); + my %Sortby = ( + active => {}, + previous => {}, + future => {}, + ); + my %lt = &Apache::lonlocal::texthash( + 'name' => 'Name', + 'usnm' => 'Username', + 'doma' => 'Domain', + 'active' => 'Active Members', + 'previous' => 'Former Members', + 'future' => 'Future Members', + ); + foreach my $user (sort(keys(%{$memberinfo}))) { + my $status = $$memberinfo{$user}{status}; + if ($env{'form.'.$status.'.sortby'} eq 'fullname') { + push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user); + } elsif ($env{'form.'.$status.'.sortby'} eq 'username') { + push(@{$Sortby{$status}{$$memberinfo{$user}{uname}}},$user); + } elsif ($env{'form.'.$status.'.sortby'} eq 'domain') { + push(@{$Sortby{$status}{$$memberinfo{$user}{udom}}},$user); + } else { + push(@{$Sortby{$status}{$$memberinfo{$user}{fullname}}},$user); + } + } + $result .= &group_check_uncheck(); + $result .= ''. + ''; + foreach my $status (@statustypes) { + if (ref($numitems) eq 'HASH') { + if ((defined($$numitems{$status})) && ($$numitems{$status})) { + $result.='". + "". + "". + &Apache::loncommon::end_data_table_header_row(); + foreach my $key (sort(keys(%{$Sortby{$status}}))) { + foreach my $user (@{$Sortby{$status}{$key}}) { + $result .= + &Apache::loncommon::start_data_table_row(). + ''. + ''. + ''. + &Apache::loncommon::end_data_table_row(); + } + } + $result .= &Apache::loncommon::end_data_table(); + } + } + $result .= ''; + } + $result .= '
'. + '
'.$lt{$status}. + ''. + ''. + '  '. + ''. + '

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(); + $result .= "
$lt{'name'}$lt{'usnm'}$lt{'doma'}'. + $$memberinfo{$user}{'fullname'}.''.$$memberinfo{$user}{'uname'}.''.$$memberinfo{$user}{'udom'}.'  
'; + } + return $result; +} + +sub group_check_uncheck { + my $output = qq| + + |; +} + +sub groupmail_header { + my ($action,$group,$cdom,$cnum) = @_; + my ($description,$refarg); + if (!$cdom || !$cnum) { + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + } + if (exists($env{'form.ref'})) { + $refarg = 'ref='.$env{'form.ref'}; + } + if (!$group) { + $group = $env{'form.group'}; + } + if ($group eq '') { + return ''; + } else { + my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$group); + if (defined($curr_groups{$group})) { + my %groupinfo = + &Apache::longroup::get_group_settings($curr_groups{$group}); + $description = &unescape($groupinfo{'description'}); + } + } + &Apache::lonhtmlcommon::clear_breadcrumbs(); + if ($refarg) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursegroups", + text=>"Groups", + title=>"View course groups"}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/$cdom/$cnum/$group/smppg?$refarg", + text=>"Group: $description", + title=>"Go to group's home page"}, + {href=>"/adm/email?compose=group&group=". + "$env{'form.group'}&$refarg", + text=>"Send a Message in a Group", + title=>"Compose Group Email Message"},); + if ($action eq 'sending') { + &Apache::lonhtmlcommon::add_breadcrumb + ({text=>"Messages being sent.", + title=>"Messages sent"},); + } + my $groupheader = &Apache::loncommon::start_page('Group Email'); + $groupheader .= &Apache::lonhtmlcommon::breadcrumbs + ('Group - '.$env{'form.group'}.' Email'); + return $groupheader; +} + +sub groupmail_sent { + my ($group,$cdom,$cnum) = @_; + my $refarg; + if (exists($env{'form.ref'})) { + $refarg = 'ref='.$env{'form.ref'}; + } + my $output .= '

'. + &mt('Send another group email').''.'   '. + ''. &mt('Return to group page').''; + return $output; +} + # ==================================================== Display Critical Message sub discrit { @@ -453,7 +640,7 @@ sub disnew { my %lt=&Apache::lonlocal::texthash( 'nm' => 'New Messages', 'su' => 'Subject', - 'co' => 'Course', + 'co' => 'Course/Group', 'da' => 'Date', 'us' => 'Username', 'op' => 'Open', @@ -571,7 +758,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") { @@ -709,8 +896,14 @@ ENDDISHEADER sub compout { my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_; my $suffix=&Apache::lonmsg::foldersuffix($folder); - - if ($broadcast eq 'individual') { + my ($cdom,$cnum,$group,$refarg); + if (exists($env{'form.group'})) { + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + $group = $env{'form.group'}; + my $action = 'composing'; + $r->print(&groupmail_header($action,$group,$cdom,$cnum)); + } elsif ($broadcast eq 'individual') { &printheader($r,'/adm/email?compose=individual', 'Send a Message'); } elsif ($broadcast) { @@ -802,15 +995,34 @@ sub compout { } } my $citation=&displayresource(%content); + my ($can_grp_broadcast,$viewgrps,$editgrps); if ($env{'form.recdom'}) { $defdom=$env{'form.recdom'}; } if ($env{'form.text'}) { $dismsg=$env{'form.text'}; } if ($env{'form.subject'}) { $dissub=$env{'form.subject'}; } $r->print( '
'."\n". - ''."\n". - ''); - unless (($broadcast eq 'group') || ($broadcast eq 'upload')) { + ''."\n"); + if ($broadcast eq 'group' && $env{'form.group'} ne '') { + $can_grp_broadcast = + &Apache::lonnet::allowed('sgb',$env{'request.course.id'}.'/'. + $group); + $viewgrps = + &Apache::lonnet::allowed('vcg',$env{'request.course.id'}. + ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); + $editgrps = + &Apache::lonnet::allowed('mdg',$env{'request.course.id'}. + ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); + if ($viewgrps || $editgrps || $can_grp_broadcast) { + $r->print(&disgroup($cdom,$cnum,$group,$viewgrps,$editgrps)); + } + } + $r->print('
'); + if (($broadcast eq 'group') && ($group ne '') && + (!$can_grp_broadcast && !$viewgrps && !$editgrps)) { + $r->print(&recipient_input_row($cdom,%lt)); + } + if (($broadcast ne 'group') && ($broadcast ne 'upload')) { if ($replying) { $r->print(''); } else { - my $domform = &Apache::loncommon::select_dom_form($defdom,'recdomain'); - my $selectlink=&Apache::loncommon::selectstudent_link - ('compemail','recuname','recdomain'); - $r->print(<<"ENDREC"); - - - -ENDREC + $r->print(&recipient_input_row($defdom,%lt)); } } my $latexHelp = Apache::loncommon::helpLatexCheatsheet(); @@ -850,6 +1055,14 @@ $disbase
$citation ENDCOMP + if (exists($env{'form.ref'})) { + $r->print(''); + } + if (exists($env{'form.group'})) { + $r->print(''); + } } else { # $broadcast is 'upload' $r->print(< @@ -879,9 +1092,13 @@ $dispcrit ENDUPLOAD } if ($broadcast eq 'group') { - &discourse($r); - my $studentsel = &discourse(); - $r->print($studentsel); + if ($group eq '') { + my $studentsel = &discourse(); + $r->print($studentsel); + } + } + if ($env{'form.displayedcrit'}) { + $r->print(''); } $r->print(''. &Apache::lonfeedback::generate_preview_button('compemail','message'). @@ -890,6 +1107,20 @@ ENDUPLOAD # ---------------------------------------------------- Display all face to face +sub recipient_input_row { + my ($dom,%lt) = @_; + my $domform = &Apache::loncommon::select_dom_form($dom,'recdomain'); + my $selectlink= + &Apache::loncommon::selectstudent_link('compemail','recuname', + 'recdomain'); + my $output = <<"ENDREC"; + + + +ENDREC + return $output; +} + sub retrieve_instructor_comments { my ($user,$domain)=@_; my $target=$env{'form.grade_target'}; @@ -976,10 +1207,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); @@ -1008,6 +1240,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"); @@ -1025,9 +1260,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'}

@@ -1048,13 +1283,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'}).'

'); @@ -1086,10 +1317,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' ); @@ -1377,7 +1610,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' ); @@ -1421,6 +1654,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); @@ -1502,8 +1737,8 @@ sub displaymessage { $content{'sendername'}.' at '. $content{'senderdomain'}.') ':'
'.&mt('To').': '. $tolist). - ($content{'courseid'}?'
'.&mt('Course').': '.$courseinfo{'description'}. - ($content{'coursesec'}?' ('.&mt('Group/Section').': '.$content{'coursesec'}.')':''):''). + ($content{'courseid'}?'
'.&mt($crstype).': '.$courseinfo{'description'}. + ($content{'coursesec'}?' ('.&mt('Section').': '.$content{'coursesec'}.')':''):''). '
'.&mt('Time').': '.$content{'time'}. ($content{'baseurl'}?'
'.&mt('Refers to').':'. $content{'baseurl'}.' ('.&Apache::lonnet::gettitle($content{'baseurl'}).')':''). @@ -1555,13 +1790,12 @@ sub header { my $extra = &Apache::loncommon::studentbrowser_javascript(); if ($baseurl) { - $extra .= ""; + $extra .= ""; } $r->print(&Apache::loncommon::start_page('Communication and Messages', - $extra)); + $extra)); $r->print(&Apache::lonhtmlcommon::breadcrumbs - (($title?$title:'Communication and Messages'))); - + (($title?$title:'Communication and Messages'))); } # ---------------------------------------------------------------- Print header @@ -1617,8 +1851,20 @@ sub sendoffmail { my $sendstatus=''; my %specialmsg_status; my $numspecial = 0; + my ($cdom,$cnum,$group); + if (exists($env{'form.group'})) { + $group = $env{'form.group'}; + } + if (exists($env{'request.course.id'})) { + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + } if ($env{'form.send'}) { - &printheader($r,'','Messages being sent.'); + if ($group eq '') { + &printheader($r,'','Messages being sent.'); + } else { + $r->print(&groupmail_header('sending',$group)); + } $r->rflush(); my %content=(); undef %content; @@ -1637,12 +1883,13 @@ sub sendoffmail { &statuschange($msgid,'replied',$folder); } - my $to = $env{'form.selectedusers.forminput'}; + my @to = + &Apache::loncommon::get_env_multiple('form.selectedusers_forminput'); my $mode = $env{'form.sendmode'}; my %toaddr; - if ($to) { - foreach my $dest (@$to) { + 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. @@ -1742,8 +1989,6 @@ sub sendoffmail { $subj_prefix = 'Broadcast.'; } my ($specialmsgid,$specialresult); - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $course_str = &escape('['.$cnum.':'.$cdom.']'); if ($numspecial) { @@ -1799,6 +2044,9 @@ sub sendoffmail { $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); } @@ -1825,7 +2073,7 @@ 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']); + 'showcommentbaseurl','dismode','group','subject','text','ref']); $sqs='&sortedby='.$env{'form.sortedby'}; # ------------------------------------------------------ They checked for email @@ -1891,6 +2139,7 @@ sub handler { &compout($r,'',$env{'form.replyto'},undef,undef,$folder,$dismode); } elsif ($env{'form.confirm'}) { &printheader($r,'','Confirmed Receipt'); + my $replying = 0; foreach (keys %env) { if ($_=~/^form\.rec\_(.*)$/) { $r->print(''.&mt('Confirming Receipt').': '. @@ -1901,9 +2150,12 @@ sub handler { $r->print(''.&mt('Confirming Receipt').': '. &Apache::lonmsg::user_crit_received($msgid).'
'); &compout($r,'','','',$msgid); + $replying = 1; } } - &discrit($r); + if (!$replying) { + &discrit($r); + } } elsif ($env{'form.critical'}) { &printheader($r,'','Displaying Critical Messages'); &discrit($r); @@ -1989,15 +2241,17 @@ sub handler { &sendoffmail($r,$folder); if ($env{'form.storebasecomment'}) { &storecomment($r); - } + } if (($env{'form.rsspost'}) && ($env{'request.course.id'})) { - &Apache::lonrss::addentry($env{'course.'.$env{'request.course.id'}.'.num'}, + &Apache::lonrss::addentry($env{'course.'.$env{'request.course.id'}.'.num'}, $env{'course.'.$env{'request.course.id'}.'.domain'}, 'Course_Announcements', $env{'form.subject'}, $env{'form.message'},'/adm/communicate','public'); } - &disall($r,($folder?$folder:$dismode)); + if ((!exists($env{'form.group'})) && (!$env{'form.displayedcrit'})) { + &disall($r,($folder?$folder:$dismode)); + } } elsif ($env{'form.newfolder'}) { &printheader($r,'','New Folder'); &makefolder($env{'form.newfolder'}); @@ -2025,9 +2279,3 @@ sub handler { __END__ - - - - - -
'.&mt('Replying to').' '. &Apache::loncommon::aboutmewrapper( @@ -821,14 +1033,7 @@ sub compout { ''. '
$lt{'us'}:$selectlink
$lt{'do'}:$domform
$lt{'us'}:$selectlink
$lt{'do'}:$domform