--- loncom/interface/lonfeedback.pm 2004/08/31 18:31:31 1.121 +++ loncom/interface/lonfeedback.pm 2004/12/09 21:58:29 1.145 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.121 2004/08/31 18:31:31 albertel Exp $ +# $Id: lonfeedback.pm,v 1.145 2004/12/09 21:58:29 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,18 +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; } @@ -59,20 +61,20 @@ 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)=@_; my $outputtarget=$ENV{'form.grade_target'}; if (defined($ENV{'form.export'})) { if($ENV{'form.export'}) { $outputtarget = 'export'; } - } + } if (not &discussion_visible($status)) { return ''; } my @bgcols = ("#cccccc","#eeeeee"); my $discussiononly=0; @@ -82,22 +84,18 @@ sub list_discussion { 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 ''; } + $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 = (); -# 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|; - } - } # Get discussion display settings for this discussion my $lastkey = $ressymb.'_lastread'; @@ -108,7 +106,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; @@ -123,9 +121,19 @@ sub list_discussion { # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts. &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','totposters']); my $sortposts = $ENV{'form.sortposts'}; - my $rolefilter = $ENV{'form.rolefilter'}; 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) { @@ -139,17 +147,22 @@ sub list_discussion { # Get information about students and non-students in course for filtering display of posts my %roleshash = (); my %roleinfo = (); - if ($rolefilter) { + 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'; } - 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'}, @@ -165,40 +178,43 @@ sub list_discussion { } # Get discussion display default settings for user - my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'}); - my $discdisplay=$userenv{'discdisplay'}; - if ($discdisplay eq 'unread') { + if ($ENV{'environment.discdisplay'} eq 'unread') { $showonlyunread = 1; } - my $discmarkread=$userenv{'discmarkread'}; - if ($discmarkread eq 'ondisp') { + if ($ENV{'environment.discmarkread'} eq 'ondisp') { $markondisp = 1; } # Override user's default if user specified display setting for this discussion if (defined($dischash{$ondispkey})) { - $markondisp = $dischash{$ondispkey}; + unless ($dischash{$ondispkey} eq '') { + $markondisp = $dischash{$ondispkey}; + } } if ($markondisp) { $discinfo{$lastkey} = time; } if (defined($dischash{$showkey})) { - $showonlyunread = $dischash{$showkey}; + unless ($dischash{$showkey} eq '') { + $showonlyunread = $dischash{$showkey}; + } } if (defined($dischash{$markkey})) { - $showunmark = $dischash{$markkey}; + unless ($dischash{$markkey} eq '') { + $showunmark = $dischash{$markkey}; + } } if (defined($dischash{$visitkey})) { - $visit = $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 %shown = (); my @posteridentity=(); @@ -224,7 +240,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,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$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; @@ -324,7 +340,6 @@ sub list_discussion { # open manifest file my $manifest = '/imsmanifest.xml'; my $manifestfilename = $tempexport.$manifest; - print STDERR "manifestfilename is $manifestfilename\n"; if ($manifestfile = Apache::File->new('>'.$manifestfilename)) { $manifestok=1; print $manifestfile qq| @@ -355,22 +370,22 @@ imscp_v1p1.xsd http://www.imsglobal.org/ } |; - $discussion.='
'; + $discussion.='
'; $discussion .=' END + if ($sortposts) { + my %sort_types = (); + my %role_types = (); + my %status_types = (); + &sort_filter_names(\%sort_types,\%role_types,\%status_types); + + $discussion .= ''; + } + } if ($dischash{$toggkey}) { my $storebutton = &mt('Store read/unread changes'); $discussion.='
'. ''; if ($visible>2) { $discussion.=''; if ($newpostsflag) { if (!$markondisp) { - $discussion .=''; } @@ -398,7 +413,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) ) { @@ -474,7 +488,6 @@ imscp_v1p1.xsd http://www.imsglobal.org/ my $postfilename = $alldiscussion{$_}.'-'.$imsitems{$alldiscussion{$_}}{'timestamp'}.'.html'; if ($manifestok) { if (($depth[$alldiscussion{$_}] <= $currdepth) && ($alldiscussion{$_} != $firstidx)) { - print STDERR "depth is $depth[$alldiscussion{$_}], currdepth is $currdepth, idx is $alldiscussion{$_}, firstidx is $firstidx\n"; print $manifestfile ' '."\n"; } $currdepth = $depth[$alldiscussion{$_}]; @@ -541,13 +554,54 @@ END $discussion .= <   + $lt{'chgt'}?
'.&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 .= '
'. @@ -600,7 +654,7 @@ END undef(%oldENV); $discussion .= 'Download the zip file from Discussion Posting Archive
'; if ($copyresult) { - $discussion .= 'The following errors occurred during export - '.$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.
'; @@ -618,15 +672,16 @@ END my $subject = ''; if ($ENV{'form.origpage'}) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['addnewattach','deloldattach','delnewattach','timestamp','idx','subject','comment']); - $subject = &HTML::Entities::encode($ENV{'form.subject'},'<>&"'); - $comment = &HTML::Entities::encode($ENV{'form.comment'},'<>&"'); + $subject = &Apache::lonnet::unescape($ENV{'form.subject'}); + $comment = &Apache::lonnet::unescape($ENV{'form.comment'}); my @keepold = (); &process_attachments(\@currnewattach,\@currdelold,\@keepold); if (@currnewattach > 0) { $attachnum += @currnewattach; } } - $discussion.=(< @@ -639,40 +694,41 @@ 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.='
'. + $ressymb.':::" '.$target.'>'. ''. &mt('Post Discussion').'
'; } @@ -683,11 +739,10 @@ 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 %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'}, + my $symb=&Apache::lonenc::check_decrypt($ressymb); + my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); @@ -696,6 +751,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'}; @@ -708,7 +768,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; @@ -903,7 +963,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; @@ -944,47 +1004,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}}) { - 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) { @@ -1034,6 +1080,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 = ''; @@ -1046,12 +1146,14 @@ sub get_post_contents { return $discussion; } } - $$screenname=&Apache::loncommon::screenname( - $$contrib{$idx.':sendername'}, - $$contrib{$idx.':senderdomain'}); - $$plainname=&Apache::loncommon::nickname( - $$contrib{$idx.':sendername'}, - $$contrib{$idx.':senderdomain'}); +# $$screenname=&Apache::loncommon::screenname( +# $$contrib{$idx.':sendername'}, +# $$contrib{$idx.':senderdomain'}); +# $$plainname=&Apache::loncommon::nickname( +# $$contrib{$idx.':sendername'}, +# $$contrib{$idx.':senderdomain'}); + ($$screenname,$$plainname)=($$contrib{$idx.':screenname'}, + $$contrib{$idx.':plainname'}); my $sender=&Apache::loncommon::aboutmewrapper( $$plainname, $$contrib{$idx.':sendername'}, @@ -1149,22 +1251,23 @@ sub replicate_attachments { $i ++; } my ($content,$rtncode); - print STDERR "File to replicate is $$attachrefs{$id}{'filename'} in $1,$2\n"; my $uploadreply = &Apache::lonnet::getuploaded('GET',$$attachrefs{$id}{'filename'},$1,$2,$content,$rtncode); if ($uploadreply eq 'ok') { - my $attachcopy; - if ($attachcopy = Apache::File->new('>'.$destination)) { - print $attachcopy $content; - close($attachcopy); - } else { - $response .= 'Error copying a file attachment to IMS package: '.$!.'
'."\n"; - } + my $attachcopy; + if ($attachcopy = Apache::File->new('>'.$destination)) { + print $attachcopy $content; + close($attachcopy); + } else { + $response .= 'Error copying file attachment - '.$5.' to IMS package: '.$!.'
'."\n"; + } } else { - print STDERR "return code from lonnet was $rtncode\n"; + &Apache::lonnet::logthis("Replication of attachment failed when building IMS export of discussion posts - domain: $1, course: $2, file: $$attachrefs{$id}{'filename'} -error: $rtncode"); + $response .= 'Error copying file attachment - '.$5.' to IMS package: '.$rtncode.'
'."\n"; } } } } + return $response; } sub mail_screen { @@ -1306,8 +1409,8 @@ END } if ($ENV{'form.origpage'}) { - $subject = $ENV{'form.subject'}; - $comment = $ENV{'form.comment'}; + $subject = &Apache::lonnet::unescape($ENV{'form.subject'}); + $comment = &Apache::lonnet::unescape($ENV{'form.comment'}); &process_attachments(\@currnewattach,\@currdelold,\@keepold); } my $latexHelp=&Apache::loncommon::helpLatexCheatsheet(); @@ -1470,10 +1573,8 @@ END sub print_display_options { my ($r,$symb,$previous,$dispchgA,$dispchgB,$markchg,$toggchg,$feedurl) = @_; - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } + &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', @@ -1654,6 +1755,7 @@ $lt{'sdpf'}
$lt{'prca'}
  1. $l


