--- loncom/interface/lonfeedback.pm 2004/10/11 18:02:40 1.99.2.11 +++ loncom/interface/lonfeedback.pm 2004/07/21 21:47:13 1.100 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.99.2.11 2004/10/11 18:02:40 albertel Exp $ +# $Id: lonfeedback.pm,v 1.100 2004/07/21 21:47:13 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,7 +36,6 @@ use Apache::loncommon(); use Apache::lontexconvert(); use Apache::lonlocal; # must not have () use Apache::lonhtmlcommon(); -use Apache::lonnavmaps(); sub discussion_open { my ($status)=@_; @@ -81,7 +80,9 @@ sub list_discussion { $symb=&Apache::lonnet::symbread(); } unless ($symb) { return ''; } - + my %usernamesort = (); + my %namesort =(); + my %subjectsort = (); # backward compatibility (bulletin boards used to be 'wrapped') my $ressymb=$symb; if ($mode eq 'board') { @@ -93,17 +94,20 @@ sub list_discussion { # Get discussion display settings for this discussion my $lastkey = $ressymb.'_lastread'; my $showkey = $ressymb.'_showonlyunread'; + my $visitkey = $ressymb.'_visit'; my $ondispkey = $ressymb.'_markondisp'; - my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$ondispkey],$ENV{'user.domain'},$ENV{'user.name'}); + my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey,$ondispkey],$ENV{'user.domain'},$ENV{'user.name'}); my %discinfo = (); my $showonlyunread = 0; my $markondisp = 0; my $prevread = 0; my $previous = 0; + my $visit = 0; my $newpostsflag = 0; # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts. - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous']); + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts']); + my $sortposts = $ENV{'form.sortposts'}; $previous = $ENV{'form.previous'}; if ($previous > 0) { $prevread = $previous; @@ -114,28 +118,32 @@ sub list_discussion { } # Get discussion display default settings for user - if ($ENV{'environment.discdisplay'} eq 'unread') { + my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'}); + my $discdisplay=$userenv{'discdisplay'}; + if ($discdisplay eq 'unread') { $showonlyunread = 1; } - if ($ENV{'environment.discmarkread'} eq 'ondisp') { + my $discmarkread=$userenv{'discmarkread'}; + if ($discmarkread eq 'ondisp') { $markondisp = 1; } # Override user's default if user specified display setting for this discussion if (defined($dischash{$ondispkey})) { - unless ($dischash{$showkey} eq '') { - $markondisp = $dischash{$ondispkey}; - } + $markondisp = $dischash{$ondispkey}; } if ($markondisp) { $discinfo{$lastkey} = time; } if (defined($dischash{$showkey})) { - unless ($dischash{$showkey} eq '') { - $showonlyunread = $dischash{$showkey}; - } + $showonlyunread = $dischash{$showkey}; + } + + if (defined($dischash{$visitkey})) { + $visit = $dischash{$visitkey}; } + $visit ++; my $seeid=&Apache::lonnet::allowed('rin',$crs); my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs) @@ -161,9 +169,9 @@ sub list_discussion { } my $now = time; - if (%discinfo) { - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } + $discinfo{$visitkey} = $visit; + + &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); if ($contrib{'version'}) { my $oldest = $contrib{'1:timestamp'}; @@ -179,12 +187,17 @@ sub list_discussion { my $hidden=($contrib{'hidden'}=~/\.$idx\./); my $deleted=($contrib{'deleted'}=~/\.$idx\./); my $origindex='0.'; - if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) { + if ($contrib{$idx.':replyto'}) { + if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread')) { # this is a follow-up message - $original[$idx]=$original[$contrib{$idx.':replyto'}]; - $depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1; - $origindex=$index[$contrib{$idx.':replyto'}]; - if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; } + $original[$idx]=$original[$contrib{$idx.':replyto'}]; + $depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1; + $origindex=$index[$contrib{$idx.':replyto'}]; + if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; } + } else { + $original[$idx]=0; + $depth[$idx]=0; + } } else { # this is an original message $original[$idx]=0; @@ -218,15 +231,28 @@ sub list_discussion { if ($hidden) { $message=''.$message.''; } -# my $screenname=&Apache::loncommon::screenname( -# $contrib{$idx.':sendername'}, -# $contrib{$idx.':senderdomain'}); -# my $plainname=&Apache::loncommon::nickname( -# $contrib{$idx.':sendername'}, -# $contrib{$idx.':senderdomain'}); - my ($screenname,$plainname)=($contrib{$idx.':screenname'}, - $contrib{$idx.':plainname'}); + my $screenname=&Apache::loncommon::screenname( + $contrib{$idx.':sendername'}, + $contrib{$idx.':senderdomain'}); + my $plainname=&Apache::loncommon::nickname( + $contrib{$idx.':sendername'}, + $contrib{$idx.':senderdomain'}); + my $sender=&mt('Anonymous'); +# Set up for sorting by subject + if ($contrib{$idx.':subject'} eq '') { + if (defined($subjectsort{'__No subject'})) { + push @{$subjectsort{'__No subject'}}, $idx; + } else { + @{$subjectsort{'__No subject'}} = ("$idx"); + } + } else { + if (defined($subjectsort{$contrib{$idx.':subject'}})) { + push @{$subjectsort{$contrib{$idx.':subject'}}}, $idx; + } else { + @{$subjectsort{$contrib{$idx.':subject'}}} = ("$idx"); + } + } if ((!$contrib{$idx.':anonymous'}) || ($seeid)) { $sender=&Apache::loncommon::aboutmewrapper( $plainname, @@ -238,6 +264,34 @@ sub list_discussion { $sender.=' ['.&mt('anonymous').'] '. $screenname; } +# Set up for sorting by domain, then username + unless (defined($usernamesort{$contrib{$idx.':senderdomain'}})) { + %{$usernamesort{$contrib{$idx.':senderdomain'}}} = (); + } + if (defined($usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}})) { + push @{$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}}, $idx; + } else { + @{$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}} = ("$idx"); + } +# Set up for sorting by last name, then first name + my %names = &Apache::lonnet::get('environment',['firstname','lastname'], + $contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'}); + my $lastname = $names{'lastname'}; + my $firstname = $names{'firstname'}; + if ($lastname eq '') { + $lastname = '_'; + } + if ($firstname eq '') { + $firstname = '_'; + } + unless (defined($namesort{$lastname})) { + %{$namesort{$lastname}} = (); + } + if (defined($namesort{$lastname}{$firstname})) { + push @{$namesort{$lastname}{$firstname}}, $idx; + } else { + @{$namesort{$lastname}{$firstname}} = ("$idx"); + } if ($seeid) { if ($hidden) { $sender.=' '; + if ($newpostsflag) { + $sender .= '&previous='.$prevread; + } + $sender .= '">'.&mt('Delete').''; } } else { if ($screenname) { $sender=''.$screenname.''; } +# Set up for sorting by domain, then username for anonymous + unless (defined($usernamesort{'__anon'})) { + %{$usernamesort{'__anon'}} = (); + } + if (defined($usernamesort{'__anon'}{'__anon'})) { + push @{$usernamesort{'__anon'}{'__anon'}}, $idx; + } else { + @{$usernamesort{'__anon'}{'__anon'}} = ("$idx"); + } +# Set up for sorting by last name, then first name for anonymous + unless (defined($namesort{'__anon'})) { + %{$namesort{'__anon'}} = (); + } + if (defined($namesort{'__anon'}{'__anon'})) { + push @{$namesort{'__anon'}{'__anon'}}, $idx; + } else { + @{$namesort{'__anon'}{'__anon'}} = ("$idx"); + } } if (&discussion_open($status) && &Apache::lonnet::allowed('pch', @@ -284,7 +356,7 @@ sub list_discussion { } #figure out at what position this needs to print my $thisindex=$idx; - if ($ENV{'environment.threadeddiscussion'}) { + if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread')) { $thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2); } $alldiscussion{$thisindex}=$idx; @@ -377,8 +449,20 @@ sub list_discussion { if ($newpostsflag) { $discussion .= '&previous='.$prevread; } - $discussion .='">'.&mt('Chronological View').'  '; - } + $discussion .='">'.&mt('Chronological View').'   + '.&mt('Sorting/Filtering options').'  '; + } else { + $discussion .= ''; + } + $discussion .=''.&mt('Export').'?  '; if ($newpostsflag) { if (!$markondisp) { $discussion .=''.&mt('Mark new posts as read').'  '; @@ -408,7 +492,37 @@ sub list_discussion { $numhidden.' '.&mt('previously viewed posts'). '
'; } - foreach (sort { $a <=> $b } keys %alldiscussion) { + +# Choose sort mechanism + my @showposts = (); + if ($sortposts eq 'descdate') { + @showposts = (sort { $b <=> $a } keys %alldiscussion); + } elsif ($sortposts eq 'thread') { + @showposts = (sort { $a <=> $b } keys %alldiscussion); + } elsif ($sortposts eq 'subject') { + foreach (sort keys %subjectsort) { + push @showposts, @{$subjectsort{$_}}; + } + } elsif ($sortposts eq 'username') { + foreach my $domain (sort keys %usernamesort) { + foreach (sort keys %{$usernamesort{$domain}}) { + push @showposts, @{$usernamesort{$domain}{$_}}; + } + } + } elsif ($sortposts eq 'lastfirst') { + foreach my $last (sort keys %namesort) { + foreach (sort keys %{$namesort{$last}}) { + push @showposts, @{$namesort{$last}{$_}}; + } + } + } else { + $sortposts = 'ascdate'; + @showposts = (sort { $a <=> $b } keys %alldiscussion); + } + foreach (@showposts) { + unless (($sortposts eq 'thread') || ($sortposts eq 'ascdate' && $ENV{'environment.threadeddiscussion'})) { + $alldiscussion{$_} = $_; + } unless ($notshown{$alldiscussion{$_}} eq '1') { if ($outputtarget ne 'tex') { $discussion.="\n"; @@ -515,7 +629,7 @@ ENDDISCUSS ''. &mt('Post Discussion').''; } - } + } } return $discussion; } @@ -548,6 +662,11 @@ sub mail_screen { } my $latexHelp=&Apache::loncommon::helpLatexCheatsheet(); my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders(); + my $onsubmit=''; + if ((&Apache::lonhtmlcommon::htmlareabrowser()) && + (!&Apache::lonhtmlcommon::htmlareablocked())) { + $onsubmit='document.mailform.onsubmit();'; + } my $send=&mt('Send'); $r->print(< @@ -591,9 +710,7 @@ $htmlheader } if (rec) { - if (typeof(document.mailform.onsubmit)=='function') { - document.mailform.onsubmit(); - } + $onsubmit document.mailform.submit(); } else { alert('Please check a feedback type.'); @@ -763,6 +880,148 @@ END return; } +sub print_sortfilter_options { + my ($r,$symb,$previous,$feedurl) = @_; + # backward compatibility (bulletin boards used to be 'wrapped') + if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { + $feedurl=~s|^/adm/wrapper||; + } + my @sections = (); + my $section_sel = ''; + my $numsections = 0; + my $numvisible = 5; + my ($classlist) = &Apache::loncoursedata::get_classlist( + $ENV{'request.course.id'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + + my $sec_index = &Apache::loncoursedata::CL_SECTION(); + my $status_index = &Apache::loncoursedata::CL_STATUS(); + my %sectioncount = (); + while (my ($student,$data) = each %$classlist) { + my ($section,$status) = ($data->[$sec_index], + $data->[$status_index]); + unless ($section eq '' || $section =~ /^\s*$/) { + if (!defined($sectioncount{$section})) { + $sectioncount{$section} = 1; + $numsections ++; + } else { + $sectioncount{$section} ++; + } + } + } + + if ($ENV{'request.course.sec'} !~ /^\s*$/) { + @sections = ($ENV{'request.course.sec'}); + $numvisible = 1; + } else { + @sections = sort {$a cmp $b} keys(%sectioncount); + unshift(@sections,'all'); # Put 'all' at the front of the list + if ($numsections < 4) { + $numvisible = $numsections + 1; + } + } + foreach (@sections) { + $section_sel .= "