--- loncom/interface/lonfeedback.pm 2004/11/15 21:51:19 1.134 +++ loncom/interface/lonfeedback.pm 2005/02/14 01:37:45 1.149 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.134 2004/11/15 21:51:19 albertel Exp $ +# $Id: lonfeedback.pm,v 1.149 2005/02/14 01:37:45 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -68,13 +68,18 @@ sub discussion_visible { } sub list_discussion { - my ($mode,$status,$ressymb)=@_; + 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; @@ -84,7 +89,7 @@ sub list_discussion { my $cid=$ENV{'request.course.id'}; if ($ENV{'request.course.sec'}) { $crs.='_'.$ENV{'request.course.sec'}; - } + } $crs=~s/\_/\//g; unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); } unless ($ressymb) { return ''; } @@ -106,7 +111,7 @@ sub list_discussion { 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; @@ -122,7 +127,18 @@ sub list_discussion { &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 = $ENV{'form.sectionpick'}; + 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) { @@ -132,7 +148,6 @@ sub list_discussion { $prevread = $dischash{$lastkey}; } } - &Apache::lonnet::logthis("\n last read r symb ".$lastkey); # Get information about students and non-students in course for filtering display of posts my %roleshash = (); @@ -141,13 +156,18 @@ sub list_discussion { %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'; } - push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status; + if ($uname && $udom) { + push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status; + } } my ($classlist) = &Apache::loncoursedata::get_classlist( $ENV{'request.course.id'}, @@ -225,7 +245,7 @@ sub list_discussion { $discinfo{$visitkey} = $visit; &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,$ENV{'form.rolefilter'},$sectionpick,$statusfilter,$toggkey,$outputtarget); + &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; @@ -310,15 +330,26 @@ sub list_discussion { } elsif ($outputtarget eq 'export') { # Create temporary directory if this is an export my $now = time; - $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports'; - if (!-e $tempexport) { - mkdir($tempexport,0700); - } - $tempexport .= '/'.$now; - if (!-e $tempexport) { - mkdir($tempexport,0700); + if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) { + $tempexport = $$imsextras{'tempexport'}; + if (!-e $tempexport) { + mkdir($tempexport,0700); + } + $tempexport .= '/'.$$imsextras{'count'}; + if (!-e $tempexport) { + mkdir($tempexport,0700); + } + } else { + $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports'; + if (!-e $tempexport) { + mkdir($tempexport,0700); + } + $tempexport .= '/'.$now; + if (!-e $tempexport) { + mkdir($tempexport,0700); + } + $tempexport .= '/'.$ENV{'user.domain'}.'_'.$ENV{'user.name'}; } - $tempexport .= '/'.$ENV{'user.domain'}.'_'.$ENV{'user.name'}; if (!-e $tempexport) { mkdir($tempexport,0700); } @@ -360,17 +391,17 @@ imscp_v1p1.xsd http://www.imsglobal.org/ ''; if ($visible>2) { $discussion.=''; if ($newpostsflag) { if (!$markondisp) { - $discussion .=''; } @@ -398,7 +429,7 @@ imscp_v1p1.xsd http://www.imsglobal.org/ if ($numhidden > 0) { my $colspan = $maxdepth+1; $discussion.="\n".' -
'. - '  '. - '   -   '.&mt('Mark NEW posts no longer new').'  '; + $discussion .=''.&mt('Mark NEW posts no longer new').'  '; } else { $discussion .= ' 
'. - ' $b } keys %alldiscussion); } my $currdepth = 0; my $firstidx = $alldiscussion{$showposts[0]}; foreach (@showposts) { - unless (($sortposts eq 'thread') || ($sortposts eq 'ascdate' && $ENV{'environment.threadeddiscussion'}) || ($outputtarget eq 'export')) { + unless (($sortposts eq 'thread') || (($sortposts eq '') && ($ENV{'environment.threadeddiscussion'})) || ($outputtarget eq 'export')) { $alldiscussion{$_} = $_; } unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) { @@ -482,8 +512,8 @@ imscp_v1p1.xsd http://www.imsglobal.org/ $imsitems{$alldiscussion{$_}}{'isvisible'}.'" identifieref="RES-'.$ressymb.'-'.$alldiscussion{$_}.'">'. ''.$imsitems{$alldiscussion{$_}}{'title'}.''; $imsresources .= "\n". - ''. - ''."\n". + ''."\n". + ''."\n". $imsfiles{$alldiscussion{$_}}{$imsitems{$alldiscussion{$_}}{'currversion'}}."\n". ''; } @@ -540,13 +570,54 @@ END $discussion .= <   + $lt{'chgt'}?
END + if ($sortposts) { + my %sort_types = (); + my %role_types = (); + my %status_types = (); + &sort_filter_names(\%sort_types,\%role_types,\%status_types); + + $discussion .= ''.&mt('Sorted by').': '.$sort_types{$sortposts}.'
'; + if (defined($ENV{'form.totposters'})) { + $discussion .= &mt('Posts by').':'; + if ($totposters > 0) { + foreach my $poster (@posters) { + $poster =~ s/:/\@/; + $discussion .= ' '.$poster.','; + } + $discussion =~ s/,$//; + } else { + $discussion .= &mt('None selected'); + } + } else { + my $filterchoice =''; + if (@sectionpick > 0) { + $filterchoice = ''.&mt('sections').'- '.$ENV{'form.sectionpick'}; + $filterchoice .= '    '; + } + if (@rolefilter > 0) { + $filterchoice .= ''.&mt('roles').'-'; + foreach (@rolefilter) { + $filterchoice .= ' '.$role_types{$_}.','; + } + $filterchoice =~ s/,$//; + $filterchoice .= '
        '; + } + if ($statusfilter) { + $filterchoice .= ''.&mt('status').'- '.$status_types{$statusfilter}; + } + if ($filterchoice) { + $discussion .= ''.&mt('Filters').': '.$filterchoice; + } + $discussion .= '
'; + } + } if ($dischash{$toggkey}) { my $storebutton = &mt('Store read/unread changes'); $discussion.=''. @@ -579,27 +650,31 @@ END |; close($manifestfile); + if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) { + $discussion = $copyresult; + } else { #Create zip file in prtspool - my $imszipfile = '/prtspool/'. - $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. - time.'_'.rand(1000000000).'.zip'; + my $imszipfile = '/prtspool/'. + $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. + time.'_'.rand(1000000000).'.zip'; # zip can cause an sh launch which can pass along all of %ENV # which can be too large for /bin/sh to handle - my %oldENV=%ENV; - undef(%ENV); - my $cwd = &getcwd(); - my $imszip = '/home/httpd/'.$imszipfile; - chdir $tempexport; - open(OUTPUT, "zip -r $imszip * 2> /dev/null |"); - close(OUTPUT); - chdir $cwd; - %ENV=%oldENV; - undef(%oldENV); - $discussion .= 'Download the zip file from Discussion Posting Archive
'; - if ($copyresult) { - $discussion .= 'The following errors occurred during export -
'.$copyresult; + my %oldENV=%ENV; + undef(%ENV); + my $cwd = &getcwd(); + my $imszip = '/home/httpd/'.$imszipfile; + chdir $tempexport; + open(OUTPUT, "zip -r $imszip * 2> /dev/null |"); + close(OUTPUT); + chdir $cwd; + %ENV=%oldENV; + undef(%oldENV); + $discussion .= 'Download the zip file from Discussion Posting Archive
'; + if ($copyresult) { + $discussion .= 'The following errors occurred during export -
'.$copyresult; + } } } else { $discussion .= '
Unfortunately you will not be able to retrieve an archive of the discussion posts at this time, because there was a problem creating a manifest file.
'; @@ -639,42 +714,42 @@ to course faculty
Title: 

ENDDISCUSS - if ($ENV{'form.origpage'}) { - $discussion.=''."\n"; - foreach (@currnewattach) { - $discussion.=''."\n"; - } - } - $discussion.="\n"; - if ($outputtarget ne 'tex') { - $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode); - if (@currnewattach > 0) { - $newattachmsg .= 'New attachments
'; - if (@currnewattach > 1) { - $newattachmsg .= '
    '; - foreach my $item (@currnewattach) { - $item =~ m#.*/([^/]+)$#; - $newattachmsg .= '
  1. '.$1.'
  2. '."\n"; + if ($ENV{'form.origpage'}) { + $discussion.=''."\n"; + foreach (@currnewattach) { + $discussion.=''."\n"; + } + } + $discussion.="\n"; + if ($outputtarget ne 'tex') { + $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode); + if (@currnewattach > 0) { + $newattachmsg .= 'New attachments
    '; + if (@currnewattach > 1) { + $newattachmsg .= '
      '; + foreach my $item (@currnewattach) { + $item =~ m#.*/([^/]+)$#; + $newattachmsg .= '
    1. '.$1.'
    2. '."\n"; + } + $newattachmsg .= '
    '."\n"; + } else { + $currnewattach[0] =~ m#.*/([^/]+)$#; + $newattachmsg .= ''.$1.'
    '."\n"; } - $newattachmsg .= '
'."\n"; - } else { - $currnewattach[0] =~ m#.*/([^/]+)$#; - $newattachmsg .= ''.$1.'
'."\n"; } - } - $discussion.=$newattachmsg; - $discussion.=&generate_preview_button(); - } + $discussion.=$newattachmsg; + $discussion.=&generate_preview_button(); + } } - } else { - if (&discussion_open($status) && - &Apache::lonnet::allowed('pch', - $ENV{'request.course.id'}. - ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) { + } else { + if (&discussion_open($status) && + &Apache::lonnet::allowed('pch', + $ENV{'request.course.id'}. + ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) { if ($outputtarget ne 'tex') { $discussion.='
'. - ''. + ''. &mt('Post Discussion').'
'; } } @@ -684,7 +759,6 @@ ENDDISCUSS sub build_posting_display { my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$statusfilter,$toggkey,$outputtarget) = @_; - my @original=(); my @index=(); my $symb=&Apache::lonenc::check_decrypt($ressymb); @@ -697,6 +771,11 @@ sub build_posting_display { if ($prevread eq '0') { $prevread = $oldest-1; } + my ($skiptest,$rolematch,$roleregexp,$secregexp,$statusregexp); + if ($sortposts) { + ($skiptest,$roleregexp,$secregexp,$statusregexp) = &filter_regexp($rolefilter,$sectionpick,$statusfilter); + $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp; + } for (my $id=1;$id<=$contrib{'version'};$id++) { my $idx=$id; my $posttime = $contrib{$idx.':timestamp'}; @@ -709,7 +788,7 @@ sub build_posting_display { my $origindex='0.'; my $numoldver=0; if ($contrib{$idx.':replyto'}) { - if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) { + if ( (($ENV{'environment.threadeddiscussion'}) && ($sortposts eq '')) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) { # this is a follow-up message $original[$idx]=$original[$contrib{$idx.':replyto'}]; $$depth[$idx]=$$depth[$contrib{$idx.':replyto'}]+1; @@ -904,7 +983,7 @@ sub build_posting_display { } if ($outputtarget eq 'export' || $message) { my $thisindex=$idx; - if ( (($ENV{'environment.threadeddiscussion'}) && (($sortposts eq '') || ($sortposts eq 'ascdate'))) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) { + if ( (($ENV{'environment.threadeddiscussion'}) && ($sortposts eq '')) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) { $thisindex=$origindex.substr('00'.$$replies[$$depth[$idx]],-2,2); } $$alldiscussion{$thisindex}=$idx; @@ -945,48 +1024,33 @@ sub build_posting_display { my $uname = $contrib{$idx.':sendername'}; my $udom = $contrib{$idx.':senderdomain'}; my $poster = $uname.':'.$udom; - my $rolematch = ''; - my $skiptest = 1; - if ($totposters > 0) { - if (grep/^$poster$/,@{$posters}) { - $$shown{$idx} = 1; - } - } else { - if ($rolefilter) { - if ($rolefilter eq 'all') { - $rolematch = '([^:]+)'; - } else { - $rolematch = $rolefilter; - $skiptest = 0; - } - } - if ($sectionpick) { - if ($sectionpick eq 'all') { - $rolematch .= ':([^:]*)'; - } else { - $rolematch .= ':'.$sectionpick; - $skiptest = 0; - } - } - if ($statusfilter) { - if ($statusfilter eq 'all') { - $rolematch .= ':([^:]+)'; - } else { - $rolematch .= ':'.$statusfilter; - $skiptest = 0; + if (defined($ENV{'form.totposters'})) { + if ($totposters == 0) { + $$shown{$idx} = 0; + } elsif ($totposters > 0) { + if (grep/^$poster$/,@{$posters}) { + $$shown{$idx} = 1; } } + } elsif ($sortposts) { if ($skiptest) { $$shown{$idx} = 1; } else { foreach my $role (@{$$roleinfo{$poster}}) { - &Apache::lonnet::logthis("\n rolematch $rolematch\nrole $role"); - if ($role =~ m/^$rolematch$/) { + if ($role =~ /^cc:/) { + my $cc_regexp = $roleregexp.':[^:]*:'.$statusregexp; + if ($role =~ /$cc_regexp/) { + $$shown{$idx} = 1; + last; + } + } elsif ($role =~ /^$rolematch$/) { $$shown{$idx} = 1; last; } } } + } else { + $$shown{$idx} = 1; } } unless ($$notshown{$idx} == 1) { @@ -1036,6 +1100,60 @@ sub build_posting_display { } } +sub filter_regexp { + my ($rolefilter,$sectionpick,$statusfilter) = @_; + my ($roleregexp,$secregexp,$statusregexp); + my $skiptest = 1; + if (@{$rolefilter} > 0) { + my @okrolefilter = (); + foreach (@{$rolefilter}) { + unless ($_ eq '') { + push @okrolefilter, $_; + } + } + if (@okrolefilter > 0) { + if (grep/^all$/,@okrolefilter) { + $roleregexp='[^:]+'; + } else { + if (@okrolefilter == 1) { + $roleregexp=$okrolefilter[0]; + } else { + $roleregexp='('.join('|',@okrolefilter).')'; + } + $skiptest = 0; + } + } + } + if (@{$sectionpick} > 0) { + my @oksectionpick = (); + foreach (@{$sectionpick}) { + unless ($_ eq '') { + push @oksectionpick, $_; + } + } + if ((@oksectionpick > 0) && (!grep/^all$/,@oksectionpick)) { + if (@oksectionpick == 1) { + $secregexp = $oksectionpick[0]; + } else { + $secregexp .= '('.join('|',@oksectionpick).')'; + } + $skiptest = 0; + } else { + $secregexp .= '[^:]*'; + } + } + if (defined($statusfilter) && $statusfilter ne '') { + if ($statusfilter eq 'all') { + $statusregexp = '[^:]+'; + } else { + $statusregexp = $statusfilter; + $skiptest = 0; + } + } + return ($skiptest,$roleregexp,$secregexp,$statusregexp); +} + + sub get_post_contents { my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_; my $discussion = ''; @@ -1475,7 +1593,8 @@ END sub print_display_options { my ($r,$symb,$previous,$dispchgA,$dispchgB,$markchg,$toggchg,$feedurl) = @_; - &dewrapper(\$feedurl); + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; my $function = &Apache::loncommon::get_users_function(); my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg', @@ -1656,6 +1775,7 @@ $lt{'sdpf'}
$lt{'prca'}
  1. $l

    + @@ -1674,35 +1794,21 @@ END sub print_sortfilter_options { my ($r,$symb,$previous,$feedurl) = @_; - &dewrapper(\$feedurl); + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + + &Apache::lonenc::check_encrypt(\$symb); 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; + + $numsections = &Apache::loncommon::get_sections($ENV{'course.'.$ENV{'request.course.id'}.'.domain'},$ENV{'course.'.$ENV{'request.course.id'}.'.num'},\%sectioncount); + + if ($ENV{'request.course.sec'} !~ /^\s*$/) { #Restrict section choice to current section + @sections = ('all',$ENV{'request.course.sec'}); + $numvisible = 2; } else { @sections = sort {$a cmp $b} keys(%sectioncount); unshift(@sections,'all'); # Put 'all' at the front of the list @@ -1724,19 +1830,49 @@ sub print_sortfilter_options { 'diop' => 'Display Options', 'curr' => 'Current setting ', 'actn' => 'Action', - 'prca' => 'Options can be set that control the sort order of the posts, in addition to which posts are displayed.', + 'prca' => 'Set options that control the sort order of posts, and/or which posts are displayed.', 'soor' => 'Sort order', - 'disp' => 'Specific user roles', - 'actv' => 'Specific role status', + 'spur' => 'Specific user roles', + 'sprs' => 'Specific role status', 'spse' => 'Specific sections', 'psub' => 'Pick specific users (by name)', 'shal' => 'Show a list of current posters' ); + + my %sort_types = (); + my %role_types = (); + my %status_types = (); + &sort_filter_names(\%sort_types,\%role_types,\%status_types); + $r->print(< $lt{'diso'} + $bodytag
    @@ -1746,47 +1882,48 @@ $bodytag $lt{'soor'}   - $lt{'disp'} + $lt{'sprs'}   - $lt{'actv'} + $lt{'spur'}   $lt{'spse'}   $lt{'psub'} - +   - - +
    @@ -1811,15 +1948,14 @@ END sub print_showposters { my ($r,$symb,$previous,$feedurl,$sortposts) = @_; -# backward compatibility (bulletin boards used to be 'wrapped') - my $ressymb=&wrap_symb($symb); + &Apache::lonenc::check_encrypt(\$symb); my $crs='/'.$ENV{'request.course.id'}; if ($ENV{'request.course.sec'}) { $crs.='_'.$ENV{'request.course.sec'}; } $crs=~s/\_/\//g; my $seeid=&Apache::lonnet::allowed('rin',$crs); - my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'}, + my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); my %namesort = (); @@ -1988,7 +2124,7 @@ ENDFAILREDIR } sub redirect_back { - my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$secpick,$numpicks) = @_; + my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$numpicks) = @_; my $sorttag = ''; my $roletag = ''; my $statustag = ''; @@ -1997,6 +2133,9 @@ sub redirect_back { my $qrystr = ''; my $prevtag = ''; + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + &dewrapper(\$feedurl); if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' }; if ($previous > 0) { @@ -2016,18 +2155,41 @@ sub redirect_back { $feedurl .= '?'.$sortqry; } $sorttag = ''; - if ( (defined($numpicks)) && ($numpicks > 0) ) { + if (defined($numpicks)) { my $userpickqry = 'totposters='.$numpicks; $feedurl .= '&'.$userpickqry; $userpicktag = ''; } else { - my $roleqry = 'rolefilter='.$rolefilter; - $feedurl .= '&'.$roleqry; - $roletag = ''; + if (ref($sectionpick) eq 'ARRAY') { + $feedurl .= '§ionpick='; + $sectag .= ''; + } else { + $feedurl .= '§ionpick='.$sectionpick; + $sectag = ''; + } + if (ref($rolefilter) eq 'ARRAY') { + $feedurl .= '&rolefilter='; + $roletag .= ''; + } else { + $feedurl .= '&rolefilter='.$rolefilter; + $roletag = ''; + } $feedurl .= '&statusfilter='.$statusfilter; $statustag =''; - $feedurl .= '§ionpick='.$secpick; - $sectag = ''; } } $feedurl=&Apache::lonenc::check_encrypt($feedurl); @@ -2084,7 +2246,7 @@ ENDNOREDIRTWO } sub screen_header { - my ($feedurl) = @_; + my ($feedurl,$symb) = @_; my $msgoptions=''; my $discussoptions=''; unless (($ENV{'form.replydisc'}) || ($ENV{'form.editdisc'})) { @@ -2110,7 +2272,7 @@ sub screen_header { } } if ($ENV{'request.course.id'}) { - if (&discussion_open() && + if (&discussion_open(undef,$symb) && &Apache::lonnet::allowed('pch', $ENV{'request.course.id'}. ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) { @@ -2120,11 +2282,11 @@ sub screen_header { $discussoptions.='
    '. &mt('Anonymous contribution to course discussion of resource'). ' ('.&mt('name only visible to course faculty').')'; - } + } } - if ($msgoptions) { $msgoptions='

    '.&mt('Sending Messages').'

    '.$msgoptions; } + if ($msgoptions) { $msgoptions='

    '.&mt('Sending Messages').'

    '.$msgoptions; } if ($discussoptions) { - $discussoptions='

    '.&mt('Discussion Contributions').'

    '.$discussoptions; } + $discussoptions='

    '.&mt('Discussion Contributions').'

    '.$discussoptions; } return $msgoptions.$discussoptions; } @@ -2396,6 +2558,8 @@ sub adddiscuss { sub show_preview { my $r=shift; + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; my $message=&clear_out_html($ENV{'form.comment'}); $message=~s/\n/\
    /g; $message=&Apache::lonspeller::markeduptext($message); @@ -2436,6 +2600,7 @@ sub modify_attachments { if ($idx) { &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold); } + &Apache::lonenc::check_encrypt(\$symb); $r->print(< @@ -2716,7 +2881,34 @@ sub has_discussion { } } return; -} +} + +sub sort_filter_names { + my ($sort_types,$role_types,$status_types) = @_; + %{$sort_types} = ( + ascdate => 'Date order - oldest first', + descdate => 'Date order - newest first', + thread => 'Threaded', + subject => 'By subject', + username => 'By domain and username', + lastfirst => 'By last name, first name' + ); + %{$role_types} = ( + all => 'All roles', + st => 'Students', + cc => 'Course Coordinators', + in => 'Instructors', + ta => 'TAs', + ep => 'Exam proctors', + ad => 'Administrators', + cr => 'Custom roles' + ); + %{$status_types} = ( + all => 'Roles of any status', + Active => 'Only active roles', + Expired => 'Only inactive roles' + ); +} sub handler { my $r = shift; @@ -2729,7 +2921,8 @@ sub handler { # --------------------------- Get query string for limited number of parameters &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','threadedon','threadedoff','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortfilter','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']); + ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']); + if ($ENV{'form.discsymb'}) { my ($symb,$feedurl) = &get_feedurl_and_clean_symb($ENV{'form.discsymb'}); my $readkey = $symb.'_read'; @@ -2752,8 +2945,6 @@ sub handler { &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', \%readinghash,$ENV{'user.domain'},$ENV{'user.name'}); } - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'
    ', '0','0','',$ENV{'form.previous'},'','','',); return OK; @@ -2762,7 +2953,7 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions'); - $r->print (<print(< Post Versions @@ -2793,16 +2984,12 @@ END return OK; } if ($ENV{'form.posterlist'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.applysort'}); &print_showposters($r,$symb,$ENV{'form.previous'},$feedurl, $ENV{'form.sortposts'}); return OK; } if ($ENV{'form.userpick'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; my @posters = &Apache::loncommon::get_env_multiple('form.stuinfo'); my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.userpick'}); my $numpicks = @posters; @@ -2816,18 +3003,14 @@ END return OK; } if ($ENV{'form.applysort'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.applysort'}); &redirect_back($r,$feedurl,&mt('Changed sort/filter').'
    ','0','0', '',$ENV{'form.previous'},$ENV{'form.sortposts'}, $ENV{'form.rolefilter'},$ENV{'form.statusfilter'}, - $ENV{'form.secpick'}); + $ENV{'form.sectionpick'}); return OK; - } elsif ($ENV{'form.sortfilter'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.sortfilter'}); + } elsif ($ENV{'form.cmd'} eq 'sortfilter') { + my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.symb'}); &print_sortfilter_options($r,$symb,$ENV{'form.previous'},$feedurl); return OK; } elsif ($ENV{'form.navtime'}) { @@ -2889,8 +3072,6 @@ $textline ENDREDIR return OK; } elsif ($ENV{'form.modifydisp'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.modifydisp'}); my ($dispchgA,$dispchgB,$markchg,$toggchg) = split(/_/,$ENV{'form.changes'}); @@ -2900,86 +3081,41 @@ ENDREDIR } elsif ($ENV{'form.markondisp'} || $ENV{'form.markonread'} || $ENV{'form.allposts'} || $ENV{'form.onlyunread'} || $ENV{'form.onlyunmark'} || $ENV{'form.toggoff'} || - $ENV{'form.toggon'} ) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $feedurl; - if ( ($ENV{'form.toggoff'}) || ($ENV{'form.toggon'}) ) { + $ENV{'form.toggon'} || $ENV{'form.markread'}) { + my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.symb'}); + my %discinfo; # ------------------------ Modify setting for read/unread toggle for each post - my $symb=$ENV{'form.toggoff'}?$ENV{'form.toggoff'}:$ENV{'form.toggon'}; - ($symb,$feedurl)=&get_feedurl_and_clean_symb($symb); - my %discinfo; - $discinfo{$symb.'_readtoggle'}=1; - if ($ENV{'form.toggoff'}) { $discinfo{$symb.'_readtoggle'}=0; } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', - \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } - if (($ENV{'form.markondisp'}) || ($ENV{'form.markonread'})) { + if ($ENV{'form.toggoff'}) { $discinfo{$symb.'_readtoggle'}=0; } + if ($ENV{'form.toggon'}) { $discinfo{$symb.'_readtoggle'}=1; } # --------- Modify setting for identification of 'NEW' posts in this discussion - my $symb=$ENV{'form.markondisp'}?$ENV{'form.markondisp'}:$ENV{'form.markonread'}; - ($symb,$feedurl)=&get_feedurl_and_clean_symb($symb); - my %discinfo; - my $lastkey = $symb.'_lastread'; - my $ondispkey = $symb.'_markondisp'; - if ($ENV{'form.markondisp'}) { - $discinfo{$lastkey} = time; - $discinfo{$ondispkey} = 1; - } elsif ($ENV{'form.markonread'}) { - if ( $ENV{'form.previous'} > 0 ) { - $discinfo{$lastkey} = $ENV{'form.previous'}; - } - $discinfo{$ondispkey} = 0; - } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', - \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); + if ($ENV{'form.markondisp'}) { + $discinfo{$symb.'_lastread'} = time; + $discinfo{$symb.'_markondisp'} = 1; + } + if ($ENV{'form.markonread'}) { + if ( $ENV{'form.previous'} > 0 ) { + $discinfo{$symb.'_lastread'} = $ENV{'form.previous'}; + } + $discinfo{$symb.'_markondisp'} = 0; } - if ($ENV{'form.allposts'} || $ENV{'form.onlyunread'} || - $ENV{'form.onlyunmark'}) { # --------------------------------- Modify display setting for this discussion - my $symb; - if ($ENV{'form.allposts'}) { - $symb = $ENV{'form.allposts'}; - } elsif ($ENV{'form.onlyunread'}) { - $symb = $ENV{'form.onlyunread'}; - } else { - $symb = $ENV{'form.onlyunmark'}; - } - ($symb,$feedurl)=&get_feedurl_and_clean_symb($symb); - my %discinfo; - if ($ENV{'form.allposts'}) { - $discinfo{$symb.'_showonlyunread'} = 0; - $discinfo{$symb.'_showonlyunmark'} = 0; - } elsif ($ENV{'form.onlyunread'}) { - $discinfo{$symb.'_showonlyunread'} = 1; - } else { - $discinfo{$symb.'_showonlyunmark'} = 1; - } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', - \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); + if ($ENV{'form.allposts'}) { + $discinfo{$symb.'_showonlyunread'} = 0; + $discinfo{$symb.'_showonlyunmark'} = 0; } + if ($ENV{'form.onlyunread'}) { $discinfo{$symb.'_showonlyunread'} = 1; } + if ($ENV{'form.onlyunmark'}) { $discinfo{$symb.'_showonlyunmark'} = 1; } +# ----------------------------------------------------- Mark new posts not NEW + if ($ENV{'form.markread'}) { $discinfo{$symb.'_lastread'} = time; } + &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', + \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); my $previous=$ENV{'form.previous'}; if ($ENV{'form.markondisp'}) { $previous=undef; } &redirect_back($r,$feedurl,&mt('Changed display status').'
    ', '0','0','',$previous); return OK; - } elsif ($ENV{'form.markread'}) { -# ----------------------------------------------------- Mark new posts not NEW - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.markread'}); - &Apache::lonnet::logthis("\n last read w symb ".$symb); - my %discinfo; - $discinfo{$symb.'_lastread'} = time; - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', - \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - &redirect_back($r,$feedurl,&mt('Changed reading status').'
    ', - '0','0'); - return OK; } elsif (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) { # ----------------------------------------------------------------- Hide/unhide - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'}; my ($symb,$idx)=split(/\:\:\:/,$entry); ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb); @@ -3017,43 +3153,37 @@ ENDREDIR &redirect_back($r,$feedurl,&mt('Changed discussion status').'
    ', '0','0','',$ENV{'form.previous'}); - } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb; - if ($ENV{'form.threadedon'}) { - $symb=$ENV{'form.threadedon'}; + return OK; + } elsif ($ENV{'form.cmd'}=~/^(threadedoff|threadedon)$/) { + my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.symb'}); + if ($ENV{'form.cmd'} eq 'threadedon') { &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'}); &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on'); } else { - $symb=$ENV{'form.threadedoff'}; &Apache::lonnet::del('environment',['threadeddiscussion']); &Apache::lonnet::delenv('environment\.threadeddiscussion'); } - my ($symb,$feedurl)=&get_feedurl_and_clean_symb($symb); &redirect_back($r,$feedurl,&mt('Changed discussion view mode').'
    ', '0','0','',$ENV{'form.previous'}); + return OK; } elsif ($ENV{'form.deldisc'}) { # --------------------------------------------------------------- Hide for good - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.deldisc'}); ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb); my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - my %newhash=('deleted' => $contrib{'deleted'}.".$idx."); - &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - &redirect_back($r,$feedurl,&mt('Changed discussion status').'
    ', - '0','0','',$ENV{'form.previous'}); + my %newhash=('deleted' => $contrib{'deleted'}.".$idx."); + &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + &redirect_back($r,$feedurl,&mt('Changed discussion status').'
    ', + '0','0','',$ENV{'form.previous'}); + return OK; } elsif ($ENV{'form.preview'}) { # -------------------------------------------------------- User wants a preview - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; &show_preview($r); + return OK; } elsif ($ENV{'form.attach'}) { # -------------------------------------------------------- Work on attachments &Apache::loncommon::content_type($r,'text/html'); @@ -3065,7 +3195,7 @@ ENDREDIR unless (length($ENV{'form.addnewattach'})>131072) { my $subdir = 'feedback/'.$ENV{'form.timestamp'}; my $newattachment=&Apache::lonnet::userfileupload('addnewattach',undef,$subdir); - push @currnewattach, $newattachment; + push @currnewattach, $newattachment; } } my $attachmenturls; @@ -3079,12 +3209,7 @@ ENDREDIR } &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx, $attachmenturls); - } elsif ($ENV{'form.chgreads'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ENV{'form.chgreads'}); - &redirect_back($r,&Apache::lonnet::clutter($url), - &mt('Changed read status').'
    ','0','0'); + return OK; } elsif ($ENV{'form.export'}) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; @@ -3144,9 +3269,6 @@ ENDREDIR return OK; } # Go ahead with feedback, no ambiguous reference - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - unless ( ( ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:) @@ -3156,12 +3278,16 @@ ENDREDIR || ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/)) ) { + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; # Unable to give feedback &no_redirect_back($r,$feedurl); } # --------------------------------------------------- Print login screen header unless ($ENV{'form.sendit'}) { - my $options=&screen_header($feedurl); + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + my $options=&screen_header($feedurl,$symb); if ($options) { &mail_screen($r,$feedurl,$options); } else {