+ @@ -1671,38 +1773,22 @@ END 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||; - } + + &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 +1810,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 +1862,48 @@ $bodytag $lt{'soor'}   - $lt{'disp'} + $lt{'sprs'}   - $lt{'actv'} + $lt{'spur'}   $lt{'spse'}   $lt{'psub'} - +   - - +
@@ -1810,24 +1927,15 @@ END sub print_showposters { my ($r,$symb,$previous,$feedurl,$sortposts) = @_; - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } -# backward compatibility (bulletin boards used to be 'wrapped') - my $ressymb=$symb; - if ($ressymb =~ /bulletin___\d+___/) { - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } - } + + &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 = (); @@ -1977,45 +2085,6 @@ sub get_post_attachments { return; } -sub build_ims_export { - 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 %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - my @depth=(); - my %alldiscussion=(); - my @discussionitems=(); - my %usernamesort = (); - my %subjectsort = (); - my %namesort = (); - my %notshown = (); - my %newitem = (); - my %dischash = (); - my %shown = (); - my %roleinfo = (); - my @posters=(); - my $maxdepth=0; - my $visible=0; - my $newpostsflag=0; - my $status; - my $viewgrades; - my $seeid; - my $prevread; - my $sortposts; - my $ressymb; - my $target; - my $readkey; - my $showunmark; - my $showonlyunread; - -} - - - sub fail_redirect {; my ($r,$feedurl) = @_; if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' }; @@ -2035,7 +2104,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 = ''; @@ -2043,10 +2112,11 @@ sub redirect_back { my $userpicktag = ''; my $qrystr = ''; my $prevtag = ''; - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } + + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + + &dewrapper(\$feedurl); if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' }; if ($previous > 0) { $qrystr = 'previous='.$previous; @@ -2065,20 +2135,44 @@ 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); $r->print (< @@ -2116,9 +2210,10 @@ sub no_redirect_back { ENDNOREDIR if ($feedurl!~/^\/adm\/feedback/) { - $r->print(''); + $r->print(''); } - + $feedurl=&Apache::lonenc::check_encrypt($feedurl); $r->print (< @@ -2131,7 +2226,7 @@ ENDNOREDIRTWO } sub screen_header { - my ($feedurl) = @_; + my ($feedurl,$symb) = @_; my $msgoptions=''; my $discussoptions=''; unless (($ENV{'form.replydisc'}) || ($ENV{'form.editdisc'})) { @@ -2157,7 +2252,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'}:''))) { @@ -2167,7 +2262,7 @@ 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 ($discussoptions) { @@ -2216,8 +2311,6 @@ sub clear_out_html { sub assemble_email { my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_; my $email=<<"ENDEMAIL"; -Refers to $feedurl - $message ENDEMAIL my $citations=<<"ENDCITE"; @@ -2334,7 +2427,13 @@ sub send_msg { sub adddiscuss { my ($symb,$email,$anon,$attachmenturl,$subject)=@_; my $status=''; - if (&discussion_open() && + my $realsymb; + if ($symb=~/^bulletin___/) { + my $filename=(&Apache::lonnet::decode_symb($symb))[2]; + $filename=~s|^adm/wrapper/||; + $realsymb=&Apache::lonnet::symbread($filename); + } + if (&discussion_open(undef,$realsymb) && &Apache::lonnet::allowed('pch',$ENV{'request.course.id'}. ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) { @@ -2363,6 +2462,7 @@ sub adddiscuss { $contrib{'history'} = ''; my $numoldver = 0; my ($oldsymb,$oldidx)=split(/\:\:\:/,$ENV{'form.editdisc'}); + &Apache::lonenc::check_decrypt(\$oldsymb); $oldsymb=~s|(bulletin___\d+___)adm/wrapper/|$1|; # get timestamp for last post and history my %oldcontrib=&Apache::lonnet::restore($oldsymb,$ENV{'request.course.id'}, @@ -2438,6 +2538,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); @@ -2464,7 +2566,8 @@ ENDPREVIEW sub modify_attachments { my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_; - my $subject=&clear_out_html($ENV{'form.subject'}); + my $orig_subject = &Apache::lonnet::unescape($ENV{'form.subject'}); + my $subject=&clear_out_html($orig_subject); $subject=~s/\n/\
/g; $subject=&Apache::lontexconvert::msgtexconverted($subject); my $timestamp=$ENV{'form.timestamp'}; @@ -2477,6 +2580,7 @@ sub modify_attachments { if ($idx) { &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold); } + &Apache::lonenc::check_encrypt(\$symb); $r->print(< @@ -2493,7 +2597,7 @@ $bodytag
- Subject:$subject

+ Subject: $subject

END if ($idx) { if ($attachmenturls) { @@ -2600,7 +2704,7 @@ sub generate_attachments_button { my $response = (< Click to add/remove attachments: new(); + my @allres=$navmap->retrieveResources(); + foreach my $resource (@allres) { + if ($resource->hasDiscussion()) { + my $ressymb; + if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) { + $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard'; + } else { + $ressymb = $resource->symb(); + } + push @{$resourcesref}, $ressymb; + } + } + 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; @@ -2752,13 +2901,13 @@ 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','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 = $ENV{'form.discsymb'}; + my ($symb,$feedurl) = &get_feedurl_and_clean_symb($ENV{'form.discsymb'}); my $readkey = $symb.'_read'; - my %readinghash = (); my $chgcount = 0; - %readinghash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$readkey],$ENV{'user.domain'},$ENV{'user.name'}); + my %readinghash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$readkey],$ENV{'user.domain'},$ENV{'user.name'}); foreach my $key (keys %ENV) { if ($key =~ m/^form\.postunread_(\d+)/) { if ($readinghash{$readkey} =~ /\.$1\./) { @@ -2773,22 +2922,18 @@ sub handler { } } if ($chgcount > 0) { - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%readinghash,$ENV{'user.domain'},$ENV{'user.name'}); + &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; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; - my $feedurl = &Apache::lonnet::clutter($url); - &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'
','0','0','',$previous,'','','',); + &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'
', + '0','0','',$ENV{'form.previous'},'','','',); return OK; } if ($ENV{'form.allversions'}) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; - my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions', - '',''); - $r->print (<print(< Post Versions @@ -2800,13 +2945,10 @@ END if ($ENV{'request.course.sec'}) { $crs.='_'.$ENV{'request.course.sec'}; } - $crs=~s/\_/\//g; + $crs=~s|_|/|g; my $seeid=&Apache::lonnet::allowed('rin',$crs); my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.allversions'}); - my $ressymb=$symb; - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } + ($symb)=&get_feedurl_and_clean_symb($symb); if ($idx > 0) { my %messages = (); my %subjects = (); @@ -2814,120 +2956,82 @@ END my %allattachments = (); my %imsfiles = (); my ($screenname,$plainname); - 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 $discussion = &get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname); - $r->print($discussion); + my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + $r->print(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname)); } return OK; } if ($ENV{'form.posterlist'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb=$ENV{'form.posterlist'}; - my $sortposts = $ENV{'form.sortposts'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - &print_showposters($r,$symb,$previous,$feedurl,$sortposts); + 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 $symb=$ENV{'form.userpick'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; -# backward compatibility (bulletin boards used to be 'wrapped') - my $ressymb=$symb; - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } - my $sort=$ENV{'form.sortposts'}; - my @posters = (); - if (ref($ENV{'form.stuinfo'}) eq 'ARRAY') { - @posters = $ENV{'form.stuinfo'}; - } else { - $posters[0] = $ENV{'form.stuinfo'}; - } + my @posters = &Apache::loncommon::get_env_multiple('form.stuinfo'); + my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.userpick'}); my $numpicks = @posters; - if (defined($ENV{'form.userpick'})) { - my %discinfo = (); - $discinfo{$ressymb.'_userpick'} = join('&',@posters); - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - &redirect_back($r,$feedurl,&mt('Changed sort/filter').'
','0','0','',$previous,$sort,'','','',$numpicks); + my %discinfo; + $discinfo{$symb.'_userpick'} = join('&',@posters); + &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', + \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); + &redirect_back($r,$feedurl,&mt('Changed sort/filter').'
','0','0', + '',$ENV{'form.previous'},$ENV{'form.sortposts'},'','','', + $numpicks); return OK; } if ($ENV{'form.applysort'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb=$ENV{'form.applysort'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; - my $sort = $ENV{'form.sortposts'}; - my $rolefilter = $ENV{'form.rolefilter'}; - my $statusfilter = $ENV{'form.statusfilter'}; - my $secpick = $ENV{'form.sectionpick'}; - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - &redirect_back($r,$feedurl,&mt('Changed sort/filter').'
','0','0','',$previous,$sort,$rolefilter,$statusfilter,$secpick); + 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.sectionpick'}); return OK; - } elsif ($ENV{'form.sortfilter'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb=$ENV{'form.sortfilter'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - &print_sortfilter_options($r,$symb,$previous,$feedurl); + } 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.navmaps'}) { + } elsif ($ENV{'form.navtime'}) { my %discinfo = (); my @resources = (); - if ($ENV{'form.navmaps'} =~ /:/) { - @resources = split/:/,$ENV{'form.navmaps'}; + if (defined($ENV{'form.navmaps'})) { + if ($ENV{'form.navmaps'} =~ /:/) { + @resources = split/:/,$ENV{'form.navmaps'}; + } else { + @resources = ("$ENV{'form.navmaps'}"); + } } else { - @resources = ("$ENV{'form.navmaps'}"); + &has_discussion(\@resources); } my $numitems = @resources; my $feedurl = '/adm/navmaps'; - if ($ENV{'form.navurl'}) { - $feedurl .= '?'.$ENV{'form.navurl'}; - } + if ($ENV{'form.navurl'}) { $feedurl .= '?'.$ENV{'form.navurl'}; } my %lt = &Apache::lonlocal::texthash( 'mnpa' => 'Marked "New" posts as read in a total of', - 'robb' => 'resources/bulletin boards.' + 'robb' => 'resources/bulletin boards.', + 'twnp' => 'There are currently no resources or bulletin boards with unread discussion postings.' ); foreach (@resources) { # backward compatibility (bulletin boards used to be 'wrapped') my $ressymb=$_; + &Apache::lonenc::check_decrypt(\$ressymb); if ($ressymb =~ m/bulletin___\d+___/) { unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper/|; } } my $lastkey = $ressymb.'_lastread'; - $discinfo{$lastkey} = time; + $discinfo{$lastkey} = $ENV{'form.navtime'}; + } + my $textline = "$lt{'mnpa'} $numitems $lt{'robb'}"; + if ($numitems > 0) { + &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss', + \%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); + } else { + $textline = "$lt{'twnp'}"; } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; $r->print (< -$lt{'mnpa'} $numitems $lt{'robb'} +$textline

Continue @@ -2948,321 +3052,234 @@ END ENDREDIR return OK; } elsif ($ENV{'form.modifydisp'}) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb=$ENV{'form.modifydisp'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - my $previous=$ENV{'form.previous'}; - my ($dispchgA,$dispchgB,$markchg,$toggchg) = split/_/,$ENV{'form.changes'}; - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - &print_display_options($r,$symb,$previous,$dispchgA,$dispchgB,$markchg,$toggchg,$feedurl); - return OK; - } 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 $previous=$ENV{'form.previous'}; - my ($map,$ind,$url); - if ( ($ENV{'form.toggoff'}) || ($ENV{'form.toggon'}) ) { -# ------------------------------ Modify setting for read/unread toggle for each post - my $symb=$ENV{'form.toggoff'}?$ENV{'form.toggoff'}:$ENV{'form.toggon'}; - my $ressymb = $symb; - ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } - my %discinfo = (); - my $toggkey = $ressymb.'_readtoggle'; - if ($ENV{'form.toggon'}) { - $discinfo{$toggkey} = 1; - } elsif ($ENV{'form.toggoff'}) { - $discinfo{$toggkey} = 0; - } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } - if (($ENV{'form.markondisp'}) || ($ENV{'form.markonread'})) { -# ---------------------- Modify setting for identification of 'NEW' posts in this discussion - my $symb=$ENV{'form.markondisp'}?$ENV{'form.markondisp'}:$ENV{'form.markonread'}; - my $ressymb = $symb; - ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } - my %discinfo = (); - my $lastkey = $ressymb.'_lastread'; - my $ondispkey = $ressymb.'_markondisp'; - if ($ENV{'form.markondisp'}) { - $discinfo{$lastkey} = time; - $discinfo{$ondispkey} = 1; - } elsif ($ENV{'form.markonread'}) { - if ( $previous > 0 ) { - $discinfo{$lastkey} = $previous; - } - $discinfo{$ondispkey} = 0; - } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } - 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'}; - } - my $ressymb = $symb; - ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; - } - my %discinfo = (); - if ($ENV{'form.allposts'}) { - $discinfo{$ressymb.'_showonlyunread'} = 0; - $discinfo{$ressymb.'_showonlyunmark'} = 0; - } elsif ($ENV{'form.onlyunread'}) { - $discinfo{$ressymb.'_showonlyunread'} = 1; - } else { - $discinfo{$ressymb.'_showonlyunmark'} = 1; - } - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - } - if (($ENV{'form.markonread'}) || ($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'}) || ($ENV{'form.onlyunmark'}) ||($ENV{'form.toggoff'}) || ($ENV{'form.toggon'}) ) { - &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'
','0','0','',$previous); - } else { - &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'
','0','0'); - } + my ($symb,$feedurl)=&get_feedurl_and_clean_symb($ENV{'form.modifydisp'}); + my ($dispchgA,$dispchgB,$markchg,$toggchg) = + split(/_/,$ENV{'form.changes'}); + &print_display_options($r,$symb,$ENV{'form.previous'},$dispchgA, + $dispchgB,$markchg,$toggchg,$feedurl); return OK; - } elsif ($ENV{'form.markread'}) { -# ----------------------------------------------------------------- Mark new posts not NEW - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - my $symb=$ENV{'form.markread'}; - my $ressymb = $symb; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { - $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; + } elsif ($ENV{'form.markondisp'} || $ENV{'form.markonread'} || + $ENV{'form.allposts'} || $ENV{'form.onlyunread'} || + $ENV{'form.onlyunmark'} || $ENV{'form.toggoff'} || + $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 + 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 + 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; } - my %discinfo = (); - my $lastkey = $ressymb.'_lastread'; - $discinfo{$lastkey} = time; - &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'}); - &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status').'
','0','0'); +# --------------------------------- Modify display setting for this discussion + 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.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 $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'}; + my ($symb,$idx)=split(/\:\:\:/,$entry); + ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb); - my ($symb,$idx)=split(/\:\:\:/,$entry); - my ($map,$ind,$url)=&Apache::lonnet::decode_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 %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + my $currenthidden=$contrib{'hidden'}; + my $currentstudenthidden=$contrib{'studenthidden'}; - - my $currenthidden=$contrib{'hidden'}; - my $currentstudenthidden=$contrib{'studenthidden'}; + 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 $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); - - if ($ENV{'form.hide'}) { - $currenthidden.='.'.$idx.'.'; - unless ($seeid) { - $currentstudenthidden.='.'.$idx.'.'; - } - } else { - $currenthidden=~s/\.$idx\.//g; - } - my %newhash=('hidden' => $currenthidden); - if ( ($ENV{'form.hide'}) && (!$seeid) ) { - $newhash{'studenthidden'} = $currentstudenthidden; - } + if ($ENV{'form.hide'}) { + $currenthidden.='.'.$idx.'.'; + unless ($seeid) { + $currentstudenthidden.='.'.$idx.'.'; + } + } else { + $currenthidden=~s/\.$idx\.//g; + } + my %newhash=('hidden' => $currenthidden); + if ( ($ENV{'form.hide'}) && (!$seeid) ) { + $newhash{'studenthidden'} = $currentstudenthidden; + } - &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + &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,&Apache::lonnet::clutter($url), - &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; - if ($ENV{'form.threadedon'}) { + &redirect_back($r,$feedurl,&mt('Changed discussion status').'
', + '0','0','',$ENV{'form.previous'}); + 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 { &Apache::lonnet::del('environment',['threadeddiscussion']); &Apache::lonnet::delenv('environment\.threadeddiscussion'); } - my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'}; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - &redirect_back($r,&Apache::lonnet::clutter($url), - &mt('Changed discussion view mode').'
','0','0','',$ENV{'form.previous'}); + &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 $entry=$ENV{'form.deldisc'}; - - my ($symb,$idx)=split(/\:\:\:/,$entry); - my ($map,$ind,$url)=&Apache::lonnet::decode_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 $currentdeleted=$contrib{'deleted'}; - - $currentdeleted.='.'.$idx.'.'; - - my %newhash=('deleted' => $currentdeleted); - - &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,&Apache::lonnet::clutter($url), - &mt('Changed discussion status').'
','0','0','',$ENV{'form.previous'}); + 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'}); + return OK; } elsif ($ENV{'form.preview'}) { # -------------------------------------------------------- User wants a preview - $r->content_type('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'); $r->send_http_header; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','addnewattach','delnewattach','timestamp','numoldver','idx','anondiscuss','discuss']); - my @currnewattach = (); - my @currdelold = (); - my @keepold = (); + my (@currnewattach,@currdelold,@keepold); &process_attachments(\@currnewattach,\@currdelold,\@keepold); if (exists($ENV{'form.addnewattach.filename'})) { 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 = ''; + my $attachmenturls; + my ($symb) = &get_feedurl_and_clean_symb($ENV{'form.attach'}); my $idx = $ENV{'form.idx'}; - my $symb = $ENV{'form.attach'}; if ($idx) { my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); $attachmenturls = $contrib{$idx.':attachmenturl'}; } - &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'); + &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx, + $attachmenturls); + return OK; } elsif ($ENV{'form.export'}) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; - my $symb=$ENV{'form.export'}; - my $mode; + my ($symb,$feedurl) = &get_feedurl_and_clean_symb($ENV{'form.export'}); + my $mode='board'; my $status='OPEN'; - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); my $previous=$ENV{'form.previous'}; - my $feedurl = &Apache::lonnet::clutter($url); - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $mode = 'board'; - $feedurl=~s|^/adm/wrapper||; - } if ($feedurl =~ /\.(problem|exam|quiz|assess|survey|form|library)$/) { $mode='problem'; $status=$Apache::inputtags::status[-1]; } my $discussion = &list_discussion($mode,$status,$symb); -# &build_ims_export($r,$symb,$previous,$feedurl); my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion'); $r->print($bodytag.$discussion); return OK; } else { # ------------------------------------------------------------- Normal feedback - my $feedurl=$ENV{'form.postdata'}; - $feedurl=~s/^http\:\/\///; - $feedurl=~s/^$ENV{'SERVER_NAME'}//; - $feedurl=~s/^$ENV{'HTTP_HOST'}//; - $feedurl=~s/\?.+$//; + my $feedurl=$ENV{'form.postdata'}; + $feedurl=~s/^http\:\/\///; + $feedurl=~s/^$ENV{'SERVER_NAME'}//; + $feedurl=~s/^$ENV{'HTTP_HOST'}//; + $feedurl=~s/\?.+$//; - my $symb; - if ($ENV{'form.replydisc'}) { - $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0]; - my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); - $feedurl=&Apache::lonnet::clutter($url); - } elsif ($ENV{'form.editdisc'}) { - $symb=(split(/\:\:\:/,$ENV{'form.editdisc'}))[0]; - my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); - $feedurl=&Apache::lonnet::clutter($url); - } elsif ($ENV{'form.origpage'}) { - $symb=""; - } else { - $symb=&Apache::lonnet::symbread($feedurl); - } - unless ($symb) { - $symb=$ENV{'form.symb'}; - if ($symb) { + my $symb; + if ($ENV{'form.replydisc'}) { + $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0]; + my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); + $feedurl=&Apache::lonnet::clutter($url); + } elsif ($ENV{'form.editdisc'}) { + $symb=(split(/\:\:\:/,$ENV{'form.editdisc'}))[0]; my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); - $feedurl=&Apache::lonnet::clutter($url); + $feedurl=&Apache::lonnet::clutter($url); + } elsif ($ENV{'form.origpage'}) { + $symb=""; + } else { + $symb=&Apache::lonnet::symbread($feedurl); + } + unless ($symb) { + $symb=$ENV{'form.symb'}; + if ($symb) { + my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb); + $feedurl=&Apache::lonnet::clutter($url); + } + } + &Apache::lonenc::check_decrypt(\$symb); + my $goahead=1; + if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) { + unless ($symb) { $goahead=0; } + } + # backward compatibility (bulletin boards used to be 'wrapped') + if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { + $feedurl=~s|^/adm/wrapper||; + } + if (!$goahead) { + # Ambiguous Problem Resource + $r->internal_redirect('/adm/ambiguous'); + return OK; } - } - my $goahead=1; - if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) { - unless ($symb) { $goahead=0; } - } - # backward compatibility (bulletin boards used to be 'wrapped') - if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { - $feedurl=~s|^/adm/wrapper||; - } - if ($goahead) { # Go ahead with feedback, no ambiguous reference - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - - if ( - ( - ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:) - ) - || - ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:)) - || - ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/)) - ) { + unless ( + ( + ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:) + ) + || + ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:)) + || + ($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); - if ($options) { - &mail_screen($r,$feedurl,$options); - } else { - &fail_redirect($r,$feedurl); + unless ($ENV{'form.sendit'}) { + &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 { + &fail_redirect($r,$feedurl); + } + return OK; } - } else { # Get previous user input my $prevattempts=&Apache::loncommon::get_previous_attempt( - $symb,$ENV{'user.name'},$ENV{'user.domain'}, - $ENV{'request.course.id'}); + $symb,$ENV{'user.name'},$ENV{'user.domain'}, + $ENV{'request.course.id'}); # Get output from resource my $usersaw=&resource_output($feedurl); @@ -3270,26 +3287,28 @@ ENDREDIR # Get resource answer (need to allow student to view grades for this to work) &Apache::lonnet::appenv(('allowed.vgr'=>'F')); my $useranswer=&Apache::loncommon::get_student_answers( - $symb,$ENV{'user.name'},$ENV{'user.domain'}, - $ENV{'request.course.id'}); + $symb,$ENV{'user.name'},$ENV{'user.domain'}, + $ENV{'request.course.id'}); &Apache::lonnet::delenv('allowed.vgr'); # Get attachments, if any, and not too large my $attachmenturl=''; - if (($ENV{'form.origpage'}) || ($ENV{'form.editdisc'}) || ($ENV{'form.replydisc'})) { - my ($symb,$idx); - if ($ENV{'form.replydisc'}) { - ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'}); - } elsif ($ENV{'form.editdisc'}) { - ($symb,$idx)=split(/\:\:\:/,$ENV{'form.editdisc'}); - } elsif ($ENV{'form.origpage'}) { - $symb = $ENV{'form.symb'}; - } - my @currnewattach = (); - my @deloldattach = (); - my @keepold = (); - &process_attachments(\@currnewattach,\@deloldattach,\@keepold); - $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|; - $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx); + if (($ENV{'form.origpage'}) || ($ENV{'form.editdisc'}) || + ($ENV{'form.replydisc'})) { + my ($symb,$idx); + if ($ENV{'form.replydisc'}) { + ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'}); + } elsif ($ENV{'form.editdisc'}) { + ($symb,$idx)=split(/\:\:\:/,$ENV{'form.editdisc'}); + } elsif ($ENV{'form.origpage'}) { + $symb = $ENV{'form.symb'}; + } + &Apache::lonenc::check_decrypt(\$symb); + my @currnewattach = (); + my @deloldattach = (); + my @keepold = (); + &process_attachments(\@currnewattach,\@deloldattach,\@keepold); + $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|; + $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx); } elsif ($ENV{'form.attachment.filename'}) { unless (length($ENV{'form.attachment'})>131072) { $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback'); @@ -3300,49 +3319,65 @@ ENDREDIR # Assemble email my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts, - $usersaw,$useranswer); + $usersaw,$useranswer); # Who gets this? my ($typestyle,%to) = &decide_receiver($feedurl); # Actually send mail my ($status,$numsent)=&send_msg($feedurl,$email,$citations, - $attachmenturl,%to); + $attachmenturl,%to); # Discussion? Store that. my $numpost=0; - if ($ENV{'form.discuss'}) { - my $subject = &clear_out_html($ENV{'form.subject'}); - $typestyle.=&adddiscuss($symb,$message,0,$attachmenturl,$subject); + if ($ENV{'form.discuss'} || $ENV{'form.anondiscuss'}) { + my $subject = &clear_out_html($ENV{'form.subject'}); + my $anonmode=(defined($ENV{'form.anondiscuss'})); + $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl, + $subject); $numpost++; } - - if ($ENV{'form.anondiscuss'}) { - my $subject = &clear_out_html($ENV{'form.subject'}); - $typestyle.=&adddiscuss($symb,$message,1,$attachmenturl,$subject); - $numpost++; - } - - + # Receipt screen and redirect back to where came from &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$ENV{'form.previous'}); - - } - } else { -# Unable to give feedback - &no_redirect_back($r,$feedurl); - } - } else { -# Ambiguous Problem Resource - if ( &Apache::lonnet::mod_perl_version() == 2 ) { - &Apache::lonnet::cleanenv(); - } - $r->internal_redirect('/adm/ambiguous'); } -} return OK; } +sub wrap_symb { + my ($ressymb)=@_; + if ($ressymb =~ /bulletin___\d+___/) { + unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) { + $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|; + } + } + return $ressymb; +} +sub dewrapper { + my ($feedurl)=@_; + if ($$feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) { + $$feedurl=~s|^/adm/wrapper||; + } +} + +sub get_feedurl { + my ($symb)=@_; + my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); + my $feedurl = &Apache::lonnet::clutter($url); + &dewrapper(\$feedurl); + return $feedurl; +} + +sub get_feedurl_and_clean_symb { + my ($symb)=@_; + &Apache::lonenc::check_decrypt(\$symb); +# backward compatibility (bulletin boards used to be 'wrapped') + unless ($symb =~ m|bulletin___\d+___adm/wrapper|) { + $symb=~s|(bulletin___\d+___)|$1adm/wrapper|; + } + my $feedurl = &get_feedurl($symb); + return ($symb,$feedurl); +} 1; __END__