--- loncom/interface/lonfeedback.pm 2004/09/15 20:35:16 1.99.2.8
+++ loncom/interface/lonfeedback.pm 2004/12/23 14:00:58 1.147
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Feedback
#
-# $Id: lonfeedback.pm,v 1.99.2.8 2004/09/15 20:35:16 albertel Exp $
+# $Id: lonfeedback.pm,v 1.147 2004/12/23 14:00:58 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -36,15 +36,20 @@ use Apache::loncommon();
use Apache::lontexconvert();
use Apache::lonlocal; # must not have ()
use Apache::lonhtmlcommon();
+use Apache::lonnavmaps;
+use Apache::lonenc();
+use HTML::LCParser();
+use Apache::lonspeller();
+use Cwd;
sub discussion_open {
- my ($status)=@_;
+ my ($status,$symb)=@_;
if (defined($status) &&
!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
|| $status eq 'OPEN')) {
return 0;
}
- my $close=&Apache::lonnet::EXT('resource.0.discussend');
+ my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb);
if (defined($close) && $close ne '' && $close < time) {
return 0;
}
@@ -56,53 +61,85 @@ sub discussion_visible {
if (not &discussion_open($status)) {
my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');
if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden)) {
- return 0;
+ if (!$ENV{'request.role.adv'}) { return 0; }
}
}
return 1;
}
sub list_discussion {
- my ($mode,$status,$symb)=@_;
-
+ my ($mode,$status,$ressymb,$imsextras)=@_;
my $outputtarget=$ENV{'form.grade_target'};
+ if (defined($ENV{'form.export'})) {
+ if($ENV{'form.export'}) {
+ $outputtarget = 'export';
+ }
+ }
+ if (defined($imsextras)) {
+ if ($$imsextras{'caller'} eq 'imsexport') {
+ $outputtarget = 'export';
+ }
+ }
if (not &discussion_visible($status)) { return ''; }
my @bgcols = ("#cccccc","#eeeeee");
my $discussiononly=0;
if ($mode eq 'board') { $discussiononly=1; }
unless ($ENV{'request.course.id'}) { return ''; }
my $crs='/'.$ENV{'request.course.id'};
+ my $cid=$ENV{'request.course.id'};
if ($ENV{'request.course.sec'}) {
$crs.='_'.$ENV{'request.course.sec'};
- }
- $crs=~s/\_/\//g;
- unless ($symb) {
- $symb=&Apache::lonnet::symbread();
- }
- unless ($symb) { return ''; }
-
-# backward compatibility (bulletin boards used to be 'wrapped')
- my $ressymb=$symb;
- if ($mode eq 'board') {
- unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
- $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
- }
}
+ $crs=~s/\_/\//g;
+ unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }
+ unless ($ressymb) { return ''; }
+ $ressymb=&wrap_symb($ressymb);
+ my $encsymb=&Apache::lonenc::check_encrypt($ressymb);
+ my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
+ && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form)$/));
+
+ my %usernamesort = ();
+ my %namesort =();
+ my %subjectsort = ();
# Get discussion display settings for this discussion
my $lastkey = $ressymb.'_lastread';
my $showkey = $ressymb.'_showonlyunread';
+ my $markkey = $ressymb.'_showonlyunmark',
+ 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 $userpickkey = $ressymb.'_userpick';
+ my $toggkey = $ressymb.'_readtoggle';
+ my $readkey = $ressymb.'_read';
+ $ressymb=$encsymb;
+ my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$ENV{'user.domain'},$ENV{'user.name'});
my %discinfo = ();
my $showonlyunread = 0;
+ my $showunmark = 0;
my $markondisp = 0;
my $prevread = 0;
my $previous = 0;
+ my $visit = 0;
my $newpostsflag = 0;
+ my @posters = split/\&/,$dischash{$userpickkey};
# 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','rolefilter','statusfilter','sectionpick','totposters']);
+ my $sortposts = $ENV{'form.sortposts'};
+ my $statusfilter = $ENV{'form.statusfilter'};
+ my @sectionpick = ();
+ if ($ENV{'form.sectionpick'} =~ /,/) {
+ @sectionpick = split/,/,$ENV{'form.sectionpick'};
+ } else {
+ $sectionpick[0] = $ENV{'form.sectionpick'};
+ }
+ my @rolefilter = ();
+ if ($ENV{'form.rolefilter'} =~ /,/) {
+ @rolefilter = split/,/,$ENV{'form.rolefilter'};
+ } else {
+ $rolefilter[0] = $ENV{'form.rolefilter'};
+ }
+ my $totposters = $ENV{'form.totposters'};
$previous = $ENV{'form.previous'};
if ($previous > 0) {
$prevread = $previous;
@@ -112,6 +149,39 @@ sub list_discussion {
}
}
+# Get information about students and non-students in course for filtering display of posts
+ my %roleshash = ();
+ my %roleinfo = ();
+ if ($ENV{'form.rolefilter'}) {
+ %roleshash = &Apache::lonnet::dump('nohist_userroles',$ENV{'course.'.$ENV{'request.course.id'}.'.domain'},$ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ foreach (keys %roleshash) {
+ my ($role,$uname,$udom,$sec) = split/:/,$_;
+ if ($role =~ /^cr/) {
+ $role = 'cr';
+ }
+ my ($end,$start) = split/:/,$roleshash{$_};
+ my $now = time;
+ my $status = 'Active';
+ if (($now < $start) || ($end > 0 && $now > $end)) {
+ $status = 'Expired';
+ }
+ if ($uname && $udom) {
+ push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status;
+ }
+ }
+ 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();
+ while (my ($student,$data) = each %$classlist) {
+ my ($section,$status) = ($data->[$sec_index],
+ $data->[$status_index]);
+ push @{$roleinfo{$student}}, 'st:'.$section.':'.$status;
+ }
+ }
+
# Get discussion display default settings for user
if ($ENV{'environment.discdisplay'} eq 'unread') {
$showonlyunread = 1;
@@ -122,33 +192,45 @@ sub list_discussion {
# Override user's default if user specified display setting for this discussion
if (defined($dischash{$ondispkey})) {
- unless ($dischash{$showkey} eq '') {
- $markondisp = $dischash{$ondispkey};
- }
+ unless ($dischash{$ondispkey} eq '') {
+ $markondisp = $dischash{$ondispkey};
+ }
}
if ($markondisp) {
$discinfo{$lastkey} = time;
}
if (defined($dischash{$showkey})) {
- unless ($dischash{$showkey} eq '') {
- $showonlyunread = $dischash{$showkey};
- }
+ unless ($dischash{$showkey} eq '') {
+ $showonlyunread = $dischash{$showkey};
+ }
}
+ if (defined($dischash{$markkey})) {
+ unless ($dischash{$markkey} eq '') {
+ $showunmark = $dischash{$markkey};
+ }
+ }
+
+ if (defined($dischash{$visitkey})) {
+ unless ($dischash{$visitkey} eq '') {
+ $visit = $dischash{$visitkey};
+ }
+ }
+ $visit ++;
+
my $seeid=&Apache::lonnet::allowed('rin',$crs);
- my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
- && ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
my @discussionitems=();
- my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ my %shown = ();
+ my @posteridentity=();
+
+ my $current=0;
my $visible=0;
my @depth=();
- my @original=();
- my @index=();
- my @replies=();
+ my @replies = ();
my %alldiscussion=();
+ my %imsitems=();
+ my %imsfiles=();
my %notshown = ();
my %newitem = ();
my $maxdepth=0;
@@ -158,163 +240,19 @@ sub list_discussion {
$ENV{'environment.remote'} eq 'off' ) {
$target='target="LONcom"';
}
-
+
my $now = time;
- if (%discinfo) {
- &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
- }
+ $discinfo{$visitkey} = $visit;
- if ($contrib{'version'}) {
- my $oldest = $contrib{'1:timestamp'};
- if ($prevread eq '0') {
- $prevread = $oldest-1;
- }
- for (my $id=1;$id<=$contrib{'version'};$id++) {
- my $idx=$id;
- my $posttime = $contrib{$idx.':timestamp'};
- if ($prevread <= $posttime) {
- $newpostsflag = 1;
- }
- my $hidden=($contrib{'hidden'}=~/\.$idx\./);
- my $deleted=($contrib{'deleted'}=~/\.$idx\./);
- my $origindex='0.';
- if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) {
-# 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]; }
- } else {
-# this is an original message
- $original[$idx]=0;
- $depth[$idx]=0;
- }
- if ($replies[$depth[$idx]]) {
- $replies[$depth[$idx]]++;
- } else {
- $replies[$depth[$idx]]=1;
- }
- unless ((($hidden) && (!$seeid)) || ($deleted)) {
- $visible++;
- my $message=$contrib{$idx.':message'};
- $message=~s/\n/\
/g;
- $message=&Apache::lontexconvert::msgtexconverted($message);
- my $subject=$contrib{$idx.':subject'};
- if (defined($subject)) {
- $subject=~s/\n/\
/g;
- $subject=&Apache::lontexconvert::msgtexconverted($subject);
- }
- if ($contrib{$idx.':attachmenturl'}) {
- my ($fname)
- =($contrib{$idx.':attachmenturl'}=~m|/([^/]+)$|);
- &Apache::lonnet::allowuploaded('/adm/feedback',
- $contrib{$idx.':attachmenturl'});
- $message.='
'.&mt('Attachment'). - ': '. - $fname.'
'; - } - if ($message) { - 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'}); - ($$screenname,$$plainname)=($$contrib{$idx.':screenname'}, - $$contrib{$idx.':plainname'}); - my $sender=&mt('Anonymous'); - if ((!$contrib{$idx.':anonymous'}) || ($seeid)) { - $sender=&Apache::loncommon::aboutmewrapper( - $plainname, - $contrib{$idx.':sendername'}, - $contrib{$idx.':senderdomain'}).' ('. - $contrib{$idx.':sendername'}.' at '. - $contrib{$idx.':senderdomain'}.')'; - if ($contrib{$idx.':anonymous'}) { - $sender.=' ['.&mt('anonymous').'] '. - $screenname; - } - if ($seeid) { - if ($hidden) { - $sender.=' '.&mt('Make Visible').''; - } else { - $sender.=' '.&mt('Hide').''; - } - $sender.=' '.&mt('Delete').''; - } - } else { - if ($screenname) { - $sender=''.$screenname.''; - } - } - if (&discussion_open($status) && - &Apache::lonnet::allowed('pch', - $ENV{'request.course.id'}. - ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) { - $sender.=' '.&mt('Reply').''; - } - my $vgrlink; - if ($viewgrades) { - $vgrlink=&Apache::loncommon::submlink('Submissions', - $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb); - } -#figure out at what position this needs to print - my $thisindex=$idx; - if ($ENV{'environment.threadeddiscussion'}) { - $thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2); - } - $alldiscussion{$thisindex}=$idx; - $index[$idx]=$thisindex; - my $spansize = 2; - if ($showonlyunread && $prevread > $posttime) { - $notshown{$idx} = 1; - } else { - if ($prevread > 0 && $prevread <= $posttime) { - $newitem{$idx} = 1; - $discussionitems[$idx] .= ' -NEW | '; - } else { - $newitem{$idx} = 0; - $discussionitems[$idx] .= ' -
'; - } - $discussionitems[$idx] .= ' | '. - ''.$subject.' '. - $sender.' '.$vgrlink.' ('. - localtime($posttime).') |
'.$message.''; - } - } - } - } - } + &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); + &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget); my $discussion=''; + my $manifestfile; + my $manifestok=0; + my $tempexport; + my $imsresources; + my $copyresult; my $function = &Apache::loncommon::get_users_function(); my $color = &Apache::loncommon::designparm($function.'.tabbg', @@ -323,22 +261,31 @@ sub list_discussion { 'cuse' => 'Current discussion settings', 'allposts' => 'All posts', 'unread' => 'New posts only', + 'unmark' => 'Unread only', 'ondisp' => 'Once displayed', - 'onmark' => 'Once marked read', + 'onmark' => 'Once marked not NEW', + 'toggoff' => 'Off', + 'toggon' => 'On', 'disa' => 'Posts to be displayed', 'npce' => 'Posts cease to be marked "NEW"', + 'epcb' => 'Each post can be toggled read/unread', 'chgt' => 'Change', 'disp' => 'Display', 'nolo' => 'Not new', + 'togg' => 'Toggle read/unread', ); my $currdisp = $lt{'allposts'}; my $currmark = $lt{'onmark'}; + my $currtogg = $lt{'toggoff'}; my $dispchange = $lt{'unread'}; my $markchange = $lt{'ondisp'}; + my $toggchange = $lt{'toggon'}; my $chglink = '/adm/feedback?modifydisp='.$ressymb; - my $displink = 'onlyunread'; + my $displinkA = 'onlyunread'; + my $displinkB = 'onlyunmark'; my $marklink = 'markondisp'; + my $togglink = 'toggon'; if ($markondisp) { $currmark = $lt{'ondisp'}; @@ -349,10 +296,24 @@ sub list_discussion { if ($showonlyunread) { $currdisp = $lt{'unread'}; $dispchange = $lt{'allposts'}; - $displink = 'allposts'; + $displinkA = 'allposts'; + } + + if ($showunmark) { + $currdisp = $lt{'unmark'}; + $dispchange = $lt{'unmark'}; + $displinkA='allposts'; + $displinkB='onlyunread'; + $showonlyunread = 0; } + + if ($dischash{$toggkey}) { + $currtogg = $lt{'toggon'}; + $toggchange = $lt{'toggoff'}; + $togglink = 'toggoff'; + } - $chglink .= '&changes='.$displink.'_'.$marklink; + $chglink .= '&changes='.$displinkA.'_'.$displinkB.'_'.$marklink.'_'.$togglink; if ($newpostsflag) { $chglink .= '&previous='.$prevread; @@ -360,27 +321,102 @@ sub list_discussion { if ($visible) { # Print the discusssion - if ($outputtarget ne 'tex') { + if ($outputtarget eq 'tex') { + $discussion.